diff options
author | Rémi Tétreault <tetreault.remi@gmail.com> | 2016-12-20 04:09:22 -0500 |
---|---|---|
committer | Rémi Tétreault <tetreault.remi@gmail.com> | 2016-12-20 04:09:22 -0500 |
commit | 1c4e6f093f197ca51715df2d44b4175c7c29204c (patch) | |
tree | b556718b8ebbe9ec3d18ad5c3487b9f88e86d213 /src/patharray.js | |
parent | 998265133f95edcf5b863686e87a9821bdc62a2e (diff) | |
download | svg.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.js | 69 |
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 +}) |