Fixed undo/redo on multitouch events

This commit is contained in:
Luis Leiva 2017-11-16 13:25:44 +01:00
parent 1bc04f757e
commit b26ea4c77e
2 changed files with 41 additions and 40 deletions

View File

@ -57,12 +57,14 @@
function restore(snapshot) {
// Manipulate canvas via jQuery sketchable API.
// This way, we don't lose default drawing settings et al.
$instance.sketchable('handler', function(elem, data){
$instance.sketchable('handler', function(elem, data) {
//data.sketch.clear().drawImage(snapshot.src);
// Note: jSketch.drawImage after clear creates some flickering,
// so use the native HTMLCanvasElement.drawImage method instead.
data.sketch.clear();
data.sketch.graphics.drawImage(snapshot, 0,0);
// Update strokes.
data.strokes = stack[stpos].strokes.slice();
});
};
/**
@ -95,10 +97,6 @@
*/
this.undo = function() {
prev();
$instance.sketchable('handler', function(elem, data) {
if (stack[stpos])
data.strokes = stack[stpos].strokes.slice();
});
return this;
};
/**
@ -107,10 +105,6 @@
*/
this.redo = function() {
next();
$instance.sketchable('handler', function(elem, data) {
if (stack[stpos])
data.strokes = stack[stpos].strokes.slice();
});
return this;
};
/**
@ -124,13 +118,19 @@
};
/**
* Save current state.
* @param {Object} evt DOM event.
* @return {MementoCanvas} Class instance.
*/
this.save = function() {
stpos++;
if (stpos < stack.length) stack.length = stpos;
$instance.sketchable('handler', function(elem, data) {
stack.push({ image: elem[0].toDataURL(), strokes: data.strokes.slice() });
this.save = function(evt) {
instance.handler(function(elem, data) {
// With multitouch events, only the first event should be used to store a snapshot.
// Then, the subsequent multitouch events must update current strokes data.
if (evt && evt.identifier > 0) {
stack[stpos].strokes = data.strokes.slice();
} else {
stack.push({ image: elem.toDataURL(), strokes: data.strokes.slice() });
stpos++;
}
});
return this;
};
@ -160,16 +160,15 @@
* @memberof $.fn.sketchable.plugins
*/
$.fn.sketchable.plugins.memento = function($instance) {
// Access the instance configuration.
var config = $instance.sketchable('config');
var callbacks = {
clear: function(elem, data) {
data.memento.reset();
data.memento.reset().save();
},
mouseup: function(elem, data, evt) {
// Don't store multitouch events separately.
if (evt.type.indexOf('touch') === 0 && evt.identifier > 0) return;
data.memento.save();
data.memento.save(evt);
},
destroy: function(elem, data) {
data.memento.destroy();
@ -203,12 +202,12 @@
override(events[i]);
}
// Expose public API: all sketchable instances will have these methods.
// Expose public API: all jQuery sketchable instances will have these methods.
$.extend($.fn.sketchable.api, {
/**
* Goes back to the previous CANVAS state, if available.
* @memberof $.fn.sketchable
* @example $('canvas').sketchable('undo');
* @example jqueryElem.sketchable('undo');
*/
undo: function() {
var elem = $(this), data = elem.data(namespace);
@ -217,7 +216,7 @@
/**
* Goes forward to the previous CANVAS state, if available.
* @memberof $.fn.sketchable
* @example $('canvas').sketchable('redo');
* @example jqueryElem.sketchable('redo');
*/
redo: function() {
var elem = $(this), data = elem.data(namespace);
@ -226,12 +225,12 @@
/**
* Save a snapshot of the current CANVAS status.
* @memberof $.fn.sketchable
* @example $('canvas').sketchable('save');
* @example jqueryElem.sketchable('save');
*/
save: function() {
var elem = $(this), data = elem.data(namespace);
data.memento.save();
},
}
});
// Initialize plugin here.

View File

@ -60,12 +60,14 @@
function restore(snapshot) {
// Manipulate canvas via jQuery sketchable API.
// This way, we don't lose default drawing settings et al.
instance.handler(function(elem, data){
instance.handler(function(elem, data) {
//data.sketch.clear().drawImage(snapshot.src);
// Note: jSketch.drawImage after clear creates some flickering,
// so use the native HTMLCanvasElement.drawImage method instead.
data.sketch.clear();
data.sketch.graphics.drawImage(snapshot, 0,0);
// Update strokes.
data.strokes = stack[stpos].strokes.slice();
});
};
/**
@ -98,10 +100,6 @@
*/
this.undo = function() {
prev();
instance.handler(function(elem, data) {
if (stack[stpos])
data.strokes = stack[stpos].strokes.slice();
});
return this;
};
/**
@ -110,10 +108,6 @@
*/
this.redo = function() {
next();
instance.handler(function(elem, data) {
if (stack[stpos])
data.strokes = stack[stpos].strokes.slice();
});
return this;
};
/**
@ -127,12 +121,19 @@
};
/**
* Save current state.
* @param {Object} evt DOM event.
* @return {MementoCanvas} Class instance.
*/
this.save = function() {
stpos++;
if (stpos < stack.length) stack.length = stpos;
this.save = function(evt) {
instance.handler(function(elem, data) {
stack.push({ image: elem.toDataURL(), strokes: data.strokes.slice() });
// With multitouch events, only the first event should be used to store a snapshot.
// Then, the subsequent multitouch events must update current strokes data.
if (evt && evt.identifier > 0) {
stack[stpos].strokes = data.strokes.slice();
} else {
stack.push({ image: elem.toDataURL(), strokes: data.strokes.slice() });
stpos++;
}
});
return this;
};
@ -167,12 +168,10 @@
var callbacks = {
clear: function(elem, data) {
data.memento.reset();
data.memento.reset().save();
},
mouseup: function(elem, data, evt) {
// Don't store multitouch events separately.
if (evt.type.indexOf('touch') === 0 && evt.identifier > 0) return;
data.memento.save();
data.memento.save(evt);
},
destroy: function(elem, data) {
data.memento.destroy();
@ -211,6 +210,7 @@
/**
* Goes back to the previous CANVAS state, if available.
* @memberof Sketchable
* @example sketchableInstance.undo();
*/
undo: function() {
var elem = this.elem, data = dataBind(elem)[namespace];
@ -219,6 +219,7 @@
/**
* Goes forward to the previous CANVAS state, if available.
* @memberof Sketchable
* @example sketchableInstance.redo();
*/
redo: function() {
var elem = this.elem, data = dataBind(elem)[namespace];
@ -227,6 +228,7 @@
/**
* Save a snapshot of the current CANVAS status.
* @memberof Sketchable
* @example sketchableInstance.save();
*/
save: function() {
var elem = this.elem, data = dataBind(elem)[namespace];