svg-path-interpolator
Advanced tools
Comparing version 0.2.2 to 0.2.3
@@ -0,0 +0,0 @@ { |
{ | ||
"author": "Justin Wilaby", | ||
"name": "svg-path-interpolator", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"license": "MIT", | ||
@@ -34,4 +34,4 @@ "description": "The SVG Path Interpolator produces point data representing interpolated values within an SVG path.", | ||
"dependencies": { | ||
"sax": "^1.2.1" | ||
"sax": "^1.2.4" | ||
} | ||
} |
@@ -55,10 +55,15 @@ # SVG Path Interpolator | ||
When `joinPathData` is `true`, all path data is joined in a single array as the output. When `false`, each path is separated by the path `id` attribute in a json object as the output. If no `id` attribute exists on the path, a unique id is created. | ||
### minDistance | ||
`minDistance` is the minimum distance between the current and previous points when sampling. If a sample results in a distance less than the specified value, the point is discarded. | ||
### roundToNearest | ||
`roundToNearest` is useful when snapping to fractional pixel values. For example, if `roundToNearest` is `.25`, a sample resulting in the point 2.343200092,4.6100923 will round to 2.25,4.5 | ||
### sampleFrequency | ||
`sampleFrequency` determines the increment of `t` when sampling. If `sampleFrequency` is set to `.001` , since `t` iterates from 0 to 1, there will be 1000 points sampled per command but only points that are greater than `minDistance` are captured. | ||
### pretty (cli only) | ||
When `true`, `pretty` creates formatted json output | ||
### prettyIndent (cli only) | ||
@@ -65,0 +70,0 @@ Then number of spaces to indent when `pretty` is `true` |
@@ -141,3 +141,3 @@ const rotatePoint = require('./utils').rotatePoint; | ||
const interpolatedPts = calculateCoordinatesCubic([startX, startY, ctrl1x, ctrl1y, ctrl2x, ctrl2y, endX, endY], minDistance, roundToNearest, sampleFrequency); | ||
const interpolatedPts = calculateCoordinatesCubic([startX, startY, ctrl1x, ctrl1y, ctrl2x, ctrl2y, endX, endY], minDistance, roundToNearest, sampleFrequency, 6); | ||
pts.push(...interpolatedPts); | ||
@@ -144,0 +144,0 @@ |
@@ -53,3 +53,3 @@ /** | ||
constructor(a = 1, b = 0, c = 0, d = 1, e = 0, f = 0) { | ||
this.m_transform = [a, b, c, d, e, f]; | ||
this.m_transform = [+a, +b, +c, +d, +e, +f]; | ||
} | ||
@@ -63,8 +63,8 @@ | ||
const m_transform = this.m_transform; | ||
m_transform[0] = a; | ||
m_transform[1] = b; | ||
m_transform[2] = c; | ||
m_transform[3] = d; | ||
m_transform[4] = e; | ||
m_transform[5] = f; | ||
m_transform[0] = +a; | ||
m_transform[1] = +b; | ||
m_transform[2] = +c; | ||
m_transform[3] = +d; | ||
m_transform[4] = +e; | ||
m_transform[5] = +f; | ||
} | ||
@@ -85,3 +85,3 @@ | ||
static det(transform) { | ||
return transform[0] * transform[3] - transform[1] * transform[2]; | ||
return +(transform[0] * transform[3] - transform[1] * transform[2]); | ||
} | ||
@@ -88,0 +88,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
const parser = require('sax').parser(true); | ||
@@ -6,3 +6,3 @@ const calculators = require('./math/calculators'); | ||
const commandRegEx = /(m|l|c|q|z|a|v|h|s)(?: ?)([\d+-., ]+)/ig; | ||
const commandRegEx = /(m|l|c|q|z|a|v|h|s|z)(?: ?)([\d+-., ]*)/ig; | ||
const argumentsRegEx = /([-]?\d+\.*\d*)(?:,| )?/g; | ||
@@ -42,7 +42,7 @@ const transformRegEx = /(matrix|translate|scale|rotate|skewX|skewY)(?:\()(.*)(?:\))/; | ||
applyTransforms(transforms, points); | ||
if (!joinPathData){ | ||
if (!joinPathData) { | ||
let key = node.attributes.id || `path_${i++}`; | ||
interpolatedPaths[key] = points; | ||
} | ||
else{ | ||
else { | ||
interpolatedPaths.push(...points); | ||
@@ -113,18 +113,13 @@ } | ||
let lastCtrlY; | ||
const {command:lastC, points:lastP, offsets:lastO} = lastCommand; | ||
const {command:lastC, points:lastP} = lastCommand; | ||
const reg = command.toLowerCase() === 's' ? /^[cs]$/ : /^[qt]$/; | ||
if (reg.test(lastC.toLowerCase())) { | ||
const {length} = lastP; | ||
lastCtrlY = lastP[length - 3]; | ||
lastCtrlX = lastP[length - 4]; | ||
lastCtrlY = lastP[length - 3]; | ||
} | ||
args = points.concat(); | ||
args = points; | ||
if (reg.test(lastC)) { | ||
lastCtrlX += lastO.offsetX; | ||
lastCtrlY += lastO.offsetY; | ||
} | ||
if (/^[st]$/.test(command)) { | ||
args = applyOffset(offsetX, offsetY, args); | ||
applyOffset(offsetX, offsetY, args, 4); | ||
} | ||
@@ -136,7 +131,20 @@ args.unshift(offsetX, offsetY, lastCtrlX, lastCtrlY); | ||
case 'a': | ||
points.unshift(0, 0); | ||
args = [applyOffset(offsetX, offsetY, points, 7)]; | ||
break; | ||
case 'c': | ||
applyOffset(offsetX, offsetY, points, 6); | ||
points.unshift(offsetX, offsetY); | ||
args = [points]; | ||
break; | ||
case 'l': | ||
points.unshift(0, 0); | ||
args = [applyOffset(offsetX, offsetY, points, 2)]; | ||
break; | ||
case 'q': | ||
points.unshift(0, 0); | ||
args = [applyOffset(offsetX, offsetY, points)]; | ||
args = [applyOffset(offsetX, offsetY, points, 4)]; | ||
break; | ||
@@ -151,16 +159,17 @@ | ||
case 'h': | ||
points.unshift(0, 0); | ||
points.push(0); | ||
args = [applyOffset(offsetX, offsetY, points)]; | ||
applyOffset(offsetX, offsetX, points, 2); // offsetX, offsetX is intentional | ||
points.unshift(offsetX, offsetY); | ||
points.push(offsetY); | ||
args = [points]; | ||
break; | ||
case 'm': | ||
subPathStartX = offsetX; | ||
subPathStartY = offsetY; | ||
args = [applyOffset(offsetX, offsetY, points.slice(2))]; | ||
subPathStartX = points[0] + offsetX; | ||
subPathStartY = points[1] + offsetY; | ||
args = [applyOffset(offsetX, offsetY, points.slice(2), 2)]; | ||
break; | ||
case 'M': | ||
subPathStartX = offsetX; | ||
subPathStartY = offsetY; | ||
subPathStartX = points[0]; | ||
subPathStartY = points[1]; | ||
args = [points.slice(2)]; | ||
@@ -175,4 +184,5 @@ break; | ||
case 'v': | ||
points.unshift(0, 0, 0); | ||
args = [applyOffset(offsetX, offsetY, points)]; | ||
applyOffset(offsetY, offsetY, points, 2); // offsetY, offsetY is intentional | ||
points.unshift(offsetX, offsetY, offsetX); | ||
args = [points]; | ||
break; | ||
@@ -182,3 +192,4 @@ | ||
case 'Z': | ||
args = [[subPathStartX, subPathStartY]]; | ||
points = [offsetX, offsetY, subPathStartX, subPathStartY]; | ||
args = [points]; | ||
break; | ||
@@ -195,10 +206,4 @@ } | ||
if (command.toLowerCase() === command) { | ||
offsetY += points[len - 1]; | ||
offsetX += points[len - 2]; | ||
} | ||
else { | ||
offsetY = points[len - 1]; | ||
offsetX = points[len - 2]; | ||
} | ||
offsetY = points[len - 1]; | ||
offsetX = points[len - 2]; | ||
} | ||
@@ -240,7 +245,13 @@ lastCommand = {command, points, offsets}; | ||
function applyOffset(offsetX, offsetY, coords = []) { | ||
return coords.map((value, index) => { | ||
return value + (index % 2 ? offsetY : offsetX); | ||
}); | ||
function applyOffset(offsetX, offsetY, coords = [], setLength = 2) { | ||
for (let i = 0; i < coords.length; i++) { | ||
if (i && i % +setLength === 0) { | ||
offsetX = coords[i - 2]; | ||
offsetY = coords[i - 1]; | ||
} | ||
coords[i] += (i % 2 ? +offsetY : +offsetX); | ||
} | ||
return coords; | ||
} | ||
module.exports = class SVGPathInterpolator { | ||
@@ -247,0 +258,0 @@ /** |
844
74
37306
Updatedsax@^1.2.4