Skip to content

Commit

Permalink
Slightly cleaner.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Feb 26, 2016
1 parent be1eb45 commit 8a8e7cf
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 58 deletions.
52 changes: 26 additions & 26 deletions src/transform/decompose.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
var rad2deg = 180 / Math.PI;

export default function(matrix) {
var r0 = [matrix.a, matrix.b],
r1 = [matrix.c, matrix.d],
kx = normalize(r0),
kz = dot(r0, r1),
ky = normalize(combine(r1, r0, -kz)) || 0;
export var identity = {
translateX: 0,
translateY: 0,
rotate: 0,
skewX: 0,
scaleX: 1,
scaleY: 1
};

if (r0[0] * r1[1] < r1[0] * r0[1]) r0[0] *= -1, r0[1] *= -1, kx *= -1, kz *= -1;
export default function(a, b, c, d, e, f) {
if (a * d === b * c) return null;

return {
rotate: (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * rad2deg,
translate: [matrix.e, matrix.f],
scale: [kx, ky],
skew: ky ? Math.atan2(kz, ky) * rad2deg : 0
};
}
var scaleX = Math.sqrt(a * a + b * b);
a /= scaleX, b /= scaleX;

function dot(a, b) {
return a[0] * b[0] + a[1] * b[1];
}
var skewX = a * c + b * d;
c -= a * skewX, d -= b * skewX;

function normalize(a) {
var k = Math.sqrt(dot(a, a));
if (k) a[0] /= k, a[1] /= k;
return k;
}
var scaleY = Math.sqrt(c * c + d * d);
c /= scaleY, d /= scaleY, skewX /= scaleY;

if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;

function combine(a, b, k) {
a[0] += k * b[0];
a[1] += k * b[1];
return a;
return {
translateX: e,
translateY: f,
rotate: Math.atan2(b, a) * rad2deg,
skewX: Math.atan(skewX) * rad2deg,
scaleX: scaleX,
scaleY: scaleY
};
}
48 changes: 24 additions & 24 deletions src/transform/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,49 @@ function interpolateTransform(parse, pxComma, pxParen, degParen) {
return s.length ? s.pop() + " " : "";
}

function translate(ta, tb, s, q) {
if (ta[0] !== tb[0] || ta[1] !== tb[1]) {
function translate(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push("translate(", null, pxComma, null, pxParen);
q.push({i: i - 4, x: number(ta[0], tb[0])}, {i: i - 2, x: number(ta[1], tb[1])});
} else if (tb[0] || tb[1]) {
s.push("translate(" + tb[0] + pxComma + tb[1] + pxParen);
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb || yb) {
s.push("translate(" + xb + pxComma + yb + pxParen);
}
}

function rotate(ra, rb, s, q) {
if (ra !== rb) {
if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(ra, rb)});
} else if (rb) {
s.push(pop(s) + "rotate(" + rb + degParen);
function rotate(a, b, s, q) {
if (a !== b) {
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "rotate(" + b + degParen);
}
}

function skew(wa, wb, s, q) {
if (wa !== wb) {
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(wa, wb)});
} else if (wb) {
s.push(pop(s) + "skewX(" + wb + degParen);
function skewX(a, b, s, q) {
if (a !== b) {
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)});
} else if (b) {
s.push(pop(s) + "skewX(" + b + degParen);
}
}

function scale(ka, kb, s, q) {
if (ka[0] !== kb[0] || ka[1] !== kb[1]) {
function scale(xa, ya, xb, yb, s, q) {
if (xa !== xb || ya !== yb) {
var i = s.push(pop(s) + "scale(", null, ",", null, ")");
q.push({i: i - 4, x: number(ka[0], kb[0])}, {i: i - 2, x: number(ka[1], kb[1])});
} else if (kb[0] !== 1 || kb[1] !== 1) {
s.push(pop(s) + "scale(" + kb + ")");
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
} else if (xb !== 1 || yb !== 1) {
s.push(pop(s) + "scale(" + xb + "," + yb + ")");
}
}

return function(a, b) {
var s = [], // string constants and placeholders
q = []; // number interpolators
a = parse(a), b = parse(b);
translate(a.translate, b.translate, s, q);
translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
rotate(a.rotate, b.rotate, s, q);
skew(a.skew, b.skew, s, q);
scale(a.scale, b.scale, s, q);
skewX(a.skewX, b.skewX, s, q);
scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
a = b = null; // gc
return function(t) {
var i = -1, n = q.length, o;
Expand Down
16 changes: 8 additions & 8 deletions src/transform/parse.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import decompose from "./decompose";
import decompose, {identity} from "./decompose";

var identity = {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0},
cssNode,
var cssNode,
cssRoot,
cssView,
svgNode;

export function parseCss(value) {
if (value === "none") return decompose(identity);
if (value === "none") return identity;
if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
cssNode.style.transform = value;
cssRoot.appendChild(cssNode);
value = cssView.getComputedStyle(cssNode, null).getPropertyValue("transform");
cssRoot.removeChild(cssNode);
var m = value.slice(7, -1).split(",");
return decompose({a: +m[0], b: +m[1], c: +m[2], d: +m[3], e: +m[4], f: +m[5]});
};
return decompose(+m[0], +m[1], +m[2], +m[3], +m[4], +m[5]);
}

export function parseSvg(value) {
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
svgNode.setAttribute("transform", value == null ? "" : value);
return decompose(svgNode.transform.baseVal.consolidate().matrix);
};
var m = svgNode.transform.baseVal.consolidate().matrix;
return decompose(m.a, m.b, m.c, m.d, m.e, m.f);
}

0 comments on commit 8a8e7cf

Please sign in to comment.