v-dragon
v1.2.3
Published
Easy & flexible unopinionated drag & drop library for Vue.js.
Downloads
10
Maintainers
Readme
Vue.js Dragon
Easy & flexible unopinionated drag & drop library for Vue.js.
Installation
Using modules
import Dragon from "v-dragon"; // Install this using `npm install vuedragon`
Vue.use(Dragon);
Using browser-based JavaScript
<script src="https://cdn.jsdelivr.net/npm/v-dragon/dragon.js"></script>
Concepts
Items
An item (v-dragon
) is an element that can be dragged and/or dropped, and can be a dragon-sink
and/or a dragon-source
.
A dragon-sink
can be used to drop stuff onto, a dragon-source
can be dragged onto other items. Not specifiying any of them is the same as specifiying both.
Payload
The dragon-payload
is the object sent to the dragon-drop
event, and should contain all necessary information so you know which thing (payload of the dragged item) has been dragged where (payload of the drop target).
The dragon-drop
Event
This event is called on the drop target after a drag & drop has occurred, and its $event
object contains the payload of the dragged item as from
, and the payload of the drop target as to
. It can then be used to run your own logic to process the event.
The $event
object also contains the boolean values keyCtrl
, keyAlt
, keyShift
, mouseLeft
, mouseMiddle
and mouseRight
to work with modifiers. The modifiers are determined on the start of the drag process.
There's also a dragon-drag
event which is called on the dragged item instead of the drop target; to avoid confusion though, its usage is discouraged unless you need to access something only available from the source.
Classes
A dragon-class
specifies the type of the object - think of it like the name
property of radio buttons. You can only drag a dragon onto a dragon of the same class.
Handle
A dragon-handle
is an element that can initiate a drag process (the thing where you can "grab" your item with the mouse). You can use more than one handle, and if an item contains no handle at all, it will be draggable everywhere.
Area of Effect
The dragon-aoe
specifies how far away from a target something can be dropped while still considering that target. If multiple targets come into question, the closest target will be taken.
It should only be used on elements that can have a ::before
pseudo-element, and don't already have one.
CSS Classes
dragon-aim
is assigned to an item (that could become a target if the mouse button is released) while hovering above it with an eligible dragged element.dragon-use
is assigned to a dragged element during a drag process.
Usage Example
<template>
<ul>
<!-- I'm a sink, so I can not be dragged, but you can drop stuff on me -->
<!-- I also have an AoE of 25 pixels, so you don't have to aim that much -->
<li
v-dragon dragon-sink :dragon-payload="{dragon: null, index: -1}"
dragon-class="game-of-thrones"
dragon-aoe="25"
v-on:dragon-drop="drop"></li>
<!-- I'm a normal dragon, you can drop stuff onto me -->
<li
v-for="(d, i) in dragons" v-bind:key="d"
dragon-item :dragon-payload="{dragon: d, index: i}"
dragon-class="game-of-thrones"
v-on:dragon-drop="drop">
<i dragon-handle class="fa fa-dragon"></i>
{{ d }}
</li>
<!-- I'm a source, so I can only be dragged -->
<li
v-dragon dragon- :dragon-payload="{dragon: newDragon, index: -1}"
dragon-class="game-of-thrones">
<i dragon-handle class="fa fa-dragon"></i>
<input type="text" placeholder="The new dragon" v-model="newDragon">
</li>
</ul>
</template>
<script>
export default {
data() {
return {
dragons: ['Drogon','Rhaegal','Viserion','Balerion','Vhagar','Meraxes','Sunfyre','Syrax','Caraxes','Meleys','Vermax','Arrax','Stormcloud','Sheepstealer','Seasmoke','Silverwing','Vermithor','Shrykos','Tyraxes','Dreamfyre','Vermithrax','Ghiscar','Valryon','Essovius','Archonei','The last dragon'],
newDragon: ""
};
},
methods: {
drag() {
if (window.event.data.from.index >= 0) this.dragons.splice(window.event.data.from.index, 1); // Remove the old dragon
this.dragons.splice(window.event.data.to.index + (window.event.data.to.index > window.event.data.from.index ? 0 : 1), 0, window.event.data.from.dragon); // Insert it at the new position
if (window.event.data.from.index == -1) this.newDragon = ""; // Clear the newDragon field
}
}
}
</script>
<style>
li { transition: box-shadow 0.5s; }
[dragon-handle] { cursor: grabbing; }
.dragon-aim { box-shadow: 0 0 10px #089E71; }
.dragon-use { opacity: 0.8; }
</style>