Resources
Made by me
Feel free to use those in any way you want. Credit is not mandatory, but appreciated!
- Customizable, character-based cursor trail
/* Usage : add a <script></script> tag in your page after the body, and either put this code in the tag
* or put it in a .js file and link it like <script src="/your/script/path.js"></script>
*/
/* Parameters to customize to your liking */
// The amount of time each particle stays on the screen
const maxLife = 120;
// The starting size of the particle
const maxSize = 1.3;
// The minimum amount of pixel difference before spawning a new particle
const minInterval = 20;
// Horizontal offset where the particles start, relative to the cursor point
const xOffset = 10;
// Vertical offset where the particles start, relative to the cursor point
const yOffset = 32;
// The moment when the particle starts fading out. The fade out is a simple size reduction until it reaches 0
const fadeOutStart = 80;
// The amount of size reduced at each reduction step
const fadeOutSpeed = 0.04;
// The list of all colors the particles can be (random)
const possibleColors = ["#6367FF","#8494FF","#C9BEFF","#FFDBFD"];
// The list of all characters the particles can be (random)
const possibleCharacters = "*☆✯✻✧";
/* Functions */
var particles = [];
var width = window.innerWidth;
var height = window.innerHeight;
var canvas, context
var lastPos = { x: width / 2, y: width / 2 };
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
);
function onWindowResize(e) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function OnMouseMove(e) {
finalX = e.clientX + xOffset;
finalY = e.clientY + yOffset;
const interval = Math.hypot(
finalX - lastPos.x,
finalY - lastPos.y
);
if (interval > minInterval)
{
SpawnParticle(finalX, finalY);
lastPos.x = finalX;
lastPos.y = finalY;
}
}
function SpawnParticle(x, y) {
var color = possibleColors[Math.floor(Math.random() * possibleColors.length)];
particles.push({
x: x,
y: y,
size: maxSize,
lifetime: 0,
color: color,
direction: 0.5 - Math.random() * 0.7,
character: possibleCharacters[Math.floor(Math.random() * possibleCharacters.length)]
});
}
function UpdateParticles() {
if (particles.length == 0) {
return;
}
context.clearRect(0, 0, width, height);
particles = particles.filter((particle) => particle.lifetime < maxLife);
particles.forEach((particle) => {
particle.lifetime++;
particle.y++;
particle.x += particle.direction;
if(particle.lifetime >= fadeOutStart && particle.size - fadeOutSpeed >= 0.0)
{
particle.size -= fadeOutSpeed;
}
context.fillStyle = particle.color;
context.font = `${particle.size}em sans-serif`;
context.fillText(particle.character, particle.x, particle.y);
});
}
function loop() {
UpdateParticles();
animationFrame = requestAnimationFrame(loop);
}
function init() {
canvas = document.createElement("canvas");
context = canvas.getContext("2d");
canvas.style.position = "fixed";
canvas.style.top = "0px";
canvas.style.left = "0px";
canvas.width = width;
canvas.height = height;
canvas.style.pointerEvents = "none";
canvas.style.zIndex = "10";
document.body.appendChild(canvas);
window.addEventListener("mousemove", OnMouseMove);
window.addEventListener("resize", onWindowResize);
loop();
}
init();
Made by others
- Border image generator - Generate a CSS border from an image
- Cursormania rips - All the Cursormania cursors, free to download (includes the ones used here!)