Skip to content

Instantly share code, notes, and snippets.

@joshblack
Created August 17, 2015 15:42
Show Gist options
  • Save joshblack/33831e664d64126b2a4c to your computer and use it in GitHub Desktop.
Save joshblack/33831e664d64126b2a4c to your computer and use it in GitHub Desktop.
const box = document.querySelector('div');
animate(box, {
translated: [250, 250],
rotated: 360,
scaled: [2, 2]
}, 1000, scaling);
function scaling(node) {
return animate(node, {
translated: [250, 250],
rotated: 360,
scaled: [4, 4]
}, 1000, () => {});
}
function css(m) {
const [a, c, ty] = m[0];
const [b, d, tx] = m[1];
return `matrix(${a}, ${b}, ${c}, ${d}, ${tx}, ${ty})`;
}
function matrix({ a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0 } = {}) {
return [
[a, c, ty],
[b, d, tx],
[0, 0, 1]
];
}
function multiply(a, b) {
return [
[
a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0],
a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1],
a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2]
],
[
a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0],
a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1],
a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2]
],
[
a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0],
a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1],
a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2]
],
];
}
function scale(a, d) {
return matrix({ a, d });
}
function translate(tx, ty) {
return matrix({ tx, ty });
}
function rotate(theta) {
const { cos, sin, PI } = Math;
const rad = theta * (PI / 180);
return matrix({
a: cos(rad),
b: sin(rad),
c: -sin(rad),
d: cos(rad)
});
}
// Analogous to transform: translate | scale | rotate;
// box.style.transform = css(translate(50, 50));
// box.style.transform = css(scale(2, 2));
// box.style.transform = css(rotate(45));
function transform({ T = matrix(), R = matrix(), S = matrix() }) {
return css(multiply(multiply(T, R), S));
}
// Analogous to transform: matrix;
// Translate x: 50px, y: 50px
// box.style.transform = transform({ T: translate(50, 50) });
// Rotate θ: 45deg
// box.style.transform = transform({ R: rotate(45) });
// Scale x: 2, y: 2
// box.style.transform = transform({ S: scale(2, 2) });
// Translate x: 250px, y: 250px, Scale x: 2, y: 2
// box.style.transform = transform({
// T: translate(250, 250),
// S: scale(2, 2)
// });
// Translate x: 250px, y: 250px, Rotate θ: 45deg
// box.style.transform = transform({
// T: translate(250, 250),
// R: rotate(45)
// });
// Translate x: 250px, y: 250px, Rotate θ: 45deg, Scale x: 2, y: 2
// box.style.transform = transform({
// T: translate(250, 250),
// R: rotate(45),
// S: scale(2, 2)
// });
function lerp(v0, v1, t) {
return (1 - t) * v0 + t * v1;
}
function animate(node, {
translated = [0, 0],
rotated = 0,
scaled = [1, 1]
} = {}, duration, cb) {
const start = Date.now();
loop();
console.log('started');
console.log(translated);
console.log(rotated);
console.log(scaled);
function loop() {
const step = (Date.now() - start) / duration;
node.style.transform = transform({
T: translate(
lerp(0, translated[0], step),
lerp(0, translated[1], step)
),
R: rotate(
lerp(0, rotated, step)
),
S: scale(
lerp(1, scaled[0], step),
lerp(1, scaled[1], step)
)
});
if (step <= 1) {
requestAnimationFrame(loop);
} else {
node.style.transform = transform({
T: translate(translated[0], translated[1]),
R: rotate(rotated),
S: scale(scaled[0], scaled[1])
});
cb(node, {
translated: translate(translated[0], translated[1]),
rotated: rotate(rotated),
scaled: scale(scaled[0], scaled[1])
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment