I'm making a component where I can drag other components vertically. When one component passes the other, they must switch places (on the X axis).
What happens is that the element I'm dragging respects the CSS transition, slides to the next position, but the other does not. It jumps directly to the new position.
What is the reason for this and how to correct it?
Vue.component('dragable', {
props: ['config', 'leftPosition'],
template: '#dragable',
data() {
return {
elementStartCoords: null,
pointerTouchDown: null,
pointerUpHandler: this.onPointerUp.bind(this),
pointerMoveHandler: this.onPointerMove.bind(this)
}
},
computed: {
style() {
return {
top: this.config.top + 'px',
left: this.leftPosition * 150 + 'px'
}
}
},
methods: {
getPointerCoordinates(e) {
return {
y: e.pageY || e.originalEvent.touches[0].pageY
};
},
getElementPosition(el) {
const coords = el.getBoundingClientRect();
return {
y: coords.top
};
},
onPointerDown(e) {
this.elementStartCoords = this.getElementPosition(this.$el);
this.pointerTouchDown = this.getPointerCoordinates(e);
window.addEventListener('mouseup', this.pointerUpHandler);
window.addEventListener('mousemove', this.pointerMoveHandler);
},
onPointerMove(e) {
e.stopPropagation();
if (!this.pointerTouchDown) return;
const pointerPosition = this.getPointerCoordinates(e);
const yDiff = pointerPosition.y - this.pointerTouchDown.y;
this.$emit('dragevent', {
name: this.config.name,
top: this.elementStartCoords.y + yDiff
});
},
onPointerUp() {
window.removeEventListener('mouseup', this.pointerUpHandler);
window.removeEventListener('mousemove', this.pointerMoveHandler);
// reset used variables
this.pointerTouchDown = null;
this.elementStartCoords = null;
},
}
})
new Vue({
el: '#app',
data() {
return {
draggables: [{
name: 'A',
top: 70
}, {
name: 'B',
top: 0
}]
}
},
methods: {
handleDrag(config) {
const draggable = this.draggables.find(drg => drg.name == config.name);
draggable.top = config.top;
this.draggables = this.draggables.sort((a, b) => b.top - a.top);
}
}
})
.dragable {
user-select: none;
position: absolute;
background-color: #dde;
border: 2px solid #88A;
border-radius: 5px;
padding: 30px;
cursor: pointer;
transition: left 1s;
}
<script src="https://vuejs.org/js/vue.min.js"></script><divid="app">
<p>Dragable test</p>
<template v-for="(draggable, i) in draggables">
<dragable :key="draggable.name" :config="draggable" :left-position="i" @dragevent="handleDrag"></dragable>
</template>
</div>
<template lang="html" id="dragable">
<div class="dragable" :style="style" @mousedown="onPointerDown" draggable="false">{{'Draggable ' + config.name}}</div>
</template>