DEMO
枠の中のどこを押しても、押した場所から火花が散ります
CODE
<div class="demo-stage csp-stage" id="csp-stage"> <p class="csp-hint">枠の中のどこを押しても、押した場所から火花が散ります</p> <button type="button" class="csp-btn" id="csp-btn">押してみる <span id="csp-count">0</span></button> <div class="csp-layer" id="csp-layer" aria-hidden="true"></div> </div>
.csp-stage { position:relative; overflow:hidden; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1rem; padding:2rem; background:#0B0B10; min-height:300px; cursor:crosshair; }
.csp-hint { margin:0; color:#A1A1AA; font-size:.82rem; text-align:center; }
.csp-btn { min-height:44px; padding:0 1.3rem; border:0; border-radius:999px; background:#D1177A; color:#fff; font-weight:600; font-size:.9rem; cursor:pointer; font-variant-numeric:tabular-nums; }
.csp-btn:focus-visible { outline:2px solid #fff; outline-offset:3px; }
.csp-layer { position:absolute; inset:0; pointer-events:none; }
.csp-spark { position:absolute; top:0; left:0; width:2px; height:10px; margin:-5px 0 0 -1px; border-radius:1px; background:#F9A8D4; }
(function(){
var stage = document.getElementById('csp-stage');
var layer = document.getElementById('csp-layer');
var btn = document.getElementById('csp-btn');
var count = document.getElementById('csp-count');
if (!stage || !layer || !btn || !count) return;
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)');
var N = 8, DIST = 28, DUR = 400;
function burst(x, y){
if (reduce.matches || !layer.animate) return;
for (var i = 0; i < N; i++) {
var a = 360 / N * i;
var s = document.createElement('span');
s.className = 'csp-spark';
s.style.left = x + 'px'; s.style.top = y + 'px';
layer.appendChild(s);
s.animate([
{ transform: 'rotate(' + a + 'deg) translateY(-8px) scaleY(1)', opacity: 1 },
{ transform: 'rotate(' + a + 'deg) translateY(-' + (8 + DIST) + 'px) scaleY(0)', opacity: 0 }
], { duration: DUR, easing: 'ease-out' }).onfinish = s.remove.bind(s);
}
}
stage.addEventListener('click', function(e){
var r = stage.getBoundingClientRect(), x, y;
if (e.detail === 0) {
var b = e.target.getBoundingClientRect();
x = b.left + b.width / 2 - r.left; y = b.top + b.height / 2 - r.top;
} else {
x = e.clientX - r.left; y = e.clientY - r.top;
}
burst(x, y);
});
btn.addEventListener('click', function(){ count.textContent = String(Number(count.textContent) + 1); });
})();
AI PROMPT
枠の中のどこを押しても、押した位置から短い火花が8方向に飛び散る Click Spark を作って。枠に position:relative と overflow:hidden を付け、中に pointer-events:none・aria-hidden="true" の層(position:absolute; inset:0)を置く。枠の click で、枠の getBoundingClientRect からの相対座標を求め、幅2px・高さ10pxの細い線(火花)を8本、その位置に position:absolute で置く(margin で線の中心を押した点に合わせる)。1本ごとに 360 ÷ 8 × i 度の角度を付け、Web Animations API の element.animate で rotate(角度) translateY(-8px) scaleY(1)・不透明 から rotate(角度) translateY(-36px) scaleY(0)・透明 へ400ミリ秒・ease-out で動かし、終わったら onfinish で取り除く(rotate を先に書くと、その角度の向きへ外に飛ぶ)。キーボードの Enter や Space で押した click は event.detail が0になるので、その時は押した要素の中心から散らす。枠の中には押せるボタンも置き、押した回数を表示する(火花は装飾なので、ボタン本来の動作とは切り離す)。prefers-reduced-motion: reduce の時と element.animate が使えない時は火花を出さない。 Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift
AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する
BOOKS · PR · AMAZON
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
学びを止めない · AMAZONサブスク
※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。
CREATOR TOOLS · スクール(PR)
※本サイトはアフィリエイトリンクを含みます。リンク経由のご購入・お申し込みで運営者が紹介料を受け取る場合があります。
画面を押した瞬間に、押した場所から短い線が放射状に飛び散る演出です。React Bits にも ClickSpark というコンポーネントがあり、説明は「クリック位置に粒子の火花を散らす」とされています。React Bits 版は canvas で描いており、既定値は火花8本・400ミリ秒・ease-out です。本ページは同じ本数と時間を、canvas を使わず要素と Web Animations API で作っています。
当サイトの Ripple Effect はボタンを押した地点から波紋が広がる演出、Like Burst はいいねボタンでハートとパーティクルが飛び散る演出、Confetti Burst はボタンを押すと色とりどりの紙吹雪が弾ける演出です。本ページは特定のボタンではなく、領域のどこを押しても反応を返す別テーマです。
押したことが一瞬で分かる小さな手応えなので、ゲームやお絵かきのように画面を何度も押す場面と相性が良い演出です。0.4秒で消える短い動きにとどめ、動きを減らす設定の利用者には出さないようにしてください。
火花が外へ飛ぶ向きはどう決めていますか?
transform の rotate(角度) の後に translateY(マイナスの値) を書くと、要素はまずその角度に回転し、回転した向きの「上」へ移動します。8本それぞれに45度ずつ違う角度を付け、同じ translateY で動かすだけで、放射状に飛び散って見えます。scaleY で線を縮めながら透明にすると、火花が燃え尽きるように消えます。
キーボードで押した時の位置はどうなりますか?
Enter や Space でボタンを押した時の click は、マウスの座標を持たず、event.detail(クリックの回数)が0になります。本実装はこの場合だけ、押された要素の中心を火花の起点にしています。座標をそのまま使うと画面の左上(0, 0)が起点になり、火花が枠の外に出て見えなくなるため、キーボードで操作する人にも同じ見え方になるよう分けて扱っています。
コードは無料で使えますか?
はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。