From f9f41a3509fc59cf9fee3cc6183210428d3c28b4 Mon Sep 17 00:00:00 2001 From: Luis Leiva Date: Mon, 11 Dec 2017 23:06:44 +0100 Subject: [PATCH] Handle multistrokes animation --- jquery.sketchable.animate.js | 68 ++++++++++++++++++++++-------------- sketchable.animate.js | 58 +++++++++++++++++++----------- 2 files changed, 79 insertions(+), 47 deletions(-) diff --git a/jquery.sketchable.animate.js b/jquery.sketchable.animate.js index dbb4038..52b6864 100644 --- a/jquery.sketchable.animate.js +++ b/jquery.sketchable.animate.js @@ -25,46 +25,62 @@ var events = data.options.events; var graphics = data.options.graphics; - // Flatten strokes struct to easily handle multistrokes. var fmtStrokes = []; + var pointCount = 0; for (var s = 0; s < strokes.length; s++) { + var fmtCoords = []; var coords = strokes[s]; for (var c = 0; c < coords.length; c++) { + // Add strokeId to easily handle multistrokes. var pt = toPoint(coords[c]); pt.strokeId = s; - fmtStrokes.push(pt); + fmtCoords.push(pt); + pointCount++; } + fmtStrokes.push(fmtCoords); } - var raf; - var frame = 1; - var count = fmtStrokes.length - 1; + if (typeof events.animationstart === 'function') { + events.animationstart($instance, data); + } - if (typeof events.animationstart === 'function') events.animationstart($instance, data); + var raf = {}; // Trigger one animation per stroke. + var pts = 1; // Will reach the total number of points. - (function loop() { - raf = requestAnimationFrame(loop); + for (var s = 0; s < fmtStrokes.length; s++) { + (function(s) { + var coords = fmtStrokes[s]; + var frame = 0; - try { - drawLine(sketch, fmtStrokes, frame, graphics); - frame++; - } catch (err) { - console.error(err); - cancelAnimationFrame(raf); - } + (function loop() { + raf[s] = requestAnimationFrame(loop); + try { + drawLine(sketch, coords, frame, graphics); + } catch (err) { + console.error(err); + cancelAnimationFrame(raf[s]); + } + // Advance local count and check if current animation should end. + if (++frame === coords.length - 1) { + cancelAnimationFrame(raf[s]); + } + // Advance global count and check if actual animation has ended. + if (++pts === pointCount - 1 && typeof events.animationend === 'function') { + events.animationend($instance, data); + } + })(); - if (frame == count) { - cancelAnimationFrame(raf); - if (typeof events.animationend === 'function') events.animationend($instance, data); - } - })(); + })(s); + } /** * Cancel current animation. * @return {AnimateSketch}. */ this.cancel = function() { - cancelAnimationFrame(raf); + for (var s in raf) { + cancelAnimationFrame(raf[s]); + } return this; }; @@ -78,17 +94,17 @@ * @param {object} [graphics] - Graphics options. */ function drawLine(sketch, coords, t, graphics) { - var prevPt = coords[t - 1]; var currPt = coords[t]; + var nextPt = coords[t + 1]; - if (sketch.data.firstPointSize && (t === 1 || currPt.strokeId !== prevPt.strokeId)) { - var pt = t > 1 ? currPt : prevPt; + if (sketch.data.firstPointSize && (t === 1 || currPt.strokeId !== nextPt.strokeId)) { + var pt = t > 1 ? nextPt : currPt; sketch.beginFill(sketch.data.strokeStyle).fillCircle(pt.x, pt.y, sketch.data.firstPointSize); } sketch.lineStyle(graphics.strokeStyle, graphics.lineWidth).beginPath(); - if (currPt.strokeId === prevPt.strokeId) { - sketch.line(prevPt.x, prevPt.y, currPt.x, currPt.y).stroke(); + if (currPt.strokeId === nextPt.strokeId) { + sketch.line(currPt.x, currPt.y, nextPt.x, nextPt.y).stroke(); } sketch.closePath(); }; diff --git a/sketchable.animate.js b/sketchable.animate.js index c8cbc13..9bab48e 100644 --- a/sketchable.animate.js +++ b/sketchable.animate.js @@ -27,46 +27,62 @@ var events = data.options.events; var graphics = data.options.graphics; - // Flatten strokes struct to easily handle multistrokes. var fmtStrokes = []; + var pointCount = 0; for (var s = 0; s < strokes.length; s++) { + var fmtCoords = []; var coords = strokes[s]; for (var c = 0; c < coords.length; c++) { + // Add strokeId to easily handle multistrokes. var pt = toPoint(coords[c]); pt.strokeId = s; - fmtStrokes.push(pt); + fmtCoords.push(pt); + pointCount++; } + fmtStrokes.push(fmtCoords); } - var raf; - var frame = 1; - var count = fmtStrokes.length - 1; + if (typeof events.animationstart === 'function') { + events.animationstart($instance, data); + } - if (typeof events.animationstart === 'function') events.animationstart(instance.elem, data); + var raf = {}; // Trigger one animation per stroke. + var pts = 1; // Will reach the total number of points. - (function loop() { - raf = requestAnimationFrame(loop); + for (var s = 0; s < fmtStrokes.length; s++) { + (function(s) { + var coords = fmtStrokes[s]; + var frame = 0; - try { - drawLine(sketch, fmtStrokes, frame, graphics); - frame++; - } catch (err) { - console.error(err); - cancelAnimationFrame(raf); - } + (function loop() { + raf[s] = requestAnimationFrame(loop); + try { + drawLine(sketch, coords, frame, graphics); + } catch (err) { + console.error(err); + cancelAnimationFrame(raf[s]); + } + // Advance local count and check if current animation should end. + if (++frame === coords.length - 1) { + cancelAnimationFrame(raf[s]); + } + // Advance global count and check if actual animation has ended. + if (++pts === pointCount - 1 && typeof events.animationend === 'function') { + events.animationend($instance, data); + } + })(); - if (frame == count) { - cancelAnimationFrame(raf); - if (typeof events.animationend === 'function') events.animationend(instance.elem, data); - } - })(); + })(s); + } /** * Cancel current animation. * @return {AnimateSketch}. */ this.cancel = function() { - cancelAnimationFrame(raf); + for (var s in raf) { + cancelAnimationFrame(raf[s]); + } return this; };