Javascript (D3+React_アニメーションサンプル)
■歯車のサンプル。
地図、ツリー、関数と見てきたけど、他に何かめぼしいものがないかD3の公式サイトを見ていたら、歯車を動かしているアニメーションがあった。それを簡素化したバージョンにして動かしてみた。

2つの歯車(左が歯数40、右が16)で2.5:1の比率。Speedのスライダーやテキストボックスで回転する速度を指定。
歯車のコードが下。teethが歯数、rootR, tipRで外径の溝部分を指定、holeRで内側の中抜きの部分を指定する。Math.PIはπ。かみ合わせの部分は溝や位置を調整してそれらしく見せている。
const gear = ({ teeth, rootR, tipR, holeR }) => {
const n = teeth;
const da = Math.PI / n;
let a = -Math.PI / 2;
const p = ["M", rootR * Math.cos(a), ",", rootR * Math.sin(a)];
for (let i = 0; i < n; i++) {
p.push(
"A", rootR, ",", rootR, " 0 0,0 ",
rootR * Math.cos(a += da), ",", rootR * Math.sin(a),
"L", tipR * Math.cos(a), ",", tipR * Math.sin(a),
"A", tipR, ",", tipR, " 0 0,0 ",
tipR * Math.cos(a += da), ",", tipR * Math.sin(a),
"L", rootR * Math.cos(a), ",", rootR * Math.sin(a)
);
}
p.push(
"M0,", -holeR,
"A", holeR, ",", holeR, " 0 0,0 0,", holeR,
"A", holeR, ",", holeR, " 0 0,0 0,", -holeR,
"Z"
);
return p.join("");
};
アニメーション部分が下。rotateで回転させたものをrequestAnimationFrameで呼び出して再描画。このとき歯車の比率に応じて歯車ごとに角度を調整。
const animate = (big, small) => {
let t = 0;
const svg = d3.select(svgRef.current);
const gears = svg.selectAll(".gear");
const ratio = -(big.teeth / small.teeth);
const tick = () => {
t += speedRef.current * 0.0005;
gears.attr("transform", d => {
const angle = (d === big) ? t :
(d === small ? t * ratio : 0);
return `translate(${d.origin}) rotate(${angle * 180 / Math.PI})`;
});
requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
};
速い速度は映しきれなかったけど、動作サンプルが下。
このくらいのアニメーションであれば、D3を使わなくても実現できるのではないかと思う。公式サイトのExamplesで他にひかれるものもないので、D3については一端このくらいにしておこうと思う。

