summaryrefslogtreecommitdiffstats
path: root/src/patharray.js
diff options
context:
space:
mode:
authorRémi Tétreault <tetreault.remi@gmail.com>2016-12-20 04:09:22 -0500
committerRémi Tétreault <tetreault.remi@gmail.com>2016-12-20 04:09:22 -0500
commit1c4e6f093f197ca51715df2d44b4175c7c29204c (patch)
treeb556718b8ebbe9ec3d18ad5c3487b9f88e86d213 /src/patharray.js
parent998265133f95edcf5b863686e87a9821bdc62a2e (diff)
downloadsvg.js-1c4e6f093f197ca51715df2d44b4175c7c29204c.tar.gz
svg.js-1c4e6f093f197ca51715df2d44b4175c7c29204c.zip
Implement the morph method of SVG.PathArray
Also add methods to SVG.Point that allow to perform operations between two points.
Diffstat (limited to 'src/patharray.js')
-rw-r--r--src/patharray.js69
1 files changed, 67 insertions, 2 deletions
diff --git a/src/patharray.js b/src/patharray.js
index 90d0558..c478b9e 100644
--- a/src/patharray.js
+++ b/src/patharray.js
@@ -100,6 +100,71 @@ SVG.extend(SVG.PathArray, {
return this
}
+ // Test if the passed path array use the same commands as this path array
+, haveSameCommands: function(pathArray) {
+ var i, il, haveSameCommands
+
+ pathArray = new SVG.PathArray(pathArray)
+
+ haveSameCommands = this.value.length === pathArray.value.length
+ for(i = 0, il = this.value.length; haveSameCommands && i < il; i++) {
+ haveSameCommands = this.value[i][0] === pathArray.value[i][0]
+ }
+
+ return haveSameCommands
+ }
+ // Make path array morphable
+, morph: function(pathArray) {
+ var pathsMorphable
+
+ this.destination = new SVG.PathArray(pathArray)
+
+ if(this.haveSameCommands(this.destination)) {
+ this.sourceMorphable = this
+ this.destinationMorphable = this.destination
+ } else {
+ pathsMorphable = SVG.utils.makePathsMorphable(this.value, this.destination)
+ this.sourceMorphable = pathsMorphable[0]
+ this.destinationMorphable = pathsMorphable[1]
+ }
+
+ return this
+ }
+ // Get morphed path array at given position
+, at: function(pos) {
+ if(pos === 1) {
+ return this.destination
+ } else if(pos === 0) {
+ return this
+ } else {
+ var sourceArray = this.sourceMorphable.value
+ , destinationArray = this.destinationMorphable.value
+ , array = [], pathArray = new SVG.PathArray()
+ , i, il, j, jl
+
+ // Animate has specified in the SVG spec
+ // See: https://www.w3.org/TR/SVG11/paths.html#PathElement
+ for (i = 0, il = sourceArray.length; i < il; i++) {
+ array[i] = [sourceArray[i][0]]
+ for(j=1, jl = sourceArray[i].length; j < jl; j++) {
+ array[i][j] = sourceArray[i][j] + (destinationArray[i][j] - sourceArray[i][j]) * pos
+ }
+ // For the two flags of the elliptical arc command, the SVG spec say:
+ // Flags and booleans are interpolated as fractions between zero and one, with any non-zero value considered to be a value of one/true
+ // Elliptical arc command as an array followed by corresponding indexes:
+ // ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
+ // 0 1 2 3 4 5 6 7
+ if(array[i][0] === 'A') {
+ array[i][4] = +(array[i][4] != 0)
+ array[i][5] = +(array[i][5] != 0)
+ }
+ }
+
+ // Directly modify the value of a path array, this is done this way for performance
+ pathArray.value = array
+ return pathArray
+ }
+ }
// Absolutize and parse path to array
, parse: function(array) {
// if it's already a patharray, no need to parse it
@@ -131,7 +196,7 @@ SVG.extend(SVG.PathArray, {
array.splice.apply(array, [i, 1].concat(first, split.map(function(el){ return '.'+el }))) // add first and all other entries back to array
}
}
-
+
}else{
array = array.reduce(function(prev, curr){
return [].concat.apply(prev, curr)
@@ -240,4 +305,4 @@ SVG.extend(SVG.PathArray, {
return SVG.parser.path.getBBox()
}
-}) \ No newline at end of file
+})