Skip to content

Instantly share code, notes, and snippets.

@jbasko
Created April 12, 2020 16:36
Show Gist options
  • Save jbasko/3e7d0d22cc20786ade90080ea8eb62b5 to your computer and use it in GitHub Desktop.
Save jbasko/3e7d0d22cc20786ade90080ea8eb62b5 to your computer and use it in GitHub Desktop.
Konva Drag&Drop with dedicated drop areas
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@4.2.2/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Drop</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: "container",
width: width,
height: height
});
var contentLayer = new Konva.Layer()
stage.add(contentLayer)
var dragLayer = new Konva.Layer()
stage.add(dragLayer)
var settlement = new Konva.Rect({
width: 30,
height: 30,
x: 100,
y: 100,
fill: "red",
draggable: true,
name: "settlement",
buildingType: "settlement",
})
settlement.on("drop", function (e) {
console.log(e.target.attrs.name, "is dropped on ", e.landing.attrs.name)
})
settlement.cache()
contentLayer.add(settlement)
var road = new Konva.Rect({
width: 20,
height: 70,
x: 200,
y: 100,
fill: "red",
draggable: true,
name: "road",
buildingType: "road",
})
road.on("drop", function (e) {
console.log(e.target.attrs.name, "is dropped on ", e.landing.attrs.name)
})
road.cache()
contentLayer.add(road)
var path = new Konva.Rect({
width: 30,
height: 100,
fill: "yellow",
allowsBuilding: function (building) {
return building.attrs.buildingType == "road"
}
})
path.cache()
for (var i=0; i<10; i++) {
var obj = path.clone({y: 200, x: 45 * i, name: "road" + (i + 1)})
contentLayer.add(obj)
}
var intersection = new Konva.Rect({
width: 50,
height: 50,
fill: "yellow",
allowsBuilding: function (building) {
return building.attrs.buildingType === "settlement"
}
})
intersection.cache()
for (var i = 0; i < 5; i++) {
var x = intersection.clone({ x: 100 * i, name: "intersection " + (i + 1) })
contentLayer.add(x)
}
contentLayer.batchDraw()
var landing
var originalPos
stage.on("dragstart", function (e) {
// TODO Stop listening on all unrelated objects
contentLayer.getChildren().map(function (obj) {
if (!obj.attrs.allowsBuilding || !obj.attrs.allowsBuilding(e.target)) {
obj.listening(false)
}
})
originalPos = e.target.position()
e.target.moveTo(dragLayer)
contentLayer.draw()
})
stage.on("dragend", function (e) {
e.target.moveTo(contentLayer)
if (!landing) {
e.target.position(originalPos)
} else {
e.target.fire("drop", {
type: "drop",
target: e.target,
evt: e,
landing: landing,
}, true)
}
landing = undefined
// Resume listening on all
contentLayer.getChildren().map(function (obj) {
obj.listening(true)
})
dragLayer.draw()
contentLayer.draw()
})
stage.on("dragmove", function (e) {
var pos = stage.getPointerPosition()
var shape = contentLayer.getIntersection(pos)
if (shape) {
if (shape.attrs.allowsBuilding(e.target)) {
shape.fill("green")
shape.draw()
landing = shape
}
} else if (landing) {
landing.fill("yellow")
landing.draw()
landing = undefined
}
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment