No.163
SCROLL CSSJS

Scroll Velocity Text

横に流れ続ける文字の帯が、ページをスクロールした速さに応じて加速し、スクロールの向きで流れる向きも変わる演出。requestAnimationFrame で速度をなめらかに追従させています。

DEMO

SCROLL VELOCITY · MOTION LAB

ページをスクロールすると流れが速くなります

CODE

HTML
<div class="demo-stage svt-stage">
  <p class="svt-sr">SCROLL VELOCITY · MOTION LAB</p>
  <div class="svt-rows" aria-hidden="true">
    <div class="svt-row"><div class="svt-track" data-dir="1"></div></div>
    <div class="svt-row"><div class="svt-track svt-alt" data-dir="-1"></div></div>
  </div>
  <p class="svt-hint">ページをスクロールすると流れが速くなります</p>
</div>
CSS
.svt-stage { display:flex; flex-direction:column; justify-content:center; gap:.6rem; padding:2rem 0; background:#0B0B10; min-height:280px; overflow:hidden; }
.svt-sr { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
.svt-rows { display:flex; flex-direction:column; gap:.3rem; }
.svt-row { overflow:hidden; white-space:nowrap; }
.svt-track { display:inline-flex; will-change:transform; }
.svt-track span { padding-right:1.5rem; font-family:'Oswald',sans-serif; font-size:2.6rem; font-weight:600; letter-spacing:.04em; color:#fff; }
.svt-alt span { color:transparent; -webkit-text-stroke:1px rgba(255,255,255,.55); }
.svt-hint { margin:0; text-align:center; color:#6E6E7A; font-size:.75rem; }
JS
(function(){
  var tracks = Array.prototype.slice.call(document.querySelectorAll('.svt-track'));
  if (!tracks.length) return;
  var TEXT = 'SCROLL VELOCITY · MOTION LAB · ';
  var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  var rows = tracks.map(function(t){
    for (var i = 0; i < 4; i++) { var s = document.createElement('span'); s.textContent = TEXT; t.appendChild(s); }
    return { el: t, dir: Number(t.dataset.dir), x: 0, unit: t.firstElementChild.offsetWidth };
  });
  if (reduce) return;
  var BASE = 40, lastY = window.scrollY, lastT = performance.now(), vel = 0, sign = 1;
  function frame(now){
    var dt = Math.min((now - lastT) / 1000, 0.05); lastT = now;
    var y = window.scrollY, raw = (y - lastY) / Math.max(dt, 0.001); lastY = y;
    vel += (raw - vel) * 0.1;
    if (Math.abs(vel) > 5) sign = vel > 0 ? 1 : -1;
    var factor = 1 + Math.min(Math.abs(vel) / 300, 5);
    rows.forEach(function(r){
      r.x -= BASE * factor * sign * r.dir * dt;
      if (r.x <= -r.unit) r.x += r.unit;
      if (r.x > 0) r.x -= r.unit;
      r.el.style.transform = 'translate3d(' + r.x + 'px,0,0)';
    });
    requestAnimationFrame(frame);
  }
  requestAnimationFrame(frame);
})();

AI PROMPT

Claude Code Cursor v0
PROMPT
横に流れ続ける文字の帯が、ページをスクロールした速さに応じて加速する Scroll Velocity Text を作って。帯は2段で、1段目は左へ、2段目は右へ流し、2段目は -webkit-text-stroke の袋文字にする。各段は overflow:hidden の中に inline-flex のトラックを置き、同じ文字列の span を4つ並べる。requestAnimationFrame の毎フレームで、window.scrollY の差分を経過時間で割ってスクロール速度を求め、vel += (raw - vel) × 0.1 でなめらかに追従させる(急に跳ねないように)。移動量は「基本速度40px/秒 × (1 + min(|速度| / 300, 5)) × 向き × 段の向き × 経過秒」で、スクロールを下へ動かせば通常の向き、上へ動かせば逆向きに流れる。位置が span 1つ分の幅を超えたら1つ分戻して、継ぎ目なく無限に流れるようにする。経過時間は0.05秒で頭打ちにして、タブ復帰時に一気に飛ばないようにする。transform は translate3d で動かす。読み上げ用に文を視覚的に隠した要素で持たせ、流れる帯は aria-hidden="true" にする。prefers-reduced-motion: reduce の時は流さずに静止表示する。

Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift

AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する

BOOKS · PR · AMAZON

📖 なかしまぁ先生のCSSアニメーション入門 📖 UIデザインの教科書 新版 マルチデバイス時代のインターフェース設計 📖 Fundamentals of Web Animation with GSAP

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

学びを止めない · AMAZONサブスク

📚 Kindle Unlimited — 技術書・デザイン書が読み放題。30日無料体験 → 🎧 Audible — 移動中に耳で学ぶオーディオブック。30日無料体験 → 📦 Amazon Prime — Prime Reading・配送特典つき。30日無料体験 → 🎵 Music Unlimited — 作業用BGMに。1億曲が聴き放題・30日無料体験 →

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

RELATED EFFECTS

↗ MORE
→ MARQUEE TEXT → INFINITE MOVING CARDS → SCROLL-DRIVEN PROGRESS

Scroll Velocity Text(スクロール速度で加速する文字帯)とは

横に流れ続ける文字の帯が、ページをスクロールする速さに反応して加速し、スクロールの向きで流れの向きも変わる演出です。Magic UI にも同じ系統のコンポーネント(Scroll Based Velocity)があり、ポートフォリオやブランドサイトで、スクロールという操作に手応えを持たせる目的で使われます。

当サイトの Marquee Text は一定の速さで流れ続ける文字帯、Infinite Moving Cards はカードが流れ続ける演出、Scroll-driven Progress はスクロール位置に合わせて進捗を描く演出です。本ページはスクロールの「位置」ではなく「速さ」に反応する別テーマです。

スクロールのたびに激しく動く演出は、酔いやすい人には負担になります。動きを減らす設定の利用者には必ず止め、ページの中で使うのは1か所にとどめてください。

よくある質問

スクロール速度をそのまま使うと何が起きますか?

スクロール量はフレームごとに大きくばらつくため、そのまま速度に使うと帯がガクガクと加速・減速を繰り返します。本実装は vel += (raw - vel) × 0.1 という式で前の値に10%ずつ近づけ、急な変化をならしています。係数を大きくすると反応が速く、小さくすると滑らかになります。

継ぎ目なく流れ続けるのはなぜですか?

同じ文字列を複数並べておき、位置がちょうど1つ分ずれた時点で1つ分だけ位置を戻しています。戻した瞬間の見た目は戻す前とまったく同じなので、利用者には途切れずに流れ続けているように見えます。帯の幅より文字列が短い場合は、並べる数を増やしてください。

コードは無料で使えますか?

はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。