Skip to content

Instantly share code, notes, and snippets.

@msand
Created November 14, 2017 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msand/aa70b252c1a684f5e24a207223e60b32 to your computer and use it in GitHub Desktop.
Save msand/aa70b252c1a684f5e24a207223e60b32 to your computer and use it in GitHub Desktop.
svg transform parser in peg.js
{
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