Created
November 14, 2017 00:07
-
-
Save msand/aa70b252c1a684f5e24a207223e60b32 to your computer and use it in GitHub Desktop.
svg transform parser in peg.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
const deg2rad = Math.PI / 180; | |
/* | |
a c e | |
( b d f ) | |
0 0 1 | |
*/ | |
function multiply_matrices(l, r) { | |
const [al, cl, el, bl, dl, fl] = l; | |
const [ar, cr, er, br, dr, fr] = r; | |
const a = al * ar + cl * br; | |
const c = al * cr + cl * dr; | |
const e = al * er + cl * fr + el; | |
const b = bl * ar + dl * br; | |
const d = bl * cr + dl * dr; | |
const f = bl * er + dl * fr + fl; | |
return [a, c, e, b, d, f]; | |
} | |
} | |
transformList | |
= wsp* ts:transforms? wsp* { return ts; } | |
transforms | |
= t:transform commaWsp+ ts:transforms | |
{ | |
return multiply_matrices(t, ts); | |
} | |
/ t:transform | |
transform | |
= matrix | |
/ translate | |
/ scale | |
/ rotate | |
/ skewX | |
/ skewY | |
matrix | |
= "matrix" wsp* "(" wsp* | |
a:number commaWsp | |
b:number commaWsp | |
c:number commaWsp | |
d:number commaWsp | |
e:number commaWsp | |
f:number wsp* ")" | |
{ | |
return [ | |
a, c, e, | |
b, d, f | |
]; | |
} | |
translate | |
= "translate" wsp* "(" wsp* tx:number ty:commaWspNumber? wsp* ")" | |
{ | |
return [ | |
1, 0, tx, | |
0, 1, ty || 0 | |
]; | |
} | |
scale | |
= "scale" wsp* "(" wsp* sx:number sy:commaWspNumber? wsp* ")" | |
{ | |
return [ | |
sx, 0, 0, | |
0, sy === null ? sx : sy, 0 | |
]; | |
} | |
rotate | |
= "rotate" wsp* "(" wsp* angle:number c:commaWspTwoNumbers? wsp* ")" | |
{ | |
const cos = Math.cos(deg2rad * angle); | |
const sin = Math.sin(deg2rad * angle); | |
if (c !== null) { | |
const [x, y] = c; | |
return [ | |
cos, -sin, cos * -x + -sin * -y + x, | |
sin, cos, sin * -x + cos * -y + y | |
]; | |
} | |
return [ | |
cos, -sin, 0, | |
sin, cos, 0 | |
]; | |
} | |
skewX | |
= "skewX" wsp* "(" wsp* angle:number wsp* ")" | |
{ | |
return [ | |
1, Math.tan(deg2rad * angle), 0, | |
0, 1, 0 | |
]; | |
} | |
skewY | |
= "skewY" wsp* "(" wsp* angle:number wsp* ")" | |
{ | |
return [ | |
1, 0, 0, | |
Math.tan(deg2rad * angle), 1, 0 | |
]; | |
} | |
number | |
= f:(sign? floatingPointConstant) { return parseFloat(f.join("")); } | |
/ i:(sign? integerConstant) { return parseInt(i.join("")); } | |
commaWspNumber | |
= commaWsp n:number { return n; } | |
commaWspTwoNumbers | |
= commaWsp n1:number commaWsp n2:number { return [n1, n2]; } | |
commaWsp | |
= (wsp+ comma? wsp*) / (comma wsp*) | |
comma | |
= "," | |
integerConstant | |
= ds:digitSequence { return ds.join(""); } | |
floatingPointConstant | |
= fractionalConstant exponent? | |
/ digitSequence exponent | |
fractionalConstant "fractionalConstant" | |
= d1:digitSequence? "." d2:digitSequence { return [d1 ? d1.join("") : null, ".", d2.join("")].join(""); } | |
/ d:digitSequence "." { return d.join(""); } | |
exponent | |
= [eE] sign? digitSequence | |
sign | |
= [+-] | |
digitSequence | |
= digit+ | |
digit | |
= [0-9] | |
wsp | |
= [\u0020\u0009\u000D\u000A] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment