ngDraggable.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /*
  2. *
  3. * https://github.com/fatlinesofcode/ngDraggable
  4. */
  5. angular.module("ngDraggable", [])
  6. .service('ngDraggable', [function() {
  7. var scope = this;
  8. scope.inputEvent = function(event) {
  9. if (angular.isDefined(event.touches)) {
  10. return event.touches[0];
  11. }
  12. //Checking both is not redundent. If only check if touches isDefined, angularjs isDefnied will return error and stop the remaining scripty if event.originalEvent is not defined.
  13. else if (angular.isDefined(event.originalEvent) && angular.isDefined(event.originalEvent.touches)) {
  14. return event.originalEvent.touches[0];
  15. }
  16. return event;
  17. };
  18. scope.touchTimeout = 100;
  19. }])
  20. .directive('ngDrag', ['$rootScope', '$parse', '$document', '$window', 'ngDraggable', function ($rootScope, $parse, $document, $window, ngDraggable) {
  21. return {
  22. restrict: 'A',
  23. link: function (scope, element, attrs) {
  24. scope.value = attrs.ngDrag;
  25. var offset,_centerAnchor=false,_mx,_my,_tx,_ty,_mrx,_mry;
  26. var _hasTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
  27. var _pressEvents = 'touchstart mousedown';
  28. var _moveEvents = 'touchmove mousemove';
  29. var _releaseEvents = 'touchend mouseup';
  30. var _dragHandle;
  31. // to identify the element in order to prevent getting superflous events when a single element has both drag and drop directives on it.
  32. var _myid = scope.$id;
  33. var _data = null;
  34. var _dragOffset = null;
  35. var _dragEnabled = false;
  36. var _pressTimer = null;
  37. var onDragStartCallback = $parse(attrs.ngDragStart) || null;
  38. var onDragStopCallback = $parse(attrs.ngDragStop) || null;
  39. var onDragSuccessCallback = $parse(attrs.ngDragSuccess) || null;
  40. var allowTransform = angular.isDefined(attrs.allowTransform) ? scope.$eval(attrs.allowTransform) : true;
  41. var getDragData = $parse(attrs.ngDragData);
  42. // deregistration function for mouse move events in $rootScope triggered by jqLite trigger handler
  43. var _deregisterRootMoveListener = angular.noop;
  44. var initialize = function () {
  45. element.attr('draggable', 'false'); // prevent native drag
  46. // check to see if drag handle(s) was specified
  47. // if querySelectorAll is available, we use this instead of find
  48. // as JQLite find is limited to tagnames
  49. if (element[0].querySelectorAll) {
  50. var dragHandles = angular.element(element[0].querySelectorAll('[ng-drag-handle]'));
  51. } else {
  52. var dragHandles = element.find('[ng-drag-handle]');
  53. }
  54. if (dragHandles.length) {
  55. _dragHandle = dragHandles;
  56. }
  57. toggleListeners(true);
  58. };
  59. var toggleListeners = function (enable) {
  60. if (!enable)return;
  61. // add listeners.
  62. scope.$on('$destroy', onDestroy);
  63. scope.$watch(attrs.ngDrag, onEnableChange);
  64. scope.$watch(attrs.ngCenterAnchor, onCenterAnchor);
  65. // wire up touch events
  66. if (_dragHandle) {
  67. // handle(s) specified, use those to initiate drag
  68. _dragHandle.on(_pressEvents, onpress);
  69. } else {
  70. // no handle(s) specified, use the element as the handle
  71. element.on(_pressEvents, onpress);
  72. }
  73. // if(! _hasTouch && element[0].nodeName.toLowerCase() == "img"){
  74. if( element[0].nodeName.toLowerCase() == "img"){
  75. element.on('mousedown', function(){ return false;}); // prevent native drag for images
  76. }
  77. };
  78. var onDestroy = function (enable) {
  79. toggleListeners(false);
  80. };
  81. var onEnableChange = function (newVal, oldVal) {
  82. _dragEnabled = (newVal);
  83. };
  84. var onCenterAnchor = function (newVal, oldVal) {
  85. if(angular.isDefined(newVal))
  86. _centerAnchor = (newVal || 'true');
  87. };
  88. var isClickableElement = function (evt) {
  89. return (
  90. angular.isDefined(angular.element(evt.target).attr("ng-cancel-drag"))
  91. );
  92. };
  93. /*
  94. * When the element is clicked start the drag behaviour
  95. * On touch devices as a small delay so as not to prevent native window scrolling
  96. */
  97. var onpress = function(evt) {
  98. // console.log("110"+" onpress: "+Math.random()+" "+ evt.type);
  99. if(! _dragEnabled)return;
  100. if (isClickableElement(evt)) {
  101. return;
  102. }
  103. if (evt.type == "mousedown" && evt.button != 0) {
  104. // Do not start dragging on right-click
  105. return;
  106. }
  107. var useTouch = evt.type === 'touchstart' ? true : false;
  108. if(useTouch){
  109. cancelPress();
  110. _pressTimer = setTimeout(function(){
  111. cancelPress();
  112. onlongpress(evt);
  113. },ngDraggable.touchTimeout);
  114. $document.on(_moveEvents, cancelPress);
  115. $document.on(_releaseEvents, cancelPress);
  116. }else{
  117. onlongpress(evt);
  118. }
  119. };
  120. var cancelPress = function() {
  121. clearTimeout(_pressTimer);
  122. $document.off(_moveEvents, cancelPress);
  123. $document.off(_releaseEvents, cancelPress);
  124. };
  125. var onlongpress = function(evt) {
  126. if(! _dragEnabled)return;
  127. evt.preventDefault();
  128. offset = element[0].getBoundingClientRect();
  129. if(allowTransform)
  130. _dragOffset = offset;
  131. else{
  132. _dragOffset = {left:document.body.scrollLeft, top:document.body.scrollTop};
  133. }
  134. element.centerX = element[0].offsetWidth / 2;
  135. element.centerY = element[0].offsetHeight / 2;
  136. _mx = ngDraggable.inputEvent(evt).pageX;//ngDraggable.getEventProp(evt, 'pageX');
  137. _my = ngDraggable.inputEvent(evt).pageY;//ngDraggable.getEventProp(evt, 'pageY');
  138. _mrx = _mx - offset.left;
  139. _mry = _my - offset.top;
  140. if (_centerAnchor) {
  141. _tx = _mx - element.centerX - $window.pageXOffset;
  142. _ty = _my - element.centerY - $window.pageYOffset;
  143. } else {
  144. _tx = _mx - _mrx - $window.pageXOffset;
  145. _ty = _my - _mry - $window.pageYOffset;
  146. }
  147. $document.on(_moveEvents, onmove);
  148. $document.on(_releaseEvents, onrelease);
  149. // This event is used to receive manually triggered mouse move events
  150. // jqLite unfortunately only supports triggerHandler(...)
  151. // See http://api.jquery.com/triggerHandler/
  152. // _deregisterRootMoveListener = $rootScope.$on('draggable:_triggerHandlerMove', onmove);
  153. _deregisterRootMoveListener = $rootScope.$on('draggable:_triggerHandlerMove', function(event, origEvent) {
  154. onmove(origEvent);
  155. });
  156. };
  157. var onmove = function (evt) {
  158. if (!_dragEnabled)return;
  159. evt.preventDefault();
  160. if (!element.hasClass('dragging')) {
  161. _data = getDragData(scope);
  162. element.addClass('dragging');
  163. $rootScope.$broadcast('draggable:start', {x:_mx, y:_my, tx:_tx, ty:_ty, event:evt, element:element, data:_data});
  164. if (onDragStartCallback ){
  165. scope.$apply(function () {
  166. onDragStartCallback(scope, {$data: _data, $event: evt});
  167. });
  168. }
  169. }
  170. _mx = ngDraggable.inputEvent(evt).pageX;//ngDraggable.getEventProp(evt, 'pageX');
  171. _my = ngDraggable.inputEvent(evt).pageY;//ngDraggable.getEventProp(evt, 'pageY');
  172. if (_centerAnchor) {
  173. _tx = _mx - element.centerX - _dragOffset.left;
  174. _ty = _my - element.centerY - _dragOffset.top;
  175. } else {
  176. _tx = _mx - _mrx - _dragOffset.left;
  177. _ty = _my - _mry - _dragOffset.top;
  178. }
  179. moveElement(_tx, _ty);
  180. $rootScope.$broadcast('draggable:move', { x: _mx, y: _my, tx: _tx, ty: _ty, event: evt, element: element, data: _data, uid: _myid, dragOffset: _dragOffset });
  181. };
  182. var onrelease = function(evt) {
  183. if (!_dragEnabled)
  184. return;
  185. evt.preventDefault();
  186. $rootScope.$broadcast('draggable:end', {x:_mx, y:_my, tx:_tx, ty:_ty, event:evt, element:element, data:_data, callback:onDragComplete, uid: _myid});
  187. element.removeClass('dragging');
  188. element.parent().find('.drag-enter').removeClass('drag-enter');
  189. reset();
  190. $document.off(_moveEvents, onmove);
  191. $document.off(_releaseEvents, onrelease);
  192. if (onDragStopCallback ){
  193. scope.$apply(function () {
  194. onDragStopCallback(scope, {$data: _data, $event: evt});
  195. });
  196. }
  197. _deregisterRootMoveListener();
  198. };
  199. var onDragComplete = function(evt) {
  200. if (!onDragSuccessCallback )return;
  201. scope.$apply(function () {
  202. onDragSuccessCallback(scope, {$data: _data, $event: evt});
  203. });
  204. };
  205. var reset = function() {
  206. if(allowTransform)
  207. element.css({transform:'', 'z-index':'', '-webkit-transform':'', '-ms-transform':''});
  208. else
  209. element.css({'position':'',top:'',left:''});
  210. };
  211. var moveElement = function (x, y) {
  212. if(allowTransform) {
  213. element.css({
  214. transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', ' + y + ', 0, 1)',
  215. 'z-index': 99999,
  216. '-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ' + x + ', ' + y + ', 0, 1)',
  217. '-ms-transform': 'matrix(1, 0, 0, 1, ' + x + ', ' + y + ')'
  218. });
  219. }else{
  220. element.css({'left':x+'px','top':y+'px', 'position':'fixed'});
  221. }
  222. };
  223. initialize();
  224. }
  225. };
  226. }])
  227. .directive('ngDrop', ['$parse', '$timeout', '$window', '$document', 'ngDraggable', function ($parse, $timeout, $window, $document, ngDraggable) {
  228. return {
  229. restrict: 'A',
  230. link: function (scope, element, attrs) {
  231. scope.value = attrs.ngDrop;
  232. scope.isTouching = false;
  233. var _lastDropTouch=null;
  234. var _myid = scope.$id;
  235. var _dropEnabled=false;
  236. var onDropCallback = $parse(attrs.ngDropSuccess);// || function(){};
  237. var onDragStartCallback = $parse(attrs.ngDragStart);
  238. var onDragStopCallback = $parse(attrs.ngDragStop);
  239. var onDragMoveCallback = $parse(attrs.ngDragMove);
  240. var initialize = function () {
  241. toggleListeners(true);
  242. };
  243. var toggleListeners = function (enable) {
  244. // remove listeners
  245. if (!enable)return;
  246. // add listeners.
  247. scope.$watch(attrs.ngDrop, onEnableChange);
  248. scope.$on('$destroy', onDestroy);
  249. scope.$on('draggable:start', onDragStart);
  250. scope.$on('draggable:move', onDragMove);
  251. scope.$on('draggable:end', onDragEnd);
  252. };
  253. var onDestroy = function (enable) {
  254. toggleListeners(false);
  255. };
  256. var onEnableChange = function (newVal, oldVal) {
  257. _dropEnabled=newVal;
  258. };
  259. var onDragStart = function(evt, obj) {
  260. if(! _dropEnabled)return;
  261. isTouching(obj.x,obj.y,obj.element);
  262. if (attrs.ngDragStart) {
  263. $timeout(function(){
  264. onDragStartCallback(scope, {$data: obj.data, $event: obj});
  265. });
  266. }
  267. };
  268. var onDragMove = function(evt, obj) {
  269. if(! _dropEnabled)return;
  270. isTouching(obj.x,obj.y,obj.element);
  271. if (attrs.ngDragMove) {
  272. $timeout(function(){
  273. onDragMoveCallback(scope, {$data: obj.data, $event: obj});
  274. });
  275. }
  276. };
  277. var onDragEnd = function (evt, obj) {
  278. // don't listen to drop events if this is the element being dragged
  279. // only update the styles and return
  280. if (!_dropEnabled || _myid === obj.uid) {
  281. updateDragStyles(false, obj.element);
  282. return;
  283. }
  284. if (isTouching(obj.x, obj.y, obj.element)) {
  285. // call the ngDraggable ngDragSuccess element callback
  286. if(obj.callback){
  287. obj.callback(obj);
  288. }
  289. if (attrs.ngDropSuccess) {
  290. $timeout(function(){
  291. onDropCallback(scope, {$data: obj.data, $event: obj, $target: scope.$eval(scope.value)});
  292. });
  293. }
  294. }
  295. if (attrs.ngDragStop) {
  296. $timeout(function(){
  297. onDragStopCallback(scope, {$data: obj.data, $event: obj});
  298. });
  299. }
  300. updateDragStyles(false, obj.element);
  301. };
  302. var isTouching = function(mouseX, mouseY, dragElement) {
  303. var touching= hitTest(mouseX, mouseY);
  304. scope.isTouching = touching;
  305. if(touching){
  306. _lastDropTouch = element;
  307. }
  308. updateDragStyles(touching, dragElement);
  309. return touching;
  310. };
  311. var updateDragStyles = function(touching, dragElement) {
  312. if(touching){
  313. element.addClass('drag-enter');
  314. dragElement.addClass('drag-over');
  315. }else if(_lastDropTouch == element){
  316. _lastDropTouch=null;
  317. element.removeClass('drag-enter');
  318. dragElement.removeClass('drag-over');
  319. }
  320. };
  321. var hitTest = function(x, y) {
  322. var bounds = element[0].getBoundingClientRect();// ngDraggable.getPrivOffset(element);
  323. x -= $document[0].body.scrollLeft + $document[0].documentElement.scrollLeft;
  324. y -= $document[0].body.scrollTop + $document[0].documentElement.scrollTop;
  325. return x >= bounds.left
  326. && x <= bounds.right
  327. && y <= bounds.bottom
  328. && y >= bounds.top;
  329. };
  330. initialize();
  331. }
  332. };
  333. }])
  334. .directive('ngDragClone', ['$parse', '$timeout', 'ngDraggable', function ($parse, $timeout, ngDraggable) {
  335. return {
  336. restrict: 'A',
  337. link: function (scope, element, attrs) {
  338. var img, _allowClone=true;
  339. var _dragOffset = null;
  340. scope.clonedData = {};
  341. var initialize = function () {
  342. img = element.find('img');
  343. element.attr('draggable', 'false');
  344. img.attr('draggable', 'false');
  345. reset();
  346. toggleListeners(true);
  347. };
  348. var toggleListeners = function (enable) {
  349. // remove listeners
  350. if (!enable)return;
  351. // add listeners.
  352. scope.$on('draggable:start', onDragStart);
  353. scope.$on('draggable:move', onDragMove);
  354. scope.$on('draggable:end', onDragEnd);
  355. preventContextMenu();
  356. };
  357. var preventContextMenu = function() {
  358. // element.off('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);
  359. img.off('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);
  360. // element.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);
  361. img.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);
  362. };
  363. var onDragStart = function(evt, obj, elm) {
  364. _allowClone=true;
  365. if(angular.isDefined(obj.data.allowClone)){
  366. _allowClone=obj.data.allowClone;
  367. }
  368. if(_allowClone) {
  369. scope.$apply(function () {
  370. scope.clonedData = obj.data;
  371. });
  372. element.css('width', obj.element[0].offsetWidth);
  373. element.css('height', obj.element[0].offsetHeight);
  374. moveElement(obj.tx, obj.ty);
  375. }
  376. };
  377. var onDragMove = function(evt, obj) {
  378. if(_allowClone) {
  379. _tx = obj.tx + obj.dragOffset.left;
  380. _ty = obj.ty + obj.dragOffset.top;
  381. moveElement(_tx, _ty);
  382. }
  383. };
  384. var onDragEnd = function(evt, obj) {
  385. //moveElement(obj.tx,obj.ty);
  386. if(_allowClone) {
  387. reset();
  388. }
  389. };
  390. var reset = function() {
  391. element.css({left:0,top:0, position:'fixed', 'z-index':-1, visibility:'hidden'});
  392. };
  393. var moveElement = function(x,y) {
  394. element.css({
  395. transform: 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, '+x+', '+y+', 0, 1)', 'z-index': 99999, 'visibility': 'visible',
  396. '-webkit-transform': 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, '+x+', '+y+', 0, 1)',
  397. '-ms-transform': 'matrix(1, 0, 0, 1, '+x+', '+y+')'
  398. //,margin: '0' don't monkey with the margin,
  399. });
  400. };
  401. var absorbEvent_ = function (event) {
  402. var e = event;//.originalEvent;
  403. e.preventDefault && e.preventDefault();
  404. e.stopPropagation && e.stopPropagation();
  405. e.cancelBubble = true;
  406. e.returnValue = false;
  407. return false;
  408. };
  409. initialize();
  410. }
  411. };
  412. }])
  413. .directive('ngPreventDrag', ['$parse', '$timeout', function ($parse, $timeout) {
  414. return {
  415. restrict: 'A',
  416. link: function (scope, element, attrs) {
  417. var initialize = function () {
  418. element.attr('draggable', 'false');
  419. toggleListeners(true);
  420. };
  421. var toggleListeners = function (enable) {
  422. // remove listeners
  423. if (!enable)return;
  424. // add listeners.
  425. element.on('mousedown touchstart touchmove touchend touchcancel', absorbEvent_);
  426. };
  427. var absorbEvent_ = function (event) {
  428. var e = event.originalEvent;
  429. e.preventDefault && e.preventDefault();
  430. e.stopPropagation && e.stopPropagation();
  431. e.cancelBubble = true;
  432. e.returnValue = false;
  433. return false;
  434. };
  435. initialize();
  436. }
  437. };
  438. }])
  439. .directive('ngCancelDrag', [function () {
  440. return {
  441. restrict: 'A',
  442. link: function (scope, element, attrs) {
  443. element.find('*').attr('ng-cancel-drag', 'ng-cancel-drag');
  444. }
  445. };
  446. }])
  447. .directive('ngDragScroll', ['$window', '$interval', '$timeout', '$document', '$rootScope', function($window, $interval, $timeout, $document, $rootScope) {
  448. return {
  449. restrict: 'A',
  450. link: function(scope, element, attrs) {
  451. var intervalPromise = null;
  452. var lastMouseEvent = null;
  453. var config = {
  454. verticalScroll: attrs.verticalScroll || true,
  455. horizontalScroll: attrs.horizontalScroll || true,
  456. activationDistance: attrs.activationDistance || 75,
  457. scrollDistance: attrs.scrollDistance || 15
  458. };
  459. var reqAnimFrame = (function() {
  460. return window.requestAnimationFrame ||
  461. window.webkitRequestAnimationFrame ||
  462. window.mozRequestAnimationFrame ||
  463. window.oRequestAnimationFrame ||
  464. window.msRequestAnimationFrame ||
  465. function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
  466. window.setTimeout(callback, 1000 / 60);
  467. };
  468. })();
  469. var animationIsOn = false;
  470. var createInterval = function() {
  471. animationIsOn = true;
  472. function nextFrame(callback) {
  473. var args = Array.prototype.slice.call(arguments);
  474. if(animationIsOn) {
  475. reqAnimFrame(function () {
  476. $rootScope.$apply(function () {
  477. callback.apply(null, args);
  478. nextFrame(callback);
  479. });
  480. })
  481. }
  482. }
  483. nextFrame(function() {
  484. if (!lastMouseEvent) return;
  485. var viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  486. var viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  487. var scrollX = 0;
  488. var scrollY = 0;
  489. if (config.horizontalScroll) {
  490. // If horizontal scrolling is active.
  491. if (lastMouseEvent.clientX < config.activationDistance) {
  492. // If the mouse is on the left of the viewport within the activation distance.
  493. scrollX = -config.scrollDistance;
  494. }
  495. else if (lastMouseEvent.clientX > viewportWidth - config.activationDistance) {
  496. // If the mouse is on the right of the viewport within the activation distance.
  497. scrollX = config.scrollDistance;
  498. }
  499. }
  500. if (config.verticalScroll) {
  501. // If vertical scrolling is active.
  502. if (lastMouseEvent.clientY < config.activationDistance) {
  503. // If the mouse is on the top of the viewport within the activation distance.
  504. scrollY = -config.scrollDistance;
  505. }
  506. else if (lastMouseEvent.clientY > viewportHeight - config.activationDistance) {
  507. // If the mouse is on the bottom of the viewport within the activation distance.
  508. scrollY = config.scrollDistance;
  509. }
  510. }
  511. if (scrollX !== 0 || scrollY !== 0) {
  512. // Record the current scroll position.
  513. var currentScrollLeft = ($window.pageXOffset || $document[0].documentElement.scrollLeft);
  514. var currentScrollTop = ($window.pageYOffset || $document[0].documentElement.scrollTop);
  515. // Remove the transformation from the element, scroll the window by the scroll distance
  516. // record how far we scrolled, then reapply the element transformation.
  517. var elementTransform = element.css('transform');
  518. element.css('transform', 'initial');
  519. $window.scrollBy(scrollX, scrollY);
  520. var horizontalScrollAmount = ($window.pageXOffset || $document[0].documentElement.scrollLeft) - currentScrollLeft;
  521. var verticalScrollAmount = ($window.pageYOffset || $document[0].documentElement.scrollTop) - currentScrollTop;
  522. element.css('transform', elementTransform);
  523. lastMouseEvent.pageX += horizontalScrollAmount;
  524. lastMouseEvent.pageY += verticalScrollAmount;
  525. $rootScope.$emit('draggable:_triggerHandlerMove', lastMouseEvent);
  526. }
  527. });
  528. };
  529. var clearInterval = function() {
  530. animationIsOn = false;
  531. };
  532. scope.$on('draggable:start', function(event, obj) {
  533. // Ignore this event if it's not for this element.
  534. if (obj.element[0] !== element[0]) return;
  535. if (!animationIsOn) createInterval();
  536. });
  537. scope.$on('draggable:end', function(event, obj) {
  538. // Ignore this event if it's not for this element.
  539. if (obj.element[0] !== element[0]) return;
  540. if (animationIsOn) clearInterval();
  541. });
  542. scope.$on('draggable:move', function(event, obj) {
  543. // Ignore this event if it's not for this element.
  544. if (obj.element[0] !== element[0]) return;
  545. lastMouseEvent = obj.event;
  546. });
  547. }
  548. };
  549. }]);