diff --git a/dragula.js b/dragula.js index 7c19fc63..809a3652 100644 --- a/dragula.js +++ b/dragula.js @@ -5,6 +5,7 @@ var crossvent = require('crossvent'); var classes = require('./classes'); var doc = document; var documentElement = doc.documentElement; +var animateDuration = 300; function dragula (initialContainers, options) { var len = arguments.length; @@ -39,6 +40,7 @@ function dragula (initialContainers, options) { if (o.direction === void 0) { o.direction = 'vertical'; } if (o.ignoreInputTextSelection === void 0) { o.ignoreInputTextSelection = true; } if (o.mirrorContainer === void 0) { o.mirrorContainer = doc.body; } + if (o.animation === void 0) { o.animation = false; } var drake = emitter({ containers: o.containers, @@ -406,7 +408,33 @@ function dragula (initialContainers, options) { reference !== nextEl(item) ) { _currentSibling = reference; + + var itemRect = item.getBoundingClientRect(); + var referenceRect = reference ? reference.getBoundingClientRect() : null; + var direct = o.direction; + // if isPositive is true, the direction is right or down + var isPositive; + if (referenceRect) { + isPositive = direct === 'horizontal' ? (itemRect.x < referenceRect.x) : (itemRect.y < referenceRect.y); + }else{ + isPositive = true; + } + // mover is the element to be exchange passively + var mover; + if (isPositive) { + mover = reference ? (reference.previousElementSibling ? reference.previousElementSibling : reference) : dropTarget.lastElementChild; + } else { + mover = reference; //upward or right + } + if (!mover) { + mover = dropTarget; + } + var moverRect = mover && mover.getBoundingClientRect(); dropTarget.insertBefore(item, reference); + if (o.animation && mover && moverRect) { + animate(moverRect, mover); + animate(itemRect, item); + } drake.emit('shadow', item, dropTarget, _source); } function moved (type) { drake.emit(type, item, _lastDropTarget, _source); } @@ -583,6 +611,31 @@ function nextEl (el) { } } +/** + * Create an animation from position before sorting to present position + * @param prevRect including element's position infomation before sorting + * @param target element after sorting + */ +function animate (prevRect, target) { + if (!prevRect || !target) { + return; + } + var currentRect = target.getBoundingClientRect(); + var originProps = {transition: target.style.transition, transform: target.style.transform}; + Object.assign(target.style, { + transition: 'none', + transform: 'translate(' + (prevRect.left - currentRect.left) + 'px,' + (prevRect.top - currentRect.top) + 'px)' + }); + target.offsetWidth; // repaint + Object.assign(target.style, {transition: 'all ' + animateDuration + 'ms', transform: 'translate(0,0)'}); + clearTimeout(target.animated); + target.animated = setTimeout(function () { + Object.assign(target.style, {originProps: originProps}); + target.animated = false; + }, animateDuration); +} + + function getEventHost (e) { // on touchend event, we have to use `e.changedTouches` // see http://stackoverflow.com/questions/7192563/touchend-event-properties diff --git a/example/example.js b/example/example.js index c94cfb2a..4297d7b1 100644 --- a/example/example.js +++ b/example/example.js @@ -36,6 +36,9 @@ dragula([$('left-copy-1tomany'), $('right-copy-1tomany')], { }); dragula([sortable]); +dragula([$('animation')], { + animation: true +}) crossvent.add(sortable, 'click', clickHandler); diff --git a/index.html b/index.html index f54b4910..6f737f71 100644 --- a/index.html +++ b/index.html @@ -204,6 +204,25 @@
+
+ dragula([document.getElementById(container)], {
+ animation: true
+ });
+
+
+