Canvas Trail Hover
ホバーでマウスの軌跡がキャンバス上に光の線として残るエフェクト。
HTML
<div class="cth-wrap" id="cth-wrap"> <canvas id="cth-canvas" width="280" height="160"></canvas> <div class="cth-content"><h3>Trail Effect</h3></div> </div>
CSS
.cth-wrap {
position: relative;
width: 280px;
height: 160px;
border-radius: 16px;
overflow: hidden;
background: #0a0a0a;
cursor: pointer;
}
#cth-canvas {
position: absolute;
inset: 0;
}
.cth-content {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #a5b4fc;
}
.cth-content h3 { margin: 0; font-size: 18px; }
JavaScript
const wrap = document.getElementById('cth-wrap');
const canvas = document.getElementById('cth-canvas');
const ctx = canvas.getContext('2d');
let points = [];
wrap.addEventListener('mousemove', function(e) {
const rect = wrap.getBoundingClientRect();
points.push({ x: e.clientX - rect.left, y: e.clientY - rect.top, alpha: 1 });
if (points.length > 50) points.shift();
});
function draw() {
ctx.clearRect(0, 0, 280, 160);
for (let i = 1; i < points.length; i++) {
ctx.beginPath();
ctx.moveTo(points[i-1].x, points[i-1].y);
ctx.lineTo(points[i].x, points[i].y);
ctx.strokeStyle = 'rgba(99,102,241,' + points[i].alpha + ')';
ctx.lineWidth = 2;
ctx.stroke();
points[i].alpha -= 0.015;
}
points = points.filter(function(p) { return p.alpha > 0; });
requestAnimationFrame(draw);
}
draw();