我需要在FabricJS画布上启用触摸缩放/平移。有些库可以在图像上显示此行为(请参阅enhancement request in github)或通过鼠标单击事件(请参阅pinch-zoom-canvas),但我似乎无法将“触摸:手势”事件联系起来正常。
我已经建立了启用手势的库(所以this Fiddle demo可以在本地为我工作),但我不知道从哪里开始将手势与工作小提琴相结合。
我尝试了这样的代码变体:
canvas.on({
'touch:gesture': function() {
var text = document.createTextNode(' Gesture ');
info.insertBefore(text, info.firstChild);
// Handle zoom only if 2 fingers are touching the screen
if (event.e.touches && event.e.touches.length == 2) {
// Get event point
var point = new fabric.Point(event.self.x, event.self.y);
// Remember canvas scale at gesture start
if (event.self.state == "start") {
zoomStartScale = self.canvas.getZoom();
}
// Calculate delta from start scale
var delta = zoomStartScale * event.self.scale;
// Zoom to pinch point
self.canvas.zoomToPoint(point, delta);
}
},
'touch:drag': function(e) {
panning = true;
var text = document.createTextNode(' Dragging ');
info.insertBefore(text, info.firstChild);
if (panning && e && e.e) {
debugger;
var units = 10;
var delta = new fabric.Point(e.e.movementX, e.e.movementY);
canvas.relativePan(delta);
}
panning = false;
},
'touch:longpress': function() {
var text = document.createTextNode(' Longpress ');
info.insertBefore(text, info.firstChild);
}
});
但是当我在iPhone / iPad上测试时没有任何反应。
答案 0 :(得分:5)
捏缩放是一个愚蠢的错误,我没有在事件参数中包含该事件。下面的代码适用于捏合/缩放和点击/拖动。
canvas.on({
'touch:gesture': function(e) {
if (e.e.touches && e.e.touches.length == 2) {
pausePanning = true;
var point = new fabric.Point(e.self.x, e.self.y);
if (e.self.state == "start") {
zoomStartScale = self.canvas.getZoom();
}
var delta = zoomStartScale * e.self.scale;
self.canvas.zoomToPoint(point, delta);
pausePanning = false;
}
},
'object:selected': function() {
pausePanning = true;
},
'selection:cleared': function() {
pausePanning = false;
},
'touch:drag': function(e) {
if (pausePanning == false && undefined != e.e.layerX && undefined != e.e.layerY) {
currentX = e.e.layerX;
currentY = e.e.layerY;
xChange = currentX - lastX;
yChange = currentY - lastY;
if( (Math.abs(currentX - lastX) <= 50) && (Math.abs(currentY - lastY) <= 50)) {
var delta = new fabric.Point(xChange, yChange);
canvas.relativePan(delta);
}
lastX = e.e.layerX;
lastY = e.e.layerY;
}
}
});
绝对~50px if / then语句是为了避免拖动远离最后一点导致画布跳转。还暂停了平移以便能够独立移动对象。在github issues thread中找到了缩放/缩放代码。
答案 1 :(得分:0)
我很难让Laurens代码的平移部分在Fabric 2.3.3
上工作。因此,如果有人遇到相同的问题,我想分享我的解决方案。
我的问题是,即使在PC上也无法平移才能在智能手机上工作。经过一些调试后,我发现可以通过将e.e.layerX
替换为e.self.x
(并将e.e.layerY
替换为e.self.y
)来解决此问题。
这里有完整的修改后的代码:
canvas.on({
'touch:gesture': function(e) {
if (e.e.touches && e.e.touches.length == 2) {
pausePanning = true;
var point = new fabric.Point(e.self.x, e.self.y);
if (e.self.state == "start") {
zoomStartScale = canvas.getZoom();
}
var delta = zoomStartScale * e.self.scale;
canvas.zoomToPoint(point, delta);
pausePanning = false;
}
},
'object:selected': function() {
pausePanning = true;
},
'selection:cleared': function() {
pausePanning = false;
},
'touch:drag': function(e) {
if (pausePanning == false && undefined != e.self.x && undefined != e.self.x) {
currentX = e.self.x;
currentY = e.self.y;
xChange = currentX - lastX;
yChange = currentY - lastY;
if( (Math.abs(currentX - lastX) <= 50) && (Math.abs(currentY - lastY) <= 50)) {
var delta = new fabric.Point(xChange, yChange);
canvas.relativePan(delta);
}
lastX = e.self.x;
lastY = e.self.y;
}
}
});}
答案 2 :(得分:0)
我能够通过mouse:wheel事件实现多点触控平移和缩放。
在进行缩放时-most browsers通常也会发出ctrl
按钮,以区分滚动操作与否。
然后,我利用Fabric事件的DeltaX和DeltaY属性来缩放或平移,类似于它们提供的sample代码。
如果您不与React一起使用,则在下面我称为setState
的每个地方都应该是函数外部的变量。
this.canvas.on("mouse:wheel", opt => {
if (!this.canvas.viewportTransform) {
return;
}
var evt: any = opt.e;
if (evt.ctrlKey === true) {
var evt: any = opt.e;
var deltaY = evt.deltaY;
var zoom = this.canvas.getZoom();
zoom = zoom - deltaY / 100;
if (zoom > 20) zoom = 20;
if (zoom < 0.01) zoom = 0.01;
this.canvas.zoomToPoint(
new fabric.Point(evt.offsetX, evt.offsetY),
zoom
);
} else {
console.log("Scrolling!!");
//inverted scrolling enabled. Remove the -1 multiplier to disable
this.canvas.viewportTransform[4] += (evt.deltaX)*-1;
this.canvas.viewportTransform[5] += (evt.deltaY)*-1;
this.canvas.requestRenderAll();
this.setState({ lastPosX: evt.clientX });
this.setState({ lastPosY: evt.clientY });
}
opt.e.preventDefault();
opt.e.stopPropagation();
});