标题: HTML5 Canvas 复杂拖放边界

如何使用 Konva 限制拖动能力?

要限制在区域内拖动和放置节点的移动,可以使用 dragmove 事件来定义节点无法越过的边界。

提示:您可以使用 shape.absolutePosition() 方法获取/设置节点的绝对位置,而不是相对的 xy

说明:拖动并放置浅蓝色矩形,观察它被限制在 y = 50 的一个虚拟边界下。拖动并放置黄色矩形,观察它被限制在一个虚拟圆形内。

Konva 复杂拖放边界演示view raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Complex Drag and Drop Bounds Demo</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 layer = new Konva.Layer();

var blueGroup = new Konva.Group({
x: 30,
y: 70,
draggable: true,
});

// bound below y=50
blueGroup.on('dragmove', () => {
blueGroup.y(Math.max(blueGroup.y(), 50));
});

// bound inside a circle
var yellowGroup = new Konva.Group({
x: stage.width() / 2,
y: 70,
draggable: true,
});

yellowGroup.on('dragmove', () => {
var x = stage.width() / 2;
var y = 70;
var radius = 50;
const pos = yellowGroup.absolutePosition();
var scale =
radius / Math.sqrt(Math.pow(pos.x - x, 2) + Math.pow(pos.y - y, 2));

if (scale < 1) {
yellowGroup.x(Math.round((pos.x - x) * scale + x));
yellowGroup.y(Math.round((pos.y - y) * scale + y));
}
});

var blueText = new Konva.Text({
fontSize: 26,
fontFamily: 'Calibri',
text: 'bound below',
fill: 'black',
padding: 10,
});

var blueRect = new Konva.Rect({
width: blueText.width(),
height: blueText.height(),
fill: '#aaf',
stroke: 'black',
strokeWidth: 4,
});

var yellowText = new Konva.Text({
fontSize: 26,
fontFamily: 'Calibri',
text: 'bound in circle',
fill: 'black',
padding: 10,
});

var yellowRect = new Konva.Rect({
width: yellowText.width(),
height: yellowText.height(),
fill: 'yellow',
stroke: 'black',
strokeWidth: 4,
});

blueGroup.add(blueRect).add(blueText);
yellowGroup.add(yellowRect).add(yellowText);

layer.add(blueGroup);
layer.add(yellowGroup);

// add the layer to the stage
stage.add(layer);
</script>
</body>
</html>