[Vue] SVG要素をドラッグ&ドロップで移動する
VueでSVG要素をドラッグ&ドロップで移動するサンプルです。
コード
template
<template>
<div id="app">
<svg xmlns="http://www.w3.org/2000/svg"
ref="svg"
width="500px"
height="500px"
viewBox="0 0 500 500"
>
<rect
v-for="( item, i ) in shapes"
:key="item._id"
:x="item.x"
:y="item.y"
:width="item.w"
:height="item.h"
:fill="item.fill"
@mousedown.stop="drag( $event, i )"
@mouseup.stop="drop( i )"
/>
</svg>
</div>
</template>
script
<script>
export default {
data() {
return {
// setting for Rect object
shapes: [
{
_id: '0',
x: 10,
y: 10,
w: 150,
h: 150,
fill: 'red',
isSelected: false
},
{
_id: '1',
x: 200,
y: 200,
w: 250,
h: 250,
fill: 'blue',
isSelected: false
}
],
// for drag&drop event, temporarily save
dragOffsetX: null,
dragOffsetY: null,
};
},
methods: {
// For drag start event
drag( e, index ) {
// Update for get target in move()
this.shapes[index].isSelected = true;
// temporarily save
this.dragOffsetX = e.offsetX - this.shapes[index].x;
this.dragOffsetY = e.offsetY - this.shapes[index].y;
// Add Event
this.$refs.svg.addEventListener( 'mousemove', this.move );
},
// For drag End event
drop( index ) {
// Reset variable
this.shapes[index].isSelected = false;
this.dragOffsetX = this.dragOffsetY = null;
// Remove Event
this.$refs.svg.removeEventListener( 'mousemove', this.move );
},
// For move(dragging) Event
move( { offsetX, offsetY } ) {
// Get target index
const index = this.shapes.findIndex( v => v.isSelected === true );
// Update position
this.shapes[index].x = offsetX - this.dragOffsetX;
this.shapes[index].y = offsetY - this.dragOffsetY;
}
}
};
</script>