diff --git a/package.json b/package.json index 52a436d..cb6c4bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/tp-sortable", - "version": "2.0.0", + "version": "2.1.0", "description": "", "main": "tp-sortable.js", "scripts": { diff --git a/tp-sortable.js b/tp-sortable.js index e97d7ae..211d036 100644 --- a/tp-sortable.js +++ b/tp-sortable.js @@ -137,48 +137,33 @@ class TpSortable extends EventHelpers(LitElement) { _moveSiblings() { const targetTop = this._rect.top + this._dy; const targetHeight = this._rect.height; + const targetIdx = this._sortables.findIndex(item => item.el === this._target); + const itemsBefore = this._sortables.slice(0, targetIdx); + const itemsAfter = this._sortables.slice(targetIdx + 1); - const isTrackingDown = () => this._dy > 0; - const itemsBeforeTarget = () => { - const idx = this._sortables.findIndex(item => item.el === this._target); - return this._sortables.slice(0, idx); - } - - const itemsAfterTarget = () => { - const idx = this._sortables.findIndex(item => item.el === this._target); - return this._sortables.slice(idx + 1); - } - - if (isTrackingDown()) { - const items = itemsAfterTarget(); - - for (let i = 0, li = items.length; i < li; ++i) { - const item = items[i]; - if (item.el !== this._target) { - - if (targetTop + targetHeight > item.rect.top + (item.rect.height * 0.5)) { - this._translate3d('0px', -targetHeight + 'px', '0px', item.el); - } - - if (targetTop + targetHeight < item.rect.top + (item.rect.height * 0.5)) { - this._translate3d('0px', '0px', '0px', item.el); - } - } + // Dragging down: items after target shift up to fill the target's original slot. + // Each item's shift = distance from that item's original top to the preceding item's original top. + for (let i = 0; i < itemsAfter.length; i++) { + const item = itemsAfter[i]; + const prevTop = i === 0 ? this._rect.top : itemsAfter[i - 1].rect.top; + const shift = -(item.rect.top - prevTop); + if (targetTop + targetHeight > item.rect.top + item.rect.height * 0.5) { + this._translate3d('0px', shift + 'px', '0px', item.el); + } else { + this._translate3d('0px', '0px', '0px', item.el); } - } else { - const items = itemsBeforeTarget(); + } - for (let i = 0, li = items.length; i < li; ++i) { - const item = items[i]; - if (item.el !== this._target) { - if (targetTop - (item.rect.height * 0.5) > item.rect.top) { - this._translate3d('0px', '0px', '0px', item.el); - } - - if (targetTop - (item.rect.height * 0.5) < item.rect.top) { - this._translate3d('0px', targetHeight + 'px', '0px', item.el); - } - } + // Dragging up: items before target shift down to fill the target's original slot. + // Each item's shift = distance from that item's original top to the following item's original top. + for (let i = 0; i < itemsBefore.length; i++) { + const item = itemsBefore[i]; + const nextTop = i === itemsBefore.length - 1 ? this._rect.top : itemsBefore[i + 1].rect.top; + const shift = nextTop - item.rect.top; + if (targetTop - item.rect.height * 0.5 < item.rect.top) { + this._translate3d('0px', shift + 'px', '0px', item.el); + } else { + this._translate3d('0px', '0px', '0px', item.el); } } } @@ -227,9 +212,10 @@ class TpSortable extends EventHelpers(LitElement) { el.style.position = el.style.position || 'relative'; el.style.transition = 'transform 300ms ease-in-out'; el.style.zIndex = '0'; + const rect = el.getBoundingClientRect(); this._sortables.push({ el: el, - rect: el.getBoundingClientRect() + rect: rect }); }