What is the syntax for that? Looks like pinching gesture scales an object, but how would I zoom in/out all of the canvas objects?
You'll need to hook up gestures to our zooming functions. Nothing like this built-in afair, but I'll mark it as possible feature.
Hi, if it will help, that's what I'm using in my project, as an example. Works for me.
'touch:gesture': function(event) {
// 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);
}
}
_Note: I only use the "free drawing" feature of the library, so this probably won't do as a general fix._
To allow normal pinch-to-zoom while drawing, I simply added this as the first line of _onMouseMove():
if((e.type === 'touchmove') && (e.touches.length > 1)) { return; }
Unfortunately, Sphinxxx's solution makes marks in drawing mode. It's of course impossible to make two touches at EXACTLY the same time!
I did it a bit differently, BTW, so that I can easily shut it off. And I first did it as a monkey-patch, but the monkey-patch became impractical when I started meddling with other code that isn't so easily patched. (I will probably go back to monkey-patch).
_onMouseMove: function (e) {
// LOCALMOD: ignore multi-touch
if (this.allowTouchScrolling) {
if((e.type === 'touchmove') && (e.touches.length > 1)) { return;}
}
e.preventDefault && e.preventDefault();
this.__onMouseMove(e);
},
allowTouchScrolling on it's own is a non-starter, as it does nothing to prevent marks, and makes much bigger marks!
I think what is needed here is to delete the most recently-started path in drawing mode when a multi-touch touchmove is seen. I'm not familiar enough with the code to do that.
I haven't tried Anruin's solution yet. Problem is, I need to scale both the canvas and multiple positioned overlays. But I think perhaps it will work for me if I substitute a CSS transform of the container (of canvas and overlays) for callingzoomToPoint(). This is why - for now - I've just enabled scaling of the entire document (which is not ideal).
Some changes to my solution, it is still far from perfect. The 400mSec delay is annoying, and still it sometimes leaves a small mark in drawing mode.
(Note the sv_ prefix is just to make names unique to my app...)
*jslint browser: true, devel: true, vars: true, unparam: true, white: true, indent: 2 */
/*global fabric */
(function fabricZoomMonkeypatchSelfEx(window, document, undefined) {
'use strict';
fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {
_svTouchStartDeferTimerID: undefined,
_svOnMouseDownOriginal: fabric.Canvas.prototype._onMouseDown,
_onMouseDown: function (e) {
if (this.allowTouchScrolling) {
// This is dubious, because it will be almost impossible to have touchstart with multi-touch
if (e.touches && (e.touches.length > 1)) {return;}
clearTimeout(this._svTouchStartDeferTimerID);
this._svTouchStartDeferTimerID = undefined;
if(e.type === 'touchstart') {
var _this = this;
this._svTouchStartDeferTimerID = setTimeout(function() {
_this._svTouchStartDeferTimerID = undefined;
_this._svOnMouseDownOriginal(e);
}, 400);
}
} else {
this._svOnMouseDownOriginal(e);
}
},
_onMouseMove: function (e) {
if (this.allowTouchScrolling) {
if((e.type === 'touchmove') && e.touches && (e.touches.length > 1)) {return;}
}
e.preventDefault && e.preventDefault();
this.__onMouseMove(e);
}
});
}(window, document));
@Anruin
self.canvas in the codes you share? Is it event.self.canvas? Thanks.touch:gesture fired on my canvas, but my objects on the canvas can be scaled by gesture. Not sure if you've ever had the same issue?
Most helpful comment
Hi, if it will help, that's what I'm using in my project, as an example. Works for me.