canvas-cursor-trail
Курсор·Шаблон: Davies - Personal Portfolio HTML Template·Складність анімації: medium·Адаптивний: Так

Файли-джерела
- index.html
canvas#trail.cursor-trail
Бібліотеки
jquery
Summary
A full-viewport <canvas> rendered behind interactive content. On pointermove it pushes a new sample to a trail buffer and draws connecting line segments with a slowly cycling HSL stroke. Each frame fills the canvas with low-alpha black so old segments fade out smoothly. Gated to xl viewports (≥1200px) — mobile gets nothing.
HTML structure (minimal)
<canvas class="cursor-trail d-none d-xl-block" id="trail"></canvas>
Key SCSS tokens
.cursor-trail {
position: fixed;
inset: 0;
z-index: 9999;
pointer-events: none;
width: 100%;
height: 100%;
}
Animation logic
// assets/js/main.js — cursorTrail()
var canvas = document.getElementById('trail');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var points = [];
var hue = 140;
window.addEventListener('pointermove', (e) => {
points.push({ x: e.clientX, y: e.clientY });
if (points.length > 25) points.shift();
});
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.18)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = 'hsl(' + hue + ', 90%, 60%)';
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.beginPath();
for (var i = 1; i < points.length; i++) {
ctx.moveTo(points[i - 1].x, points[i - 1].y);
ctx.lineTo(points[i].x, points[i].y);
}
ctx.stroke();
hue = (hue + 0.5) % 360;
requestAnimationFrame(draw);
}
draw();
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
Notable details
- Trail length is capped at ~25 points — older points are shifted out before drawing, so memory stays flat.
fillRectwith rgba alpha 0.18 each frame creates the fade-out without needing per-pixel manipulation; the lower the alpha the longer the trail persists.- HSL hue cycles slowly (0.5° per frame) so the trail subtly shifts colour the longer the cursor moves — matches the "design-craft" tone of the template.
- Bootstrap utility classes (
d-none d-xl-block) gate the canvas at the markup level — JS doesn't even touch it on mobile.
Use when
- Portfolios / showreel sites where you want a signature cursor effect without coupling it to GSAP or react-spring.
- When the page background is dark — the rgba(0,0,0,0.18) fade only works on dark themes.
Caveats
- The fade-out is hard-coded to black — on light backgrounds the trail won't fade visibly without changing
fillStyleto white rgba. pointermoveevents on touch devices fire too — if you re-enable below xl, expect unwanted trails on tap.- Canvas covers the full viewport with
pointer-events: none; double-check that no descendant CSS bumpspointer-eventsback on by accident.