interact.jsとは
JavaScriptのドラッグ&ドロップの処理を簡単に実装できるJavaScriptライブラリ。
npm or CDNで読み込む場合は以下の通り。
npm
npm i -D interactjs
// ES6 import
import interact from 'interactjs'
// or if using commonjs or AMD
const interact = require('interactjs')
CDN
<script src="https://unpkg.com/interactjs/dist/interact.min.js"></script>
要素をドラッグできるようにする
interact.jsを読み込んだらドラッグするための要素を作成する。
今回は適当に以下のようなドラッグ要素のHTMLを作成してCSSで装飾する。
<div class="drag">ドラッグ要素</div>
.drag {
display: grid;
place-items: center;
width: 120px;
height: 120px;
border-radius: 10px;
background: skyblue;
touch-action: none;
user-select: none;
}
ブラウザで見るとこのようになります。
次にJavaScriptでconst pos = { x: 0, y: 0 }でドラッグする要素の位置の定数を用意したあと、interact('.drag').draggableでドラッグする要素を指定すればドラッグ可能になる。
const pos = { x: 0, y: 0 }
interact('.drag').draggable({
listeners: {
move(event) {
pos.x += event.dx
pos.y += event.dy
event.target.style.transform =
`translate(${pos.x}px, ${pos.y}px)`
},
},
})
しかし、これだけだと画面外にドラッグ&ドロップすると該当の要素は操作不可能になってしまうので、必ずmodifiersのrestrictを以下のように指定して画面外に要素が出ないように設定したほうが良いです。
const pos = { x: 0, y: 0 }
interact('.drag').draggable({
listeners: {
move(event) {
pos.x += event.dx
pos.y += event.dy
event.target.style.transform =
`translate(${pos.x}px, ${pos.y}px)`
},
},
modifiers: [
interact.modifiers.restrict({
restriction: 'parent',
endOnly: true
})
],
})
ドラッグした要素をドロップする範囲を作成
interact.jsは要素を特定の範囲にドラッグ&ドロップした際に何かしらの処理を実行させることもできる。
やり方はまずドロップする範囲のHTMLとCSSを以下のように作成する。
要素には特定の範囲にドラッグ&ドロップされたか検知するためdata-interactという属性をそれぞれに付けています。
ドラッグ中にドラッグした要素の色がnavyに変わるように.drag.activeもCSSに記載しています。
<div class="drag" data-interact>ドラッグ要素</div>
<hr>
<div class="drop" data-interact>ドロップ範囲</div>
.drag,
.drop {
display: grid;
place-items: center;
width: 120px;
height: 120px;
border-radius: 10px;
touch-action: none;
user-select: none;
}
.drag {
background: skyblue;
}
.drop {
background: palegreen;
}
.drag.active {
background: navy;
color: white;
}
正しく書けていればこのような見た目になります。
JavaScriptはinteract('.drop').dropzoneでドロップ(ondrop)した際にドラッグした要素(relatedTarget)がドラッグ範囲(target)にドロップされたら「ドロップ完了」という文字列に変わって背景色がオレンジになるようにする処理を追記します。
ドラッグ中はdropactivate、ドラッグ中止はdropdeactivateで検知できます。
interact('.drop').dropzone({
ondrop(event) {
const relatedTarget = event.relatedTarget
const target = event.target
const dragData = relatedTarget.dataset.interact
const dropData = target.dataset.interact
if (dragData === dropData) {
relatedTarget.textContent = 'ドロップ完了'
target.style.backgroundColor = 'orange'
}
}
}).on('dropactivate', (event) => {
event.relatedTarget.classList.add('active')
}).on('dropdeactivate', (event) => {
event.relatedTarget.classList.remove('active')
})
このやり方法を覚えればWebサイトでよくあるドラッグ&ドロップでロボットではなく人間か判別するUIの処理や設定した要素の並び替えの処理なども簡単にできるので試してみると良いです。