GODRICH
#cssアニメーション#ボタン#ローディング#トランジション#スクロール#ダッシュボード#実用ui#デザイントレンド

フーリエ変換 アニメーション 9種 — 円の連鎖で星とハートを描き直す

フーリエ変換 アニメーションとは、絵を描き直す作業ではなく、絵に隠れていた周波数を円の連鎖として巻き戻す計算です。ライブラリ・WebGLなしで、描きたい線の点を複素平面上に置き、サイン・コサインの積分を一度走らせると、円の上に円が載って回るエピサイクルが生まれます。

デモ

自動再生 · タイルを押すとその項目へ · すべて1つのzip

手入力の係数から離散フーリエ変換まで、九つの段階

並び順の基準は見栄えではなく係数がどこから来て、どこへ流れるかです。01は係数を手で定義する再合成の最小単位で、02が奇数倍音のサイン級数という古典的な合成を円の縦スタックで示し、03で初めて描いた線の点に離散フーリエ変換をかけます。04はその係数の上位だけを使う圧縮の予告編、05は読者の線そのものを係数に変え、06は係数の大きさをバーで見せて「絵の指紋」とも言えるスペクトラムを示します。07は大きさを凍結して位相だけを回す分離実験、08は円の数を1から64まで動かして「どこまで減らしても形が残るか」を確かめ、09が暗い舞台の演出で締めくくります。9種すべてで24フレーム中23フレームが動き続けました。規則の反復だけで形が決まる点では、群れの個体がまわりの位置だけで操舵するボイドのシミュレーションや、匂いを追う点の集まりが自ら最短経路を育てる粘菌のシミュレーションと同じ種類の面白さです。

9種の計算は1本の道ではない

誤解しやすい点を先に言っておくと、9種全部が同じ計算を回しているわけではありません。03・04・05・07・08・09は経路の点に離散フーリエ変換を走らせる本流で、01は係数を手で定義しただけの最小構成、02はサイン級数を直接足す合成、06は2つの絵の係数を補間するという、それぞれ別の入り口です。どこで係数が生まれるかを意識すると、9つの盤の違いが一目で読めるようになります。

項目別コード

項目ごとに、挙動を左右する定数の名前をそのまま示し、動いているデモの関数を丸ごと引用します。切り詰めた断片ではなく動いているコードそのものなので、この画面から自分のページへ貼って動かせます。コメントだけこの記事の言葉に置き換えてあり、変数名と関数名はzipの中身と同じ英語のままです。

01基本のエピサイクル連鎖 — 円の上に円が載って周回し、点を打つ構造

周波数2・3・5・7・9の5つの係数を半径0.34から0.05まで直接書き下ろし、外側の円の端から内側の円の中心へ順に繋ぐと、末端の点が花びらのような対称模様を描いて周回します。DFTもサンプリングもまだ登場しない、f(t) = Σ r_k·e^(i(k·t + φ_k)) をそのまま画面に置いた構造です。背景の極座標グリッドは回るスポーク16本と息づく同心円4つを毎フレーム描き直し、24フレーム中23フレームが動いて累積面積36.176%、強度平均は06と並んで9種で最も明るい33.1に達します。

基本のエピサイクル連鎖 — 円の上に円が載って周回し、点を打つ構造
新しいタブで開く

01 · 基本のエピサイクル連鎖 — 円の上に円が載って周回し、点を打つ構造 — 計測 累積面積 36.176% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DarcrequestAnimationFrame

半径が小さくなる円を順に繋ぐだけの最小構造

係数はk(周波数)・r(半径比)・p(初期位相)の3つ組で、角度k·t + pの位置へ前の円の端から次の中心を置くだけです。あと8つの盤はすべて、このCOEF配列の中身をどう用意するかの違いだと読めます。

  // 係数5つ — 周波数2・3・5・7・9。位相をずらして花びらの対称が出るようにする
  var COEF = [
    { k: 2, r: 0.34, p: 0.0 },
    { k: 3, r: 0.18, p: 1.1 },
    { k: 5, r: 0.12, p: 2.4 },
    { k: 7, r: 0.07, p: 0.6 },
    { k: 9, r: 0.05, p: 3.6 }
  ];

  // 係数チェーンを角度tで回してペン位置までの中心列を計算する
  function computeChain(t) {
    var cx = W * 0.5, cy = H * 0.5;
    var base = Math.min(W, H) * 0.48;
    var pts = [{ x: cx, y: cy }];
    for (var i = 0; i < TERMS && i < COEF.length; i++) {
      var c = COEF[i];
      var a = c.k * t + c.p;
      var px = pts[i].x + Math.cos(a) * c.r * base;
      var py = pts[i].y + Math.sin(a) * c.r * base;
      pts.push({ x: px, y: py });
    }
    return pts;
  }

02矩形波の合成 — 奇数倍音の円いくつかで角ある波形を作る

第1・3・5・7次の奇数倍音だけを重ねると、滑らかな円運動の和が急峻な階段へ変わる瞬間が毎フレーム描かれます。各項は半径AMP/kの円がk倍速で回るものと同じで、左に円の連鎖を縦に積み、末端の高さを右の波形領域に時間軸で展開して積んでいきます。AMPには級数の振幅係数4/π≈1.2732を使い、24フレーム中23フレームが動いて累積面積36.88%、フレーム最大面積は9.004%です。

矩形波の合成 — 奇数倍音の円いくつかで角ある波形を作る
新しいタブで開く

02 · 矩形波の合成 — 奇数倍音の円いくつかで角ある波形を作る — 計測 累積面積 36.88% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DlineTorequestAnimationFrame

奇数倍音の縦スタックが階段を作る

角のある波形がサインの和でできている様子を、式ではなく円の重ね方で見せる盤です。円の数を増やすほど立ち上がりは急になり、TERMS=4の4段でもう階段の輪郭がはっきり読めます。

  function computeChain(t) {
    // 縦スタック: 円kの半径 = AMP/k、角速度 = k
    var pts = [];
    var cx = W * 0.24, cy = H * 0.5;
    var base = H * 0.36;
    pts.push({ x: cx, y: cy });
    for (var k = 1; k <= TERMS * 2; k += 2) {
      var y = pts[pts.length - 1].y + Math.sin(k * t) * (AMP / k) * base;
      pts.push({ x: cx, y: y });
    }
    return pts;
  }

03星を描く — 係数サイズ順でペン先が一筆で星を描く

五芒星(外側半径1・内側0.42、10個の頂点を通る閉じた経路)を256点でサンプリングして離散フーリエ変換を走らせ、係数を大きさ順に並べ直すと、ペン先が頂点を一つも逃さず一周して元の星を再現します。再合成に使うのは大きさ順の上位14個(SHOW=14)だけで、残りの係数は使わずにここまでの形が立ち上がります。HOLD=0.45の割りだけ完成図に停留し、24フレーム中23フレームが動いて累積面積45.551%です。

星を描く — 係数サイズ順でペン先が一筆で星を描く
新しいタブで開く

03 · 星を描く — 係数サイズ順でペン先が一筆で星を描く — 計測 累積面積 45.551% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DlineTorequestAnimationFrame

256点の星を係数へ変える二重ループ

経路の各点を複素数x + iyと見なし、すべての周波数kについて積算するN=256の二重ループがDFTの本体です。N=256ならO(N²)でも一瞬で終わるので、FFTライブラリは不要です。k > N/2の係数は負の周波数(k - N)へ折り畳み、大きさ順にソートして連鎖の順番を決めます。

  function dft(path) {
    var M = path.length;
    var out = [];
    for (var k = 0; k < M; k++) {
      var freq = (k <= M / 2) ? k : k - M;   // 負の周波数へ折り畳む
      var re = 0, im = 0;
      for (var n = 0; n < M; n++) {
        var a = -TAU * k * n / M;
        var c = Math.cos(a), s = Math.sin(a);
        re += path[n].x * c - path[n].y * s;
        im += path[n].x * s + path[n].y * c;
      }
      re /= M; im /= M;
      out.push({ freq: freq, re: re, im: im, amp: Math.sqrt(re * re + im * im) });
    }
    out.sort(function (a, b) { return b.amp - a.amp; });   // 大きさ順ソート
    return out;
  }

04ハートを描く — 閉曲線の係数でハートを蘇らせる

ハートの媒介変数曲線を256点でサンプリングして同じ変換にかけ、大きさ順ソートのあと上位60個(SHOW=60)だけを描くと、連鎖が窪み(くびれ)から始まって凹んだ部分まで正確になぞります。03より多くの円を使うのは、尖った星に対してハートの滑らかな膨らみと窪みの両方を追うためで、係数を捨てても形の本質が残る圧縮の予告編です。24フレーム中23フレームが動き、累積面積46.641%・強度平均27.7です。

ハートを描く — 閉曲線の係数でハートを蘇らせる
新しいタブで開く

04 · ハートを描く — 閉曲線の係数でハートを蘇らせる — 計測 累積面積 46.641% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DlineTorequestAnimationFrame

閉じた曲線を式から点列へ

ハートの形そのものは3行の数式で与え、uを0から1まで動かしてx・yを取り出します。星の頂点でも署名の落書きでも、閉じた経路を点列にさえすれば同じパイプラインに乗るので、05の自由描画へそのまま橋渡しできます。

  // ── ① ハートの媒介変数曲線 ──
  function heartPath(u) {
    var t = u * TAU;
    var x = 16 * Math.pow(Math.sin(t), 3);
    var y = -(13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));
    return { x: x / 17, y: y / 17 };
  }

05自分の線を描く — マウスで引いたら円がその場で蘇らせる

キャンバスにpointerdownからpointermoveで線を引くと、動かすたびにその点列が即座に正規化され、複素係数へ変換されて、描いたばかりの署名や落書きを48個の円が一筆ずつ描き直します。計算はO(N²)ですが点数は最大512点(MAXPTS=512)に抑えるので一瞬で済み、入力がない間はサンプルの落書きを薄いアルファで敷いておきます。24フレーム中23フレームが動いて累積面積42.997%です。

自分の線を描く — マウスで引いたら円がその場で蘇らせる
新しいタブで開く

05 · 自分の線を描く — マウスで引いたら円がその場で蘇らせる — 計測 累積面積 42.997% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

pointerdownpointermoverequestAnimationFrame

線を引くたびに係数が生まれ変わる

moveDrawが点を4px以上動いたぶんだけPATHへ積み、normalize()で中心と幅を揃えてからDFTをかけ直します。ペン先の記憶prevPenを毎回捨てるので、係数が入れ替わった瞬間から軌跡が新しい絵へ滑らかに切り替わります。

  // ── 入力 — 線を描くと即座にDFTを再計算 ──
  function moveDraw(e) {
    if (!drawing) return;
    var p = toField(e);
    if (Math.abs(p.x - lastPt.x) + Math.abs(p.y - lastPt.y) < 4) return;
    PATH.push(p);
    if (PATH.length > MAXPTS) PATH.shift();
    handCtx.strokeStyle = rgba(C_HOT, 0.28);
    handCtx.lineWidth = 2;
    handCtx.lineCap = 'round';
    handCtx.beginPath();
    handCtx.moveTo(lastPt.x, lastPt.y);
    handCtx.lineTo(p.x, p.y);
    handCtx.stroke();
    lastPt = p;
    normalize();
    prevPen = null;
    e.preventDefault();
  }

06スペクトラムバー — 係数の大きさが示す『どの円が働いているか』

星と「均一スペクトラム」の落書き(多くの周波数が似た大きさで混ざった波模様)の2つのDFT係数を周波数スロット±12にバーで立てて見せながら、両者の係数を振幅のlerpと位相の混合でMORPH=2.6秒周期で往復補間すると、絵の指紋が星(低い周波数のわずかだけが働く)から落書き(均一な櫛)へ連続変形します。バーの帯が画面の狭い領域を占める項目の性格上、フレーム最大面積は9種で最も小さい2.672%ですが、強度平均33.1は01と並んで最も明るい値です。

スペクトラムバー — 係数の大きさが示す『どの円が働いているか』
新しいタブで開く

06 · スペクトラムバー — 係数の大きさが示す『どの円が働いているか』 — 計測 累積面積 36.266% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DfillRectrequestAnimationFrame

振幅のlerpと位相の混合で指紋が変わる

coefAtが周波数ごとに星の係数と落書きの係数を1つのmixで混ぜます。振幅は単純な線形補間、位相はatan2で取り出した両者の角度を同じ比率で混ぜるので、棒の高さと並びの両方が同時に変わり、モーフが円の連鎖とバーの両方に現れます。

  // 補間係数 — mix 0(星)〜1(落書き)。振幅はlerp、位相は星の位相を優先
  function coefAt(mix) {
    var used = [];
    for (var fi = -NBARS / 2; fi <= NBARS / 2; fi++) {
      if (fi === 0 && mix < 0.5) continue;
      var s = slotStar[fi], d = slotDoodle[fi];
      if (!s || !d) continue;
      used.push({
        freq: fi,
        amp: s.amp + (d.amp - s.amp) * mix,
        ph: s.ph !== undefined ? s.ph + (d.ph - s.ph) * mix : 0
      });
    }
    // 位相を埋める(初回計算後に固定)
    for (var i = 0; i < used.length; i++) {
      var s2 = slotStar[used[i].freq], d2 = slotDoodle[used[i].freq];
      used[i].ph = Math.atan2(s2.im, s2.re) + (Math.atan2(d2.im, d2.re) - Math.atan2(s2.im, s2.re)) * mix;
    }
    return used;
  }

07位相モーフ — 係数はそのまま、位相だけ回すと模様が変身する

星の経路(03と同一)の係数で振幅を凍結し、位相にだけ周波数比例のオフセットφ_k = d·kを足すと、ペン先の軌跡が星から花びら・渦へ連続変身します。dはSWEEP=2.4秒周期のサイン波で-0.8〜0.8の範囲を往復し、軌跡は透明キャンバスに積まれてモーフが通った跡が残像として重なります。1フレームあたりの変化は9種で最も大きく、フレーム最大面積15.098%を記録しました。

位相モーフ — 係数はそのまま、位相だけ回すと模様が変身する
新しいタブで開く

07 · 位相モーフ — 係数はそのまま、位相だけ回すと模様が変身する — 計測 累積面積 40.69% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

CanvasRenderingContext2DglobalAlpharequestAnimationFrame

位相だけを掛けて動かす実験

chainAtのphにc.freq * dを1行足すだけで、大きさは「どれだけ」を、位相は「どこから」を担うという役割分担がそのまま見えます。位相を元に戻すと軌跡は必ず星へ戻るので、絵の正体が係数の大きさ側にあることを確認できます。

  function chainAt(u, d, show) {
    var base = Math.min(W, H) * 0.36;
    var cx = W * 0.32, cy = H * 0.5;
    var pts = [{ x: cx, y: cy }];
    for (var i = 0; i < show && i < COEF.length; i++) {
      var c = COEF[i];
      var ph = Math.atan2(c.im, c.re) + c.freq * d;
      var ang = c.freq * u * TAU + ph;
      pts.push({
        x: pts[i].x + Math.cos(ang) * c.amp * base,
        y: pts[i].y + Math.sin(ang) * c.amp * base
      });
    }
    return pts;
  }

08倍音スライダー — 円の数を減らすと絵がどう滲むか

ハート曲線(04と同一)の係数を大きさ順に用意し、円の数を1から64までのスライダーで動かすと、ハートが水滴のにじみからくっきりしたハートへ蘇ります。自動デモはSWEEP=3.2秒周期の三角波で数を往復させ、スライダーを直接つかむと自動モードが切れて人の値で動きます。フレーム最大面積12.36%・強度平均31.8で、24フレーム中23フレームが動き続けます。

倍音スライダー — 円の数を減らすと絵がどう滲むか
新しいタブで開く

08 · 倍音スライダー — 円の数を減らすと絵がどう滲むか — 計測 累積面積 41.044% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

input[type=range]CanvasRenderingContext2DrequestAnimationFrame

三角波で円の数を往復させる

autoModeの間はコサインで作った三角波が1→64→1の往復を計算し、スライダーの見た目も同じ値へ追従します。pointerdown・input・keydownのどれかが来た時点で自動を切るので、デモと実験が1本のつまみで切り替わります。

    var show;
    if (autoMode) {
      // 自動往復 — 1→64→1。人がつかむと止まる
      var tri = 0.5 - 0.5 * Math.cos(lt * TAU / SWEEP);
      show = 1 + Math.round(tri * (MAXSHOW - 1));
      if (slider && String(slider.value) !== String(show)) slider.value = String(show);
    } else {
      show = slider ? parseInt(slider.value, 10) : MAXSHOW;
    }

09ロゴトレースシーン — 暗い舞台での一筆ロゴ公開

一筆書きの「G」ロゴ(300度の円弧と内側へ折れて横棒)の輪郭を03・04と同じ変換と再合成で描き直す、この回の締めの演出です。暗い舞台に半径もアルファも息づく中央照明を敷き、トレイルの減衰はα=0.012と9種で最も遅くして、居座る残像自体をコンセプトにします。円が止まった後も照明が息づき続けるので毎フレームが動き、累積面積は9種で最大の47.314%です。

ロゴトレースシーン — 暗い舞台での一筆ロゴ公開
新しいタブで開く

09 · ロゴトレースシーン — 暗い舞台での一筆ロゴ公開 — 計測 累積面積 47.314% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

createRadialGradientCanvasRenderingContext2DrequestAnimationFrame

円弧と横棒を自分で定義する

ロゴの形も星やハートと同じく自作の関数で与えます。経路の前72%が300度の円弧、残りが内側へ折れる横棒で、DFT以降は03と完全に同じパイプラインです。任意のブランドマークの一筆輪郭をこの1関数で差し替えられるのがこの盤の実用値です。

  // ── ① ロゴ輪郭 — "G"の一筆。円弧300度 + 内側へ折れて横棒 ──
  function logoPath(u) {
    // 0〜0.72: 円弧(-60度から240度の方向へ)、0.72〜1: 横棒
    var ARC = 0.72;
    var R = 1;
    if (u < ARC) {
      var ang = (-Math.PI / 6) + (u / ARC) * (TAU * 300 / 360) * -1;
      return { x: Math.cos(ang) * R * 0.62, y: Math.sin(ang) * R * 0.62 };
    }
    var f = (u - ARC) / (1 - ARC);
    var sx = Math.cos(-Math.PI / 6) * 0.62, sy = Math.sin(-Math.PI / 6) * 0.62;
    var ex = 0.42, ey = 0.02;
    var cx2 = sx + (ex - sx) * f, cy2 = sy + (ey - sy) * f;
    return { x: cx2, y: cy2 };
  }

なぜ円が回るだけで絵になるのか — 複素係数と周波数分解の計算

理由は1つで、線上の点はすでに回転の和だからです。描きたい線の点(x, y)を複素数z = x + iyと見なすと、その点列は周期1の関数z(u)と読めます。この関数は必ず単位円の回転e^(i·2πku)の和に分解できて、各回転の重みがフーリエ係数c_kです。フーリエ変換 描画と聞くと数式の話に見えますが、画面の上で起きているのは半径の足し算の繰り返しです。

点を複素数として積算するだけのDFT

03のdftがやっているのは、各周波数kについて全点に回転を掛けて平均を取る積算です。実部reと虚部imに分けた2行の積算がc_k = (1/N)·Σ z_n·e^(-i·2πkn/N)の実装そのもので、ライブラリも数値計算の仕組みも使わずMath.cosとMath.sinだけが回ります。得られた係数のamp = √(re² + im²)が円の半径、atan2(im, re)が回転の始まりの角度です。

大きさは半径、位相は始まりの角度

再合成では時刻u(0〜1)で各円の角度をfreq·u·2π + 位相と置き、前の円の端から次の中心を置いていきます。連鎖の最後の点はすべての回転の和そのものなので、一周し終えたとき元の絵が蘇ります。係数を大きさ順に並べるのは大きな円から載せることで連鎖が安定し、上位いくつかだけで形の輪郭が決まる——03の上位14個・04の上位60個・08の1〜64個が、この性質を直接確かめられる実験です。フーリエ解析 わかりやすく理解したいなら、式を眺めるよりこの円が載って回る画面を1周見るのが一番の近道です。

回転速度と並べ替え基準を変える3つの変種とreduced-motion

名前 変更する値 変わる感触
使う円の数 03のSHOW 14 → 5 頂点が丸まって柔らかい星になる
時間の速さ 01のSPEED 1.0 → 3.0 トレイルが長く尾を引いてハッチング模様になる
ソートの基準 03のソート 大きさ順 → 周波数順 軌跡は同じでも円の並び方ががらりと変わる

定数ブロックの1行を書き換えるだけ

3つとも書き換えるのはソース先頭の変数ブロックの1行だけです。円の数は形の解像度、速さは残像の長さ、ソートは連鎖の見た目という、それぞれ別の性格のつまみです。

動きを減らす設定で残る1枚

9盤すべてにprefers-reduced-motion: reduceの分岐が組み込まれており、ループを回さずトレイルを一周分先に打ってから最後の場面を固定し、キャンバスに.is-stillクラスを付けます。静止していても星やハートの完成図が丸ごと見えるので、動きを止めた訪問者に絵だけは届きます。

係数を大きさ順ではなく周波数順に並べると連鎖が崩れる落とし穴

実測で壊れた場面を3つ挙げます。どれも「見た目は合っているのに絵が蘇らない」系の、原因の特定に時間がかかる失敗です。

周波数の折り畳みを省くと閉じた経路が蘇らない

k > N/2の係数をそのまま正の周波数として使うと、後半の円がすべて逆向きに回り、経路の後ろ半分が裏返った別の図形になります。(k <= M / 2) ? k : k - Mの1行が正負両方の周波数をそろえる条件で、これを外すと星の頂点が1個おきに裏側へ飛びました。

大きさと位相を分けられず片方を捨てる

位相を捨てて振幅だけ使うと、円は正しく回ってもペン先が絵を見つけられず、中心の周りの対称な花模様になります。逆に07のように振幅を凍結して位相だけ動かすと形は別物に変わる——大きさが「どれだけ」、位相が「どこから」を担う証拠が、この失敗と実験の対になります。

毎フレームのクリアが残像の感覚を殺す

メインキャンバスを毎フレームclearRectして軌跡を配列から描き直すと、減衰の感覚が死んで彗星の尾が消えます。軌跡は透明なオフスクリーンキャンバスに積み、毎フレームdestination-outのrgba(0,0,0,α)でごくわずかずつ消すのが正解で、累積面積36〜47%・23フレーム遷移という数値条件はこの構成から出ています。

9つのソース一式が入ったzipを展開するパスワードはtjy7w4m5です。定数ブロックの1行を書き換えて壊し方を確かめる材料として使えます。

エピサイクル連鎖を組み込む前によくある質問

エピサイクル とは何で、どうやって絵を描くのですか?

円の上に円を載せて回す仕組みで、各円が1つの周波数を担当します。描きたい線の点を複素数に変換して周波数ごとの重み(係数)を求め、半径=係数の大きさ・速さ=周波数・始まりの角度=位相として円を大きい順に繋ぐと、末端の点の軌跡が元の線をなぞります。

描きたい線はいくつの点で用意すればいいですか?

この回の標準は256点です。少なくても閉じた経路であれば形は蘇りますが、尖った頂点や細かいくぼみを追うための係数が足りず丸まります。多ければ解像度は上がりますが、変換はO(N²)なので05では入力を512点までに抑えて、描きながらの再計算が一瞬で終わる範囲に収めています。

スマホのブラウザでもそのまま動きますか?

動きます。HTMLファイル1つの中のgetContext('2d')とrequestAnimationFrame、配列の四則演算だけで組まれており、WebGLも外部CDNもフォントの読み込みもありません。05の自由描画はポインターイベントで受け取るので、タッチ操作でもそのまま線を引けます。

ロゴ公開と手描きデモ — この9枚を実際どこに置くか

ブランドのイントロやローディング画面なら09 ロゴトレースシーンをそのまま使うのが一番早い方法です。暗い舞台の上で一筆が完成する演出がすでに組んであるので、パスをロゴの経路に差し替えるだけで済みます。訪問者に直接参加してほしいイベントページや芳名帳には05 自分の線を描くを置くと、マウスで引いた落書きがその場でエピサイクルとして蘇る体験になります。

音声・信号処理を説明する教育コンテンツなら06 スペクトラムバーが向いています。係数の大きさがどの円が働いているかを棒で示すので、フーリエ変換という抽象的な概念が目に見えるグラフに変わります。3枚ともファイル1つで完結しているので、追加のフレームワークなしで静的なセクションにそのまま組み込めます。

もっと読む

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。