画布形状上的手势事件

如何在画布形状上监听滑动、捏合缩放、旋转和其他多点触摸手势事件?

默认情况下,Konva 仅支持基本的触摸事件,如 touchstarttouchmovetouchend

您必须手动从这些触摸事件实现手势事件。

如果您在寻求整个舞台的平移和缩放逻辑,请查看 多点触控缩放舞台演示

但我可以稍微修改 Hammer.js 使其与 Konva 一起工作!

您可以在这里找到修改过的 hammer.js 源代码

说明:您可以在矩形上尝试不同的手势,如滑动、旋转、缩放、拖放、按压。

对于桌面浏览器,您可以按住 Shift 键来模拟触摸事件。

注意:此演示为实验性。

Konva Touch Gestures Demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script>
<!-- emulate touches on desktop -->
<script src="https://cdn.rawgit.com/hammerjs/touchemulator/master/touch-emulator.js"></script>
<!-- 3-rd party library for gesture events -->
<script src="/js/hammer-konva.js"></script>

<meta charset="utf-8" />
<title>Konva Touch Gestures Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
TouchEmulator();
Konva.hitOnDragEnabled = true;
Konva.captureTouchEventsEnabled = true;

var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});

var layer = new Konva.Layer();
stage.add(layer);

var originalAttrs = {
x: stage.width() / 2,
y: stage.height() / 2,
scaleX: 1,
scaleY: 1,
draggable: true,
rotation: 0,
};

var group = new Konva.Group(originalAttrs);
layer.add(group);

var size = 200;

var rect = new Konva.Rect({
width: size,
height: size,
fill: 'yellow',
offsetX: size / 2,
offsetY: size / 2,
cornerRadius: 5,
shadowBlur: 10,
shadowColor: 'grey',
});
group.add(rect);

var defaultText = 'Try\ndrag, swipe, pinch zoom, rotate, press...';
var text = new Konva.Text({
text: defaultText,
x: -size / 2,
width: size,
align: 'center',
});
group.add(text);

// attach modified version of Hammer.js
// "domEvents" property will allow triggering events on group
// instead of "hammertime" instance
var hammertime = new Hammer(group, { domEvents: true });

// add rotate gesture
hammertime.get('rotate').set({ enable: true });

// now attach all possible events
group.on('swipe', function (ev) {
text.text('swiping');
group.to({
x: group.x() + ev.evt.gesture.deltaX,
y: group.y() + ev.evt.gesture.deltaY,

onFinish: function () {
group.to(Object.assign({}, originalAttrs));
text.text(defaultText);
},
});
});

group.on('press', function (ev) {
text.text('Under press');
rect.to({
fill: 'green',
});
});

group.on('touchend', function (ev) {
rect.to({
fill: 'yellow',
});

setTimeout(() => {
text.text(defaultText);
}, 300);
});

group.on('dragend', () => {
group.to(Object.assign({}, originalAttrs));
});

var oldRotation = 0;
var startScale = 0;
group.on('rotatestart', function (ev) {
oldRotation = ev.evt.gesture.rotation;
startScale = rect.scaleX();
group.stopDrag();
group.draggable(false);
text.text('rotating...');
});

group.on('rotate', function (ev) {
var delta = oldRotation - ev.evt.gesture.rotation;
group.rotate(-delta);
oldRotation = ev.evt.gesture.rotation;
group.scaleX(startScale * ev.evt.gesture.scale);
group.scaleY(startScale * ev.evt.gesture.scale);
});

group.on('rotateend rotatecancel', function (ev) {
group.to(Object.assign({}, originalAttrs));
text.text(defaultText);
group.draggable(true);
});
</script>
</body>
</html>