Reputation: 71
I'm implementing a nested layers component in vue with vuedraggable. I try to keep it close to Adobe's layers panel (for example in Illustrator).
The desired behaviour is: While dragging an item, it remains at it's position and only a black line is indicating where the item would be inserted after releasing the drag.
The black line could be realised by styling vue draggable's ghost. But how can I prevent the item from being removed from its original position while dragging?
Adobe Illustrator layers example
Upvotes: 4
Views: 3448
Reputation: 71
So I ended up using sl-vue-tree which does basically everything I need to simulate Adobe Illustrators layer panel.
Upvotes: 1
Reputation: 71
I now use a similar approach to Death Waltz's answer, but without manipulating the DOM directly.
Instead I make a copy of the item in the list...
start(event) {
// Make a clone of the choosen item and add it to the
// layers list.
const index = event.oldIndex
const item = this.layers[index]
this.layers.splice(index + 1, 0, {
...item,
// Vue requires unique keys.
id: item.id + '_clone',
// Set a isClone flag to be able to delete the clone
// afterwards.
isClone: true
})
},
...and delete it afterwards
end() {
// Delete the clone from the layers.
this.layers = this.layers.filter(layer => !layer.isClone)
}
here is the full example: https://jsfiddle.net/arnoson/587L0nx9/45/
I'm still not sure if this is the most elegant solution and wish there would be a built in way to do this.
Upvotes: 1
Reputation: 2276
In essence, create a copy of the item on click, then set the selected item to invisible. On mouse-up, hide the copy and make the item visible again.
An example:
ball.onmousedown = function(event) { // (1) start the process
// (2) prepare to moving: make absolute and on top by z-index
var ball2 = ball; //set the balls current position so it doesn't appear to move
ball.style.position = 'absolute';
ball.style.visibility = "hidden"; //make the moving item invisible
document.body.append(ball);
// ...and put that absolutely positioned ball under the pointer
moveAt(event.pageX, event.pageY);
// centers the ball at (pageX, pageY) coordinates
function moveAt(pageX, pageY) {
ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
}
// (3) move the ball on mousemove
document.addEventListener('mousemove', onMouseMove);
// (4) drop the ball, remove unneeded handlers
ball.onmouseup = function() {
ball.style.visibility = "visible"; //makes the moved ball visible again
ball2.style.visibility = "hidden"; //makes the copy invisible
document.removeEventListener('mousemove', onMouseMove);
ball.onmouseup = null;
};
};
Upvotes: 0