cvs
Version:
A basic canvas framework for 2d drawing.
116 lines (104 loc) • 2.66 kB
JavaScript
// https://github.com/jkroso/normalize-svg-path
import a2c from './a2c'
/* eslint-disable */
export default function normalize(path){
// init state
var prev
var result = []
var bezierX = 0
var bezierY = 0
var startX = 0
var startY = 0
var quadX = null
var quadY = null
var x = 0
var y = 0
for (var i = 0, len = path.length; i < len; i++) {
var seg = path[i]
var command = seg[0]
switch (command) {
case 'M':
startX = seg[1]
startY = seg[2]
break
case 'A':
var curves = a2c(x, y, seg[6], seg[7], seg[4], seg[5], seg[1], seg[2], seg[3])
if (!curves.length) continue
curves = curves.map(curve => {
const [x0, y0, x1, y1, x2, y2, x, y] = curve
return {x1, y1, x2, y2, x, y}
})
for (var j = 0, c; j < curves.length; j++) {
c = curves[j]
seg = ['C', c.x1, c.y1, c.x2, c.y2, c.x, c.y]
if (j < curves.length - 1) result.push(seg)
}
break
case 'S':
// default control point
var cx = x
var cy = y
if (prev == 'C' || prev == 'S') {
cx += cx - bezierX // reflect the previous command's control
cy += cy - bezierY // point relative to the current point
}
seg = ['C', cx, cy, seg[1], seg[2], seg[3], seg[4]]
break
case 'T':
if (prev == 'Q' || prev == 'T') {
quadX = x * 2 - quadX // as with 'S' reflect previous control point
quadY = y * 2 - quadY
} else {
quadX = x
quadY = y
}
seg = quadratic(x, y, quadX, quadY, seg[1], seg[2])
break
case 'Q':
quadX = seg[1]
quadY = seg[2]
seg = quadratic(x, y, seg[1], seg[2], seg[3], seg[4])
break
case 'L':
seg = line(x, y, seg[1], seg[2])
break
case 'H':
seg = line(x, y, seg[1], y)
break
case 'V':
seg = line(x, y, x, seg[1])
break
case 'Z':
seg = line(x, y, startX, startY)
break
}
// update state
prev = command
x = seg[seg.length - 2]
y = seg[seg.length - 1]
if (seg.length > 4) {
bezierX = seg[seg.length - 4]
bezierY = seg[seg.length - 3]
} else {
bezierX = x
bezierY = y
}
result.push(seg)
}
return result
}
function line(x1, y1, x2, y2){
return ['C', x1, y1, x2, y2, x2, y2]
}
function quadratic(x1, y1, cx, cy, x2, y2){
return [
'C',
x1/3 + (2/3) * cx,
y1/3 + (2/3) * cy,
x2/3 + (2/3) * cx,
y2/3 + (2/3) * cy,
x2,
y2
]
}
/* eslint-enable */