Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add animation #656

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions dragula.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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); }
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ dragula([$('left-copy-1tomany'), $('right-copy-1tomany')], {
});

dragula([sortable]);
dragula([$('animation')], {
animation: true
})

crossvent.add(sortable, 'click', clickHandler);

Expand Down
19 changes: 19 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,25 @@ <h3 class='tagline'><span class='tagline-text'>Drag and drop so simple it hurts<
</code>
</pre>
</div>

<div class='parent'>
<label>Add some animation?</label>
<div class='wrapper'>
<div id='animation' class='container'>
<div>Anxious Cab Driver</div>
<div>Thriving Venture</div>
<div>Such <a href='http://ponyfoo.com'>a good blog</a></div>
<div>Calm Clam</div>
</div>
</div>
<pre>
<code>
dragula([document.getElementById(container)], {
animation: true
});
</code>
</pre>
</div>
</div>
<h3 class='promo'>Who couldn't love a pun that good? &mdash; <a href='http://thenextweb.com/dd/2015/07/20/less-of-a-drag-maaaaaaaan'>The Next Web</a></h3>
<h3>Get it on GitHub! <a href='https://github.com/bevacqua/dragula'>bevacqua/dragula</a></h3>
Expand Down
5 changes: 5 additions & 0 deletions readme.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ dragula(containers, {
invalid: function (el, handle) {
return false; // don't prevent any drags from initiating by default
},
animation: false, // no animation by default
direction: 'vertical', // Y axis is considered when determining where an element would be dropped
copy: false, // elements are moved by default, not copied
copySortSource: false, // elements in copy-source containers can be reordered
Expand Down Expand Up @@ -196,6 +197,10 @@ By default, spilling an element outside of any containers will move the element

By default, spilling an element outside of any containers will move the element back to the _drop position previewed by the feedback shadow_. Setting `removeOnSpill` to `true` will ensure elements dropped outside of any approved containers are removed from the DOM. Note that `remove` events won't fire if `copy` is set to `true`.

#### `options.animation`

If the `animation` is true, there will be smooth animation after dragging finish.

#### `options.direction`

When an element is dropped onto a container, it'll be placed near the point where the mouse was released. If the `direction` is `'vertical'`, the default value, the Y axis will be considered. Otherwise, if the `direction` is `'horizontal'`, the X axis will be considered.
Expand Down