JSFiddle - React, Tailwind, and code Playground
HTML
Demonstration from <a href="http://yal.cc/angular-rotations-explained" target="_blank">blog post</a>.<br>
<canvas id="_130717" width="360" height="360">
CSS
#_130717 {
border: 1px solid #ddd;
border-radius: 4px;
background: rgba(255, 255, 255, 0.7);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
JavaScript
(function _130717js() {
var can = document.getElementById("_130717"), ctx,
cycle = function cycle(v, m, x) {
return m + ((v = (v -= m) % (x -= m)) < 0 ? v + x : v);
},
arotate = function arotate(a, b, s) {
return a + Math.max(-s, Math.min(s, cycle(b - a, -Math.PI, Math.PI)));
}, mouseX = can.width, mouseY = 0, angle = 0.1,
onTimer = function _130717tween() {
hasTimer = true;
var t = Math.atan2(mouseY, mouseX);
angle = arotate(angle, t, 0.1);
draw();
if (angle != t) setTimeout(onTimer, 30); else hasTimer = false;
}, hasTimer = false,
draw = function _130717draw() {
can.width += 0;
ctx.fillStyle = "rgba(0, 0, 0, 0.7)";
// transform:
ctx.save();
ctx.translate(can.width / 2, can.height / 2);
ctx.rotate(angle);
// fill triangle:
ctx.beginPath();
ctx.moveTo(-15, -20);
ctx.lineTo(-15, 20);
ctx.lineTo(25, 0);
ctx.closePath();
ctx.fill();
// restore transform:
ctx.restore();
};
if (!can || !can.getContext) return;
ctx = can.getContext("2d");
draw();
can.addEventListener("mousemove", function _130717mouseMove(e) {
mouseX = e.offsetX - can.width / 2;
mouseY = e.offsetY - can.height / 2;
if (!hasTimer) onTimer();
}, false);
})();