Trail

Size
2,883 Kb
Views
24,288

How do I make an trail?

A set of rotating particles that leave a silky smooth trail as you move your mouse. One of my first canvas experiments :D. What is a trail? How do you make a trail? This script and codes were developed by Hakim El Hattab on 24 September 2022, Saturday.

Trail Previews

Trail - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Trail</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <canvas id='world'></canvas> <script src="js/index.js"></script>
</body>
</html>

Trail - Script Codes CSS Codes

body { background-color: #000000; padding: 0; margin: 0; overflow: hidden;
}

Trail - Script Codes JS Codes

// One of my first <canvas> experiments, woop! :D
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var RADIUS = 70;
var RADIUS_SCALE = 1;
var RADIUS_SCALE_MIN = 1;
var RADIUS_SCALE_MAX = 1.5;
var QUANTITY = 25;
var canvas;
var context;
var particles;
var mouseX = SCREEN_WIDTH * 0.5;
var mouseY = SCREEN_HEIGHT * 0.5;
var mouseIsDown = false;
function init() { canvas = document.getElementById( 'world' ); if (canvas && canvas.getContext) {	context = canvas.getContext('2d');	// Register event listeners	window.addEventListener('mousemove', documentMouseMoveHandler, false);	window.addEventListener('mousedown', documentMouseDownHandler, false);	window.addEventListener('mouseup', documentMouseUpHandler, false);	document.addEventListener('touchstart', documentTouchStartHandler, false);	document.addEventListener('touchmove', documentTouchMoveHandler, false);	window.addEventListener('resize', windowResizeHandler, false);	createParticles();	windowResizeHandler();	setInterval( loop, 1000 / 60 );	}
}
function createParticles() {	particles = [];	for (var i = 0; i < QUANTITY; i++) {	var particle = {	size: 1,	position: { x: mouseX, y: mouseY },	offset: { x: 0, y: 0 },	shift: { x: mouseX, y: mouseY },	speed: 0.01+Math.random()*0.04,	targetSize: 1,	fillColor: '#' + (Math.random() * 0x404040 + 0xaaaaaa | 0).toString(16),	orbit: RADIUS*.5 + (RADIUS * .5 * Math.random())	};	particles.push( particle );	}
}
function documentMouseMoveHandler(event) {	mouseX = event.clientX - (window.innerWidth - SCREEN_WIDTH) * .5;	mouseY = event.clientY - (window.innerHeight - SCREEN_HEIGHT) * .5;
}
function documentMouseDownHandler(event) {	mouseIsDown = true;
}
function documentMouseUpHandler(event) {	mouseIsDown = false;
}
function documentTouchStartHandler(event) {	if(event.touches.length == 1) {	event.preventDefault();	mouseX = event.touches[0].pageX - (window.innerWidth - SCREEN_WIDTH) * .5;;	mouseY = event.touches[0].pageY - (window.innerHeight - SCREEN_HEIGHT) * .5;	}
}
function documentTouchMoveHandler(event) {	if(event.touches.length == 1) {	event.preventDefault();	mouseX = event.touches[0].pageX - (window.innerWidth - SCREEN_WIDTH) * .5;;	mouseY = event.touches[0].pageY - (window.innerHeight - SCREEN_HEIGHT) * .5;	}
}
function windowResizeHandler() {	SCREEN_WIDTH = window.innerWidth;	SCREEN_HEIGHT = window.innerHeight;	canvas.width = SCREEN_WIDTH;	canvas.height = SCREEN_HEIGHT;
}
function loop() {	if( mouseIsDown ) {	RADIUS_SCALE += ( RADIUS_SCALE_MAX - RADIUS_SCALE ) * (0.02);	}	else {	RADIUS_SCALE -= ( RADIUS_SCALE - RADIUS_SCALE_MIN ) * (0.02);	}	RADIUS_SCALE = Math.min( RADIUS_SCALE, RADIUS_SCALE_MAX );	context.fillStyle = 'rgba(0,0,0,0.05)'; context.fillRect(0, 0, context.canvas.width, context.canvas.height);	for (i = 0, len = particles.length; i < len; i++) {	var particle = particles[i];	var lp = { x: particle.position.x, y: particle.position.y };	// Rotation	particle.offset.x += particle.speed;	particle.offset.y += particle.speed;	// Follow mouse with some lag	particle.shift.x += ( mouseX - particle.shift.x) * (particle.speed);	particle.shift.y += ( mouseY - particle.shift.y) * (particle.speed);	// Apply position	particle.position.x = particle.shift.x + Math.cos(i + particle.offset.x) * (particle.orbit*RADIUS_SCALE);	particle.position.y = particle.shift.y + Math.sin(i + particle.offset.y) * (particle.orbit*RADIUS_SCALE);	// Limit to screen bounds	particle.position.x = Math.max( Math.min( particle.position.x, SCREEN_WIDTH ), 0 );	particle.position.y = Math.max( Math.min( particle.position.y, SCREEN_HEIGHT ), 0 );	particle.size += ( particle.targetSize - particle.size ) * 0.05;	if( Math.round( particle.size ) == Math.round( particle.targetSize ) ) {	particle.targetSize = 1 + Math.random() * 7;	}	context.beginPath();	context.fillStyle = particle.fillColor;	context.strokeStyle = particle.fillColor;	context.lineWidth = particle.size;	context.moveTo(lp.x, lp.y);	context.lineTo(particle.position.x, particle.position.y);	context.stroke();	context.arc(particle.position.x, particle.position.y, particle.size/2, 0, Math.PI*2, true);	context.fill();	}
}
window.onload = init;
Trail - Script Codes
Trail - Script Codes
Home Page Home
Developer Hakim El Hattab
Username hakimel
Uploaded September 24, 2022
Rating 4.5
Size 2,883 Kb
Views 24,288
Do you need developer help for Trail?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Hakim El Hattab (hakimel) Script Codes
Name
Hole
Checkwave
CSS Wiggle
Monocle List
Hypnos
Flipside
Blob
Spiral
Bakemono
Animated Line Chart
Create amazing captions with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!