01
スクロールリビール
IntersectionObserver画面に入った瞬間に要素をフェードアップ。一度だけ発火する、最も使われるスクロール演出。
↓ ページをスクロールすると各カードが順次フェード:
🎨デザイン
⚡パフォーマンス
🔧ツーリング
🎯ターゲット
📐レイアウト
🎮UX
🌈カラー
🔮魔法
// 画面に入ったら .show を付けるだけ const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('show'); io.unobserve(e.target); // 一度だけ } }); }, { threshold: 0.15 }); document.querySelectorAll('.js-reveal').forEach(el => io.observe(el));
02
マウスパララックス
mousemove + layered transform複数のレイヤーが異なる速度で動く、奥行きの錯覚。
// 各レイヤーに data-depth を持たせ、マウス位置で平行移動 stage.addEventListener('mousemove', e => { const r = stage.getBoundingClientRect(); const mx = (e.clientX - r.left) / r.width - 0.5; const my = (e.clientY - r.top) / r.height - 0.5; stage.querySelectorAll('[data-depth]').forEach(el => { const d = parseFloat(el.dataset.depth); el.style.transform = `translate(${mx * d * 6}px, ${my * d * 6}px)`; }); });
03
カーソルトレイル
requestAnimationFrameマウスを追いかける光の粒。RAFループで滑らかに、過去N点を残光させる。
マウスやタッチを動かしてみて
// 50個のドットを並べ、それぞれ前のドットに追従させる const dots = Array.from({length: 30}, () => ...); const tick = () => { let x = mouseX, y = mouseY; dots.forEach((d, i) => { d.x += (x - d.x) * 0.3; d.y += (y - d.y) * 0.3; d.el.style.transform = `translate(${d.x}px,${d.y}px) scale(${1 - i/30})`; x = d.x; y = d.y; }); requestAnimationFrame(tick); };
04
マグネティックボタン
pointermoveマウスが近づくとボタンが引き寄せられる。さりげない物理感がUIに「気配」を与える。
// ボタンの中心と相対座標の30%だけ動かす btn.addEventListener('mousemove', e => { const r = btn.getBoundingClientRect(); const x = e.clientX - r.left - r.width / 2; const y = e.clientY - r.top - r.height / 2; btn.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`; }); btn.addEventListener('mouseleave', () => btn.style.transform = '');
05
テキストスクランブル
setInterval / random charsランダムな文字がじわじわ正解に収束していく、エージェント映画の暗号復号風。
Hello, World
// 進行状況に応じて、未確定文字をランダム置換 const chars = '!<>-_\\/[]{}—=+*^?#________'; function scramble(target) { const queue = buildQueue(current, target); let frame = 0; const tick = () => { const out = queue.map(({from, to, start, end}, i) => { if (frame >= end) return to; if (frame < start) return from; return chars[Math.floor(Math.random() * chars.length)]; }); el.textContent = out.join(''); frame++; if (frame <= maxFrame) requestAnimationFrame(tick); }; tick(); }
06
数値カウントアップ
requestAnimationFrame + easing「0 → 目標値」へとイージングしながら駆け上がる数字。実績ページの定番。
ユーザー
0
プロジェクト
0
公開ファイル
0
成功率
0%
// ease-out で滑らかに到達 function count(el, to, duration = 1800) { const start = performance.now(); const step = (now) => { const t = Math.min((now - start) / duration, 1); const eased = 1 - Math.pow(1 - t, 3); // easeOutCubic el.textContent = (eased * to).toFixed(decimals); if (t < 1) requestAnimationFrame(step); }; requestAnimationFrame(step); }
07
マルチライン・タイピング
setTimeout chain複数行を順番に打ち、カラー区別や遅延を効かせるターミナル風タイピング。
// 1行ずつ、文字を1個ずつ追加。HTMLも解釈可 async function typeLine(html, speed = 30) { for (let i = 0; i <= html.length; i++) { el.innerHTML = collected + html.slice(0, i) + '<span class="caret"></span>'; await sleep(speed); } collected += html + '\n'; }
08
パーティクル・ネットワーク
Canvas 2D点と点を距離に応じて線で結ぶ古典的Canvas表現。マウスにも反応します。
120 nodes · live connections
// 各ノードを更新 → 近接同士を線で結ぶ function tick() { ctx.clearRect(0, 0, w, h); nodes.forEach(n => { n.x += n.vx; n.y += n.vy; if (n.x < 0 || n.x > w) n.vx *= -1; if (n.y < 0 || n.y > h) n.vy *= -1; }); for (let i = 0; i < nodes.length; i++) { for (let j = i + 1; j < nodes.length; j++) { const d = dist(nodes[i], nodes[j]); if (d < 100) { ctx.strokeStyle = `rgba(124,92,255,${1 - d/100})`; ctx.beginPath(); ctx.moveTo(nodes[i].x, nodes[i].y); ctx.lineTo(nodes[j].x, nodes[j].y); ctx.stroke(); } } } requestAnimationFrame(tick); }
09
スプリングドラッグ
pointer + spring physics引っ張って離すと、バネのように元へ戻る。バネの剛性と減衰をコードで指定。
⇕
// バネ方程式: x'' = -k(x - x₀) - c·x' const k = 0.15; // 剛性 const damp = 0.8; // 減衰 function tick() { if (!dragging) { vx += (originX - x) * k; vx *= damp; x += vx; vy += (originY - y) * k; vy *= damp; y += vy; box.style.transform = `translate(${x}px,${y}px) scale(${1 + Math.abs(vx + vy) * 0.01})`; } requestAnimationFrame(tick); }
10
3Dティルトカード
perspective + rotateX/Yマウス位置から回転角度を計算し、立体的に傾く。光沢のスイープも追従。
PREMIUM
CSS × JS
// マウスの相対位置から ±15° 回転 card.addEventListener('mousemove', e => { const r = card.getBoundingClientRect(); const mx = (e.clientX - r.left) / r.width; const my = (e.clientY - r.top) / r.height; const ry = (mx - 0.5) * 30; const rx = (my - 0.5) * -30; card.style.transform = `rotateX(${rx}deg) rotateY(${ry}deg)`; card.style.setProperty('--glare', `${mx * 200 - 100}%`); });
11
音波ビジュアライザ
RAF + sine wavesWeb Audio APIなしで、複数のサイン波を重ねた「それっぽい」リアルタイム視覚化。
// 各バーに対し、複数の正弦波を合成 function tick(t) { bars.forEach((bar, i) => { const v = Math.sin(t / 300 + i * 0.2) * 0.5 + Math.sin(t / 120 + i * 0.5) * 0.3 + Math.sin(t / 80 + i) * 0.2; const h = (v + 1) / 2 * 140 + 20; bar.style.height = h + 'px'; }); requestAnimationFrame(tick); }
12
SVGパスドロー
stroke-dasharrayパスの長さを getTotalLength() で取り、ダッシュ配列でアニメ。手描き風の線。
// 線の長さを取って、初期は全部ダッシュで隠す → 0にトリガ const len = path.getTotalLength(); path.style.strokeDasharray = len; path.style.strokeDashoffset = len; path.getBoundingClientRect(); // reflow path.style.transition = 'stroke-dashoffset 2s ease-out'; path.style.strokeDashoffset = 0;
13
コンフェッティ砲
Canvas + 2D physics重力・空気抵抗・初速・回転、すべてをコードで指定したリアル目の紙吹雪。
// 各粒子は位置・速度・回転を持ち、毎フレーム重力で落下 const P = { x, y, vx, vy, rot, vrot, color, size, life }; P.vy += 0.25; // gravity P.vx *= 0.99; // drag P.x += P.vx; P.y += P.vy; P.rot += P.vrot; ctx.save(); ctx.translate(P.x, P.y); ctx.rotate(P.rot); ctx.fillStyle = P.color; ctx.fillRect(-P.size/2, -P.size/2, P.size, P.size * 2); ctx.restore();
14
Web Animations API
element.animate()スクラブで時間軸を巻き戻したり、playbackRateで早回し。CSSキーフレームより柔軟。
// element.animate() は Animation オブジェクトを返す const anim = box.animate([ { transform: 'translateX(-150px) rotate(0deg)', borderRadius: '50%' }, { transform: 'translateX(0) rotate(180deg)', borderRadius: '8px' }, { transform: 'translateX(150px) rotate(360deg)', borderRadius: '50%' } ], { duration: 2500, iterations: Infinity, direction: 'alternate' }); anim.pause(); anim.play(); anim.playbackRate = 0.3; anim.currentTime = 1200; // 任意の時点へジャンプ
15
スタッガーリスト
classList + animation-delayリスト項目を順番に、わずかな遅延つきで登場。チーム表、メニュー、結果一覧に。
1はじめにJSを読み込みます
2各要素にdelayを動的に割り当て
3.goクラスを付与してアニメ開始
4CSSの@keyframesが順番に発火
5視線が自然に下へ移動する
6これで連続演出の完成
// 各要素のdelayをインデックスから計算 items.forEach((el, i) => { el.style.animationDelay = `${i * 80}ms`; el.classList.remove('go'); void el.offsetWidth; // reflow to restart el.classList.add('go'); });