Trail
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 - 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;
Developer | Hakim El Hattab |
Username | hakimel |
Uploaded | September 24, 2022 |
Rating | 4.5 |
Size | 2,883 Kb |
Views | 24,288 |
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!
Name | Size |
Hole | 3,204 Kb |
Checkwave | 2,735 Kb |
CSS Wiggle | 3,233 Kb |
Monocle List | 4,124 Kb |
Hypnos | 2,937 Kb |
Flipside | 4,297 Kb |
Blob | 6,452 Kb |
Spiral | 2,958 Kb |
Bakemono | 5,997 Kb |
Animated Line Chart | 3,305 Kb |
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!
Name | Username | Size |
Polygon Logo in CSS | Kai | 3,412 Kb |
Week7 replicate | Hwcasis | 1,620 Kb |
3D-box | Parthviroja | 2,346 Kb |
Lazy Load for Background Images | The_ruther4d | 2,977 Kb |
Animated Slide Hamburger Mobile Menu | BJack | 2,247 Kb |
SnappySnippet Test | Elmsoftware | 8,385 Kb |
Angular-HAML | Cwacht | 2,022 Kb |
Revolving Text Landing Page Trial | TimRuby | 2,976 Kb |
RSW | JordanC | 3,726 Kb |
Google Fonts Sass Mixin | HugoGiraudel | 4,237 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!