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

qr コード アニメーション css 9選 — 残り時間

スキャン失敗のせいでもなく、ただ長く浮いているせいでもない — qrコードローディングアニメーションの残り時間の比率の値ひとつが尽きることでリングが狭まり、角度が削られ、終わりに触れると揺れる。3番はその値でパルスリングの半径を狭め、4番は同じ値を角度に変えてリングを削り、8番は値が0に触れた瞬間に揺れを起こす。

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

9つのQRローディング画面を動かしているのはたった1つの残り時間の値です

このページのすべてのグリッドは、シードを固定した小さな線形合同法の乱数生成器(qrRandまたはseedRand。項目ごとに1回だけシードを与えます)から作った疑似ランダムなドットの模様です。QRコードのモジュール配置に見えますが何もエンコードしておらず、実際のカメラで読み取ることはできません。それぞれのデモの主役はコードの中身ではなく、ドットやリング、数字を動かしているひとつの値です。9つのうち01・02・05・06・07・09の6つは作業が進むにつれて0から1へ近づく進捗型の値を読み取り、出現の順番・スキャンラインまでの距離・認識のポップ・落ち着く比率・桁の入れ替わり・カルーセルの位置に使っています。残りの03・04・08の3つは逆に1から尽きていく残り時間の比率を読み取っていて、これが冒頭のフックが指しているものです。3番はその値でリングを狭め、4番は角度に変え、8番は値が0に触れるのを待って揺れます。ローディング アニメーション css のみで組める軽さを保ったまま、この値ひとつの切り替えで9通りの表情が生まれています。

01進捗の値でモジュールが順番に現れるQRコード

生成の進捗値が0から1へ満ちていくにつれてグリッドの黒いモジュールは一斉にではなく1つずつ現れていくので、コードが一瞬で完成するのではなく徐々に仕上がっていくように見え、その出現までの遅延はbuildModulesが計算する行の位置にqrRandでシードした小さなゆらぎを足したものをQR_MODULE_REVEAL_STAGGER_MSで間隔づけています。

進捗値の分だけモジュールが一つずつ満ちるQRコード
新しいタブで開く

01 · 進捗値の分だけモジュールが一つずつ満ちるQRコード — 計測 累積面積 17.923% · 動いたフレーム 9/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

QR_MODULE_REVEAL_STAGGER_MSbuildModulesqrRand
  // 計算のひと工夫: 各モジュールの行(y)の値を基準の遅延にし、そこにシード付き乱数のゆらぎを少し足すことで
  // 出現の波が自然に上から下へ広がるようにしています(実際のエンコードではありません)。
  var jitterRand = qrRand(20260924);
  var order = [];
  for (var y2 = 0; y2 < SIZE; y2 += 1) {
    for (var x2 = 0; x2 < SIZE; x2 += 1) {
      var jitter = (jitterRand() - 0.5) * QR_MODULE_REVEAL_STAGGER_MS;
      order.push({ x: x2, y: y2, delay: y2 * QR_MODULE_REVEAL_STAGGER_MS + jitter });
    }
  }
  var maxDelay = 0;
  order.forEach(function (o) { if (o.delay > maxDelay) maxDelay = o.delay; });

このQR_MODULE_REVEAL_STAGGER_MSという数値だけが動かしどころで、大きくすると各行のモジュールが時間的に離れて現れ、小さくするとグリッドがほぼ一枚のブロックのように満ちていきます。

測定: 累積面積はフレーム全体の17.9%、平均強度83.8、9/23 フレームで動きました。

02待っている間に四隅の枠が明滅するQRコード

スキャンラインの値がSWEEP_MSかけて画面を下へ走り、各コーナーの発光の強さは今そのラインがどれだけ近いかからcornerGlowが0から1の値へ変換して両端でクランプし、SCF_CORNER_GLOW_RANGE_PXが明るくなる範囲の広さを決めているので、4つのマークは一斉ではなく順番に明るくなったり暗くなったりします。

コーナーフレームが点滅して認識を待つQRコード
新しいタブで開く

02 · コーナーフレームが点滅して認識を待つQRコード — 計測 累積面積 28.194% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

SCF_CORNER_GLOW_RANGE_PXcornerGlowseedRand
  function cornerGlow(dist) {
    // 計算のひと工夫: スキャンラインまでの距離を0-1の発光の強さに変換し、範囲の外では0にしています。
    var p = 1 - dist / SCF_CORNER_GLOW_RANGE_PX;
    return p < 0 ? 0 : (p > 1 ? 1 : p);
  }

  function draw(elapsed) {
    var cw = canvas.width, ch = canvas.height;
    ctx.clearRect(0, 0, cw, ch);

どのコーナーも同じcornerGlow(dist)の値を読んでいるので、4つのマークはお互いずれることなく、常に一緒に明るくなったり暗くなったりします。

測定: 累積面積はフレーム全体の28.2%、平均強度62.6、23/23 フレームで動きました。

03残り時間の値でパルスリングが狭まるQRコード

PULSE_RING_INTERVAL_MSごとに新しいリングが生まれ、ringsForが返す今生きているすべてのリングの経過比率が各リングの半径をMAX_RADIUSまで決めているので、残り時間の比率が減っていくとまだ十分若くて大きく見えるリングの数そのものが減り、1本だけが縮むのではなく群れ全体がはっきりと締まって見えます。

残り時間値の分だけ狭まるパルスリングのQRコード
新しいタブで開く

03 · 残り時間値の分だけ狭まるパルスリングのQRコード — 計測 累積面積 40.212% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

PULSE_RING_INTERVAL_MSringsForMAX_RADIUS
  function ringsFor(elapsed) {
    var out = [];
    var firstIndex = Math.ceil((elapsed - RING_LIFE_MS) / PULSE_RING_INTERVAL_MS);
    var lastIndex = Math.floor(elapsed / PULSE_RING_INTERVAL_MS);
    for (var i = Math.max(0, firstIndex); i <= lastIndex; i += 1) {
      var born = i * PULSE_RING_INTERVAL_MS;
      var age = elapsed - born;
      if (age < 0 || age > RING_LIFE_MS) continue;
      out.push(age / RING_LIFE_MS);
    }
    return out;
  }

ringsForは実時間の時計を一度も参照せず、現在の経過値と各リングの誕生時刻を比べているだけなので、この狭まり方は比率そのものの性質であり、実際の時間経過ではありません。

測定: 累積面積はフレーム全体の40.2%、平均強度46.9、23/23 フレームで動きました。

04残り時間の値が角度の値に変わるカウントダウンリング

冒頭のフックで触れた残り時間の比率はそのまま角度(ratio * 360)に変換されて値が0に達するまで円形のリングを時計回りに削っていき、残り20%を切るとurgencyという値がリングの色を青から赤へ補間しながらカードの背景も明るくするので、終盤ほど緊迫感のある見た目に変わります。

残り時間値が角度値として削られるカウントダウンリング
新しいタブで開く

04 · 残り時間値が角度値として削られるカウントダウンリング — 計測 累積面積 61.73% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

QR_EXPIRE_DURATION_MSDEMO_ACCEL_FACTORurgency
    // 計算のひと工夫: 経過の比率を0-360度の角度に変換してリングを削り、残り20%を切ったところから
    // リングの色を青から赤へ補間しています。同じurgencyの値が背景の色調やリング外側の発光にも及ぶので、
    // 画面の広い範囲が一体になって変化します。
    var ratio = Math.min(1, virtualElapsed / QR_EXPIRE_DURATION_MS);
    var remainRatio = 1 - ratio;
    var angle = ratio * 360;
    var urgency = remainRatio < 0.2 ? (0.2 - remainRatio) / 0.2 : 0;
    var r1 = lerp(120, 255, urgency), g1 = lerp(200, 90, urgency), b1 = lerp(255, 90, urgency);
    var ringColor = 'rgb(' + Math.round(r1) + ',' + Math.round(g1) + ',' + Math.round(b1) + ')';

このデモはQR_EXPIRE_DURATION_MS——実際に30000ms、本番のカウントダウンでも使う値そのもの——をデモ専用のDEMO_ACCEL_FACTORで圧縮して、この画面では数秒でループが終わるようにしているだけで、定数そのものは変えていません。

測定: 累積面積はフレーム全体の61.7%、平均強度81.0、23/23 フレームで動きました。

05読み取られた瞬間にチェックマークへ折りたたまれるQRコード

スキャンが認識された瞬間、すべてのモジュールの位置の値は徐々にではなく一斉にチェックマークの形へ収束し、springScaleが1をSUCCESS_CHECK_SPRING_OVERSHOOTぶんだけ超えてから落ち着くので、ポップに小さなバウンドが加わってぴたっと止まるだけの動きにはなりません。

認識された瞬間チェック形に折りたたまれるQRコード
新しいタブで開く

05 · 認識された瞬間チェック形に折りたたまれるQRコード — 計測 累積面積 6.892% · 動いたフレーム 14/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

SUCCESS_CHECK_SPRING_OVERSHOOTspringScalePOP_START
  function springScale(p, overshoot) {
    if (p <= 0) return 0;
    if (p >= 1) return 1;
    var decay = Math.exp(-4.5 * p);
    return 1 + overshoot * decay * Math.cos(p * Math.PI * 2.2);
  }

  function clamp01(v) { return v < 0 ? 0 : (v > 1 ? 1 : v); }

springScaleは進捗とオーバーシュートを受け取るだけの再利用できる関数なので、モジュールの収束もチェックマークの線も同じバウンドの形で動き、2つの別々のイージングを揃える手間がありません。

測定: 累積面積はフレーム全体の6.9%、平均強度119.7、14/23 フレームで動きました。

06生成中にゆらぎの振幅が小さくなって落ち着くQRコード

生成の進捗値が大きくなるにつれて各モジュールのゆらぎの振幅はQR_NOISE_SETTLE_AMPLITUDE_PXからSETTLE_MSをかけて指数関数的にゼロへ減衰していくので最初はノイズのように震えていたグリッドがしだいに固定された配置へ落ち着き、各モジュールが自分だけの位相と方向を持っているぶん一様に縮むのではなく隣同士で少しずつタイミングをずらしながら静まっていきます。

揺れ幅が減って落ち着く生成中のQRコード
新しいタブで開く

06 · 揺れ幅が減って落ち着く生成中のQRコード — 計測 累積面積 10.958% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

QR_NOISE_SETTLE_AMPLITUDE_PXSETTLE_MSwobble
    // 計算のひと工夫: 振幅は時間とともに指数関数的に減っていきます — QR_NOISE_SETTLE_AMPLITUDE_PXから始まり
    // SETTLE_MSをかけて0へ収束し、各モジュールは自分だけの位相と方向で揺れながら落ち着いていきます。
    var settleP = Math.min(1, elapsed / SETTLE_MS);
    var amp = QR_NOISE_SETTLE_AMPLITUDE_PX * Math.exp(-4 * settleP);

    ctx.fillStyle = 'rgb(255,247,230)';
    modules.forEach(function (m) {
      var wobble = Math.sin(elapsed / 1000 * m.freq + m.phase) * amp;
      var jx = Math.cos(m.dir) * wobble;
      var jy = Math.sin(m.dir) * wobble;
      var s = cell * 0.68;
      var cx = ox + m.x * cell + cell / 2 + jx;
      var cy = oy + m.y * cell + cell / 2 + jy;
      ctx.globalAlpha = 0.55 + 0.45 * settleP;
      ctx.fillRect(cx - s / 2, cy - s / 2, s, s);
    });

最初の振幅ひとつだけが1フレーム目のノイズの荒さを決めていて、減衰のカーブや時間の長さは固定のままです。

測定: 累積面積はフレーム全体の11.0%、平均強度44.7、23/23 フレームで動きました。

07金額の桁が入れ替わるQRコードパネル

デモ内の仮の金額が変わるたびに各桁の入れ替わりの進捗はprogressForが桁ごとのずらし遅延を引いてからROLL_MSで割って計算するので末尾から離れた桁ほどわずかに遅れて動き始め、easeOutBackがその進捗を小さなオーバーシュートに変えるので各桁は止まりきる前に少しだけ弾みます。

決済金額の桁が回転して変わるQRコードパネル
新しいタブで開く

07 · 決済金額の桁が回転して変わるQRコードパネル — 計測 累積面積 11.454% · 動いたフレーム 20/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

AMOUNT_ROLL_DIGIT_STAGGER_MSeaseOutBackROLL_MS
  function easeOutBack(t) {
    var c1 = 1.4, c3 = c1 + 1;
    return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
  }

  function progressFor(elapsed, segStart, delay) {
    var local = elapsed - segStart - delay;
    if (local <= 0) return 0;
    if (local >= ROLL_MS) return 1;
    return local / ROLL_MS;
  }

AMOUNT_ROLL_DIGIT_STAGGER_MSだけが桁のずれ具合を決める値で、大きくすると左から右へ流れるように見え、ゼロに近づけると全部の桁が一斉に入れ替わります。

測定: 累積面積はフレーム全体の11.5%、平均強度74.0、20/23 フレームで動きました。

08残り時間の値が0に触れた瞬間に揺れるQRコード

残り時間の比率が0に触れた瞬間、shakeOffsetがSHAKE_FREQの速さとEXPIRED_SHAKE_AMPLITUDE_PXの上限でSHAKE_MSの間だけ減衰する正弦波を発生させ、その後は再発行のアイコンが現れながら揺れがゼロへ収まっていき、デモの自動再生ループは1周の中に2回の期限切れを仕込んでいるので揺れてから再試行するまでの流れを実際の長さを2回分待たずに確認できます。

残り時間値が0に触れると揺れる期限切れQRコード
新しいタブで開く

08 · 残り時間値が0に触れると揺れる期限切れQRコード — 計測 累積面積 32.133% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

EXPIRED_SHAKE_AMPLITUDE_PXshakeOffsetSHAKE_FREQ
  // 計算のひと工夫: 減衰する正弦波 — 周波数(SHAKE_FREQ)に指数的な減衰を掛け合わせて揺れを作っています。
  function shakeOffset(t) {
    if (t < 0 || t > SHAKE_MS) return 0;
    var p = t / SHAKE_MS;
    return Math.sin(p * Math.PI * 2 * SHAKE_FREQ) * EXPIRED_SHAKE_AMPLITUDE_PX * Math.exp(-3.2 * p);
  }

  // オートプレイの期限切れ区間: 1回目(EXPIRE_ATからRETRY_ATまで)、2回目(EXPIRE_AT2からループの終わりまで)。
  function autoExpired(elapsed) {
    return (elapsed >= EXPIRE_AT && elapsed < RETRY_AT) || elapsed >= EXPIRE_AT2;
  }
  function autoExpireStart(elapsed) {
    return elapsed < RETRY_AT ? EXPIRE_AT : EXPIRE_AT2;
  }

shakeOffsetは期限切れが始まってからの経過時間しか見ていないので、自動再生の2回の期限切れも、手動で再試行を押した場合も、揺れのロジックを重複させずに同じ関数でまかなえます。

測定: 累積面積はフレーム全体の32.1%、平均強度65.1、23/23 フレームで動きました。

09位置の値でコードを切り替えるQRカルーセル

クーポン・ポイント・支払いのコードはそれぞれ5つの位置の値のどれかに対応していて、easeInOutが2つの位置の間の端数を直線的にではなく遠近感のある動きに変換し、各コードの拡大率・不透明度・横方向のずれはすべて同じ「中心からの距離」の値から計算されているので、5つの独立したパーツではなく行全体がひとつの塊としてまとまって動きます。

複数コードがインデックス値に沿って切り替わるQRカルーセル
新しいタブで開く

09 · 複数コードがインデックス値に沿って切り替わるQRカルーセル — 計測 累積面積 18.378% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

MULTI_CODE_CAROUSEL_STEP_MSeaseInOutgrids
    var raw = elapsed / MULTI_CODE_CAROUSEL_STEP_MS;
    var index = Math.floor(raw) % COUNT;
    var localT = raw - Math.floor(raw);
    var eased = easeInOut(localT);
    var pos = index + eased;

    for (var i = 0; i < COUNT; i += 1) {
      // 計算のひと工夫: 現在位置からの距離が、遠近感のスケール・不透明度・横方向のずれをまとめて動かします。
      var diff = i - pos;
      while (diff > COUNT / 2) diff -= COUNT;
      while (diff < -COUNT / 2) diff += COUNT;
      var dist = Math.abs(diff);
      if (dist > 1.8) continue;
      var scale = Math.max(0.35, 1 - dist * 0.42);
      var alpha = Math.max(0, 1 - dist * 0.55);
      var cx = cw / 2 + diff * stepX;

ループの中で時間に関わる値はMULTI_CODE_CAROUSEL_STEP_MSだけなので、これを短くすれば5つのコードは遠近感の計算を変えないまま速く切り替わります。

測定: 累積面積はフレーム全体の18.4%、平均強度118.8、23/23 フレームで動きました。

残り時間の値がフレームごとに画面をどれだけ動かしたか

レンダリングした画面を24枚撮って直前の1枚と比べた実測値です。動いたフレームは、その24枚をつなぐ23回の比較のうち実際に画面が変わった回数を数えています。

項目 累積面積% 強度平均 動いたフレーム
01 モジュールリビール 17.9% 83.8 9/23
02 コーナーフレーム 28.2% 62.6 23/23
03 パルスリング期限 40.2% 46.9 23/23
04 期限カウントダウンリング 61.7% 81.0 23/23
05 スキャン成功チェック 6.9% 119.7 14/23
06 生成ノイズ収束 11.0% 44.7 23/23
07 金額ロールスワップ 11.5% 74.0 20/23
08 期限切れ揺れ再試行 32.1% 65.1 23/23
09 マルチコードカルーセル 18.4% 118.8 23/23

04が61.7%ともっとも広く動いたのは、背景・リング・外側の発光が同じurgencyの値でまとめて変わるためで、05が6.9%ともっとも狭いのはチェックバッジひとつだけが短く跳ねる動きだからです — 項目の性格が違えば面積が狭いほうが自然なので、無理に面積を広げてはいません。

この9つがreduced-motionや型落ち端末で壊れる落とし穴

9つすべてが最初のフレームより前にprefers-reduced-motionを確認していて、設定が入っていればアニメーションさせずにそのパターンの最終値へ一気に飛ばします。より少ない動きを求めた人は、波も、カウントダウンも、揺れも見ることはなく、完成した状態だけを目にします。コピーする前に知っておくべき唯一の落とし穴は、項目4のQR_EXPIRE_DURATION_MSは本当に30000msで、本番のカウントダウンで使う定数そのものだということです。この画面で数秒でループが終わって見えるのは、デモ専用のDEMO_ACCEL_FACTORが経過時間の進み方を速めているためで、実際に取り除くのはこの倍率のほうであり、定数自体ではありません。9つのどれも実際の時計や実際の支払い金額、実際のURLは一切読み取っていません。項目7のパネルの数字も、このページのすべてのQRグリッドも仮の値で、zip の中の本物のファイルを取り出すには、このページの少し下にある wkt849wy が必要です。

値がどこで着地の順番になり、どこでカウントダウンになるか

9つのうち01・02・05・06・07・09の6つ——スキャンと生成にまつわる計算——は作業が終わるにつれて1へ近づく値を読み取っていて、これはひとつのローダーだけを取り出して ローディング バー css として使う場合にも欲しい形です。ひとつの進捗の数値を差し込めば、あとはその値が全部の見た目を引き受けてくれます。残りの03・04・08は同じ形を逆向きにして、1から始まって尽きていくカウントダウンにしています。リングも角度も色も見た目の語彙は同じですが、読み方はローディングバーというよりも期限切れのタイマーに近くなります。09番だけはどちらにも属さず、位置の値は上がりも下がりもせず、5つの固定位置の間をただ移動しているだけなので、カルーセルは「完成する」動きではなく「切り替わる」動きとして見えます。

まず触ってみる価値がある3つの定数

定数 変更 何が変わるか
QR_MODULE_REVEAL_STAGGER_MS 18 → 36 項目1の出現の波が大きく広がり、グリッドがほぼ一気に満ちる感じから、モジュールが1つずつはっきり現れる感じへ変わります
QR_EXPIRE_DURATION_MS 30000 → 15000 項目4のカウントダウンリングが2倍の速さで削れていき、のんびりした印象から急いた印象へ変わります
QR_NOISE_SETTLE_AMPLITUDE_PX 6 → 2 項目6の生成時のゆらぎが控えめになり、最初のフレームから落ち着いて見えるようになります

残り時間のQRローディングが本当に活きる画面

まもなく失効する支払いや入館用のQRコードは、値が縮んでいくことが装飾ではなく本当に必要な数少ない画面のひとつです。項目3・4・8をリング・角度・揺れとして一緒に使えば、見逃す前にユーザーへ同じカウントダウンを3通りの手がかりで伝えられます。コードが要求された直後、まだエンコードが終わっていない生成中の画面には、項目1・2・6が向いています。満ちていく・スキャンする・落ち着くという動きは、何も表示しない空のスピナーよりも「まだです」を伝える手段になります。2つ以上のコードを抱えたチケットやクーポンの財布のような画面には、項目9の位置の値で切り替わるカルーセルが合っています。5つの固定コードを切り替えることは、1つのコードを数え尽くすこととはまったく別の問題だからです。

アクセシビリティ: prefers-reduced-motionが実際に取り除いているもの

同じメディアクエリの確認は9つすべてのindex.htmlの先頭にあり、それぞれが同じように応答します。playingをfalseにしてrequestAnimationFrameのループを開始させず、is-demoクラスを外してCSSだけの装飾的な動きも止め、途中のフレームを飛ばしてそのパターンの最終値を1フレームだけ描画します。

項目 reduced-motionで取り除かれるもの
01 順に現れる波 — グリッドはすべてのモジュールが埋まった状態で描画されます
04 カウントダウンの削れ — リングはもっとも緊迫した色で完全に削れた状態で描画されます
08 期限切れの揺れ — カードはすでに揺れ終わった状態で、再試行のアイコンが見えています
09 遠近感のスライド — カルーセルは最初のコードが中央に止まった状態で描画されます

ほかにも html css ローディング アニメーション の実例を探すなら

ローディング アニメーション js 9パターン — 物理演算で作るは、値がQR風のグリッドではなく重力・バネ・衝突といった実際の物理を動かすローダーを扱っていて、この9つがバネと減衰の計算を借りている土台にあたります。css 3d 回転ローダー9種 — 値で面切替は「値ひとつが9通りのパターンを動かす」という同じ考え方を平面のキャンバスから3D空間へ広げたもので、カウントダウンよりも奥行きが欲しいときに向いています。AI処理中 アイコン 9パターン — 値で動くローディングは精神的にもっとも近い兄弟編です——決まった長さのない作業を表す不確定な進捗の値を扱っていて、今回のセットの03・04・08はそれとは逆に、あらかじめ長さが決まっていて、それがただ尽きていくだけの値を扱っています。9つのtick関数すべてが土台にしている1フレームごとのタイミングについては、MDNのrequestAnimationFrameのリファレンスに、そのコールバックループの仕組みがまとまっています。

残り時間のQRローディングを組み込む前によくある質問

このQRのグリッドは本物の読み取れるコードですか?

いいえ。このページのすべてのグリッドはqrRandかseedRandから作った、シードを固定した疑似ランダムなドットの模様です。QRコードのモジュール配置に見えるように作られているだけで、何もエンコードしておらず、どのカメラでも読み取ることはできません。項目1のコードのコメントに、その断り書きをそのまま残しているのはそのためです。

項目4の30秒のカウントダウンは、このページでも本当に30秒かかりますか?

このページ上ではかかりません。QR_EXPIRE_DURATION_MSは本当に30000msですが、デモ専用のDEMO_ACCEL_FACTORが経過時間の進み方を速めていて、この画面では数秒でループが終わります。この倍率は本番の実装に持っていく前に必ず取り除く部分で、定数そのものはそのまま使えます。

css ローディング スピナーの代わりに、この9つを定数だけ差し替えて使えますか?

はい。QR_MODULE_REVEAL_STAGGER_MSやQR_EXPIRE_DURATION_MS、QR_NOISE_SETTLE_AMPLITUDE_PXをはじめ、ここで挙げたすべての定数はそれぞれのindex.htmlの先頭にまとまっていて、ほかに触る場所はありません。パターンごとにその1つの数値を入れ替えるだけで、下にある関数を書き直す必要はありません。

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

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