From 9d5e5632df9cbf38d787732797546a6e3ab73435 Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Tue, 11 Mar 2014 19:06:30 +0100 Subject: [PATCH 01/24] Add WineGums example by kynd.info. --- examples/Animated/WineGums.html | 152 ++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 examples/Animated/WineGums.html diff --git a/examples/Animated/WineGums.html b/examples/Animated/WineGums.html new file mode 100644 index 00000000..93ed05a7 --- /dev/null +++ b/examples/Animated/WineGums.html @@ -0,0 +1,152 @@ + + + + + Space + + + + + + + + \ No newline at end of file From 3b3f86ae2d40515d636a5c37060c516ddb966229 Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Tue, 11 Mar 2014 19:08:19 +0100 Subject: [PATCH 02/24] Optimise WineGums example. --- examples/Animated/WineGums.html | 61 +++++++++++++++++---------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/examples/Animated/WineGums.html b/examples/Animated/WineGums.html index 93ed05a7..042dad80 100644 --- a/examples/Animated/WineGums.html +++ b/examples/Animated/WineGums.html @@ -16,21 +16,18 @@ this.numSegment = Math.floor(r / 3 + 2); this.boundOffset = []; this.boundOffsetBuff = []; - this.cos = []; - this.sin = []; - this.path = new Path(); - this.path.fillColor = new Color({ - hue:Math.random() * 360, - saturation:1, - brightness:1 + this.path = new Path({ + fillColor: { + hue: Math.random() * 360, + saturation: 1, + brightness: 1 + }, + blendMode: 'screen' }); - this.path.blendMode = "screen"; for (var i = 0; i < this.numSegment; i ++) { this.boundOffset.push(this.radius); this.boundOffsetBuff.push(this.radius); - this.cos.push(Math.cos(Math.PI * 2 / this.numSegment * i)); - this.sin.push(Math.sin(Math.PI * 2 / this.numSegment * i)); this.path.add(new Point()); } this.path.add(new Point()); @@ -38,12 +35,12 @@ Ball.prototype.iterate = function() { - this.checkWallCollision(); - if (this.vector.length > this.maxVec) { - this.vector = this.vector.normalize(this.maxVec); - } - this.point += this.vector; - this.updateShape(); + this.checkWallCollision(); + if (this.vector.length > this.maxVec) { + this.vector.length = this.maxVec; + } + this.point += this.vector; + this.updateShape(); } Ball.prototype.checkWallCollision = function() { @@ -56,7 +53,10 @@ Ball.prototype.updateShape = function() { var points = []; for (var i = 0; i < this.numSegment; i ++) { - points.push(new Point(this.point.x + this.cos[i] * this.boundOffset[i], this.point.y + this.sin[i] * this.boundOffset[i])); + points.push(this.point + { + angle: 360 / this.numSegment * i, + length: this.boundOffset[i] + }); } for (var i = 0; i < this.path.segments.length; i ++) { @@ -64,12 +64,12 @@ var point = (points[i % this.numSegment] + next) / 2; var vector = (next - point) / 4; this.path.segments[i].point = point + vector; - //this.path.segments[i].handleIn = -vector; - //this.path.segments[i].handleOut = vector; } this.path.smooth(); for (var i = 0; i < this.numSegment; i ++) { - if (this.boundOffset[i] < this.radius / 4) { this.boundOffset[i] = this.radius / 4}; + if (this.boundOffset[i] < this.radius / 4) { + this.boundOffset[i] = this.radius / 4; + }; var next = (i + 1) % this.numSegment; var prev = (i > 0) ? i - 1 : this.numSegment - 1; this.boundOffsetBuff[i] = this.boundOffset[i] += (this.radius - this.boundOffset[i]) / 15; @@ -80,10 +80,10 @@ Ball.prototype.react = function(b) { var dist = this.point.getDistance(b.point); if (dist < this.radius + b.radius && dist != 0) { - var direc = (this.point - b.point).normalize(); var overlap = this.radius + b.radius - dist; - this.vector += direc * overlap * 0.015; - b.vector -= direc * overlap * 0.015; + var direc = (this.point - b.point).normalize(overlap * 0.015); + this.vector += direc; + b.vector -= direc; this.calcBounds(b); b.calcBounds(this); @@ -100,7 +100,7 @@ Ball.prototype.calcBounds = function(b) { for (var i = 0; i < this.numSegment; i ++) { - var tp = this.point + new Point(this.cos[i] * this.boundOffset[i], this.sin[i] * this.boundOffset[i]); + var tp = this.getSidePoint(i); var bLen = b.getboundOffset(tp); var td = tp.getDistance(b.point); if (td < bLen ) { @@ -109,6 +109,13 @@ } } + Ball.prototype.getSidePoint = function(index) { + return this.point + { + angle: 360 / this.numSegment * index, + length: this.boundOffset[index] + }; + } + Ball.prototype.updateBounds = function() { for (var i = 0; i < this.numSegment; i ++) { this.boundOffset[i] = this.boundOffsetBuff[i]; @@ -118,11 +125,7 @@ //--------------------- main --------------------- - var unitAngle = 15 / 180 * Math.PI; - var bg = new Group(); var balls = []; - var bgRadius; - var numBalls = 18; for (var i = 0; i < numBalls; i++) { var position = Point.random() * view.size , @@ -131,7 +134,6 @@ balls.push(ball); } - function onFrame() { for (var i = 0; i < balls.length - 1; i++) { for (var j = i + 1; j < balls.length; j++) { @@ -141,7 +143,6 @@ for (var i = 0, l = balls.length; i < l; i++) { balls[i].iterate(); } - bg.rotate(2); } From c5ee8ffb73236993c852443986389a1bb684d20d Mon Sep 17 00:00:00 2001 From: Jonathan Puckey Date: Tue, 11 Mar 2014 19:09:32 +0100 Subject: [PATCH 03/24] Change title of WineGums example. --- examples/Animated/WineGums.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Animated/WineGums.html b/examples/Animated/WineGums.html index 042dad80..82e82c18 100644 --- a/examples/Animated/WineGums.html +++ b/examples/Animated/WineGums.html @@ -2,7 +2,7 @@ - Space + Wine Gums + + + + + + + + + + + + + + + Arc start + Arc end + + + + + + + + + + large-arc-flag=0 + sweep-flag=0 + + + + + large-arc-flag=0 + sweep-flag=1 + + + + + large-arc-flag=1 + sweep-flag=0 + + + + + large-arc-flag=1 + sweep-flag=1 + + + + + + + + + \ No newline at end of file From 326ecfca0e19374dd729d3d8723227dd8ee4618d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Wed, 12 Mar 2014 23:05:54 +0100 Subject: [PATCH 21/24] Rename angle parameter to rotation. --- src/path/Path.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/path/Path.js b/src/path/Path.js index 1b21de5d..e48ddcdb 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -2297,7 +2297,7 @@ var Path = PathItem.extend(/** @lends Path# */{ }, arcTo: function(/* to, clockwise | through, to - | to, radius, angle, large, sweep */) { + | to, radius, rotation, large, sweep */) { // Get the start point: var current = getCurrentSegment(this), from = current._point, @@ -2320,7 +2320,7 @@ var Path = PathItem.extend(/** @lends Path# */{ through = to; to = Point.read(arguments); } else { - // #3: arcTo(to, radius, angle, large, sweep) + // #3: arcTo(to, radius, rotation, large, sweep) // Drawing arcs in SVG style: var radius = Size.read(arguments); // If rx = 0 or ry = 0 then this arc is treated as a @@ -2329,11 +2329,11 @@ var Path = PathItem.extend(/** @lends Path# */{ return this.lineTo(to); // See for an explanation of the following calculations: // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes - var angle = Base.read(arguments), + var rotation = Base.read(arguments), large = !!Base.read(arguments), sweep = !!Base.read(arguments), middle = from.add(to).divide(2), - pt = from.subtract(middle).rotate(-angle), + pt = from.subtract(middle).rotate(-rotation), x = pt.x, y = pt.y, abs = Math.abs, @@ -2363,10 +2363,10 @@ var Path = PathItem.extend(/** @lends Path# */{ // "...where the + sign is chosen if fA != fS, // and the − sign is chosen if fA = fS." .multiply((large == sweep ? -1 : 1) * Math.sqrt(factor)) - .rotate(angle).add(middle); + .rotate(rotation).add(middle); // Now create a matrix that maps the unit circle to the ellipse, // for easier construction below. - matrix = new Matrix().translate(center).rotate(angle) + matrix = new Matrix().translate(center).rotate(rotation) .scale(rx, ry); // Transform from and to to the unit circle coordinate space // and calculcate start vector and extend from there. From 86c589482202f2c7f9e34a11a4911dd6e7e4dcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Wed, 12 Mar 2014 23:06:13 +0100 Subject: [PATCH 22/24] No need to use parseFloat() in color parsing, a + does enough. --- src/style/Color.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/style/Color.js b/src/style/Color.js index 23c5438b..0ab82def 100644 --- a/src/style/Color.js +++ b/src/style/Color.js @@ -71,7 +71,7 @@ var Color = Base.extend(new function() { // RGB / RGBA components = match[1].split(','); for (var i = 0, l = components.length; i < l; i++) { - var value = parseFloat(components[i]); + var value = +components[i]; components[i] = i < 3 ? value / 255 : value; } } else { From afcabea1a7b24448b2c226ae5f25c944e9a4fc71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Wed, 12 Mar 2014 23:24:09 +0100 Subject: [PATCH 23/24] Fix issue with Z in the middle of SVG path data, not followed by a M command. Closes #413. --- src/path/PathItem.js | 17 +++++++++++------ src/svg/SVGImport.js | 12 ++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/path/PathItem.js b/src/path/PathItem.js index 93313c7a..c02ec61b 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -192,7 +192,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{ relative = false, previous, control, - current = new Point(); + current = new Point(), + start = new Point(); function getCoord(index, coord) { var val = +coords[index]; @@ -219,6 +220,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{ coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g); var length = coords && coords.length; relative = command === lower; + if (previous === 'z' && lower !== 'z') + this.moveTo(start); switch (lower) { case 'm': case 'l': @@ -226,6 +229,8 @@ var PathItem = Item.extend(/** @lends PathItem# */{ this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo']( current = getPoint(j)); control = current; + if(lower == 'm') + start = current; break; case 'h': case 'v': @@ -248,12 +253,12 @@ var PathItem = Item.extend(/** @lends PathItem# */{ // Smooth cubicCurveTo for (var j = 0; j < length; j += 4) { this.cubicCurveTo( - /[cs]/i.test(previous) + /[cs]/.test(previous) ? current.multiply(2).subtract(control) : current, control = getPoint(j), current = getPoint(j + 2)); - previous = command; + previous = lower; } break; case 'q': @@ -267,11 +272,11 @@ var PathItem = Item.extend(/** @lends PathItem# */{ // Smooth quadraticCurveTo for (var j = 0; j < length; j += 2) { this.quadraticCurveTo( - control = (/[qt]/i.test(previous) + control = (/[qt]/.test(previous) ? current.multiply(2).subtract(control) : current), current = getPoint(j)); - previous = command; + previous = lower; } break; case 'a': @@ -285,7 +290,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{ this.closePath(); break; } - previous = command; + previous = lower; } }, diff --git a/src/svg/SVGImport.js b/src/svg/SVGImport.js index 03c5b32e..bc787ee6 100644 --- a/src/svg/SVGImport.js +++ b/src/svg/SVGImport.js @@ -130,14 +130,10 @@ new function() { } function importPath(node) { - // Get the path data, and determine whether it is a compound path or a - // normal path based on the amount of moveTo commands inside it. - var data = node.getAttribute('d'), - path = data.match(/m/gi).length > 1 - ? new CompoundPath() - : new Path(); - path.setPathData(data); - return path; + return new CompoundPath({ + pathData: node.getAttribute('d'), + insert: false + }).reduce(); } function importGradient(node, type) { From e80991658b3f6944cfc36751bf61edf3f6e7857d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Thu, 13 Mar 2014 00:52:24 +0100 Subject: [PATCH 24/24] Fix issue with relative commands after Z. Closes #413. --- src/path/PathItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path/PathItem.js b/src/path/PathItem.js index c02ec61b..12bf2453 100644 --- a/src/path/PathItem.js +++ b/src/path/PathItem.js @@ -221,7 +221,7 @@ var PathItem = Item.extend(/** @lends PathItem# */{ var length = coords && coords.length; relative = command === lower; if (previous === 'z' && lower !== 'z') - this.moveTo(start); + this.moveTo(current = start); switch (lower) { case 'm': case 'l':