Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
JS
// Local variables var fireworks = []; var particles = []; var mouse = {down: false, x: 0, y: 0}; var currentHue = 120; var clickLimiterTotal = 10; var clickLimiterTick = 0; var timerTotal = 80; var timerTick = 0; // Helper function for canvas animations window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(cb) { window.setTimeout(callback, 1000 / 60); } })(); // Helper function to return random numbers within a specified range function random(min, max) { return Math.random() * (max - min) + min; } // Helper function to calculate the distance between 2 points function calculateDistance(p1x, p1y, p2x, p2y) { var xDistance = p1x - p2x; var yDistance = p1y - p2y; return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); } // Setup some basic variables var canvas = document.getElementById('canvas'); var canvasCtx = canvas.getContext('2d'); var canvasWidth = window.innerWidth; var canvasHeight = window.innerHeight; // Resize canvas canvas.width = canvasWidth; canvas.height = canvasHeight; // Firework class function Firework(sx, sy, tx, ty) { // Set coordinates (x/y = actual, sx/sy = starting, tx/ty = target) this.x = this.sx = sx; this.y = this.sy = sy; this.tx = tx; this.ty = ty; // Calculate distance between starting and target point this.distanceToTarget = calculateDistance(sx, sy, tx, ty); this.distanceTraveled = 0; // To simulate a trail effect, the last few coordinates will be stored this.coordinates = []; this.coordinateCount = 3; // Populate coordinate array with initial data while(this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } // Some settings, you can adjust them if you'd like to do so. this.angle = Math.atan2(ty - sy, tx - sx); this.speed = 2; this.acceleration = 1.03; this.brightness = random(50, 80); this.targetRadius = 1; this.targetDirection = false; // false = Radius is getting bigger, true = Radius is getting smaller }; // This method should be called each frame to update the firework Firework.prototype.update = function(index) { // Update the coordinates array this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); // Cycle the target radius (used for the pulsing target circle) if(!this.targetDirection) { if(this.targetRadius < 8) this.targetRadius += 0.15; else this.targetDirection = true; } else { if(this.targetRadius > 1) this.targetRadius -= 0.15; else this.targetDirection = false; } // Speed up the firework (could possibly travel faster than the speed of light) this.speed *= this.acceleration; // Calculate the distance the firework has travelled so far (based on velocities) var vx = Math.cos(this.angle) * this.speed; var vy = Math.sin(this.angle) * this.speed; this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy); // If the distance traveled (including velocities) is greater than the initial distance // to the target, then the target has been reached. If that's not the case, keep traveling. if(this.distanceTraveled >= this.distanceToTarget) { createParticles(this.tx, this.ty); fireworks.splice(index, 1); } else { this.x += vx; this.y += vy; } }; // Draws the firework Firework.prototype.draw = function() { var lastCoordinate = this.coordinates[this.coordinates.length - 1]; // Draw the rocket canvasCtx.beginPath(); canvasCtx.moveTo(lastCoordinate[0], lastCoordinate[1]); canvasCtx.lineTo(this.x, this.y); canvasCtx.strokeStyle = 'hsl(' + currentHue + ',100%,' + this.brightness + '%)'; canvasCtx.stroke(); // Draw the target (pulsing circle) canvasCtx.beginPath(); canvasCtx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2); canvasCtx.stroke(); }; // Particle class function Particle(x, y) { // Set the starting point this.x = x; this.y = y; // To simulate a trail effect, the last few coordinates will be stored this.coordinates = []; this.coordinateCount = 5; // Populate coordinate array with initial data while(this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } // Set a random angle in all possible directions (radians) this.angle = random(0, Math.PI * 2); this.speed = random(1, 10); // Add some friction and gravity to the particle this.friction = 0.95; this.gravity = 1; // Change the hue to a random number this.hue = random(currentHue - 20, currentHue + 20); this.brightness = random(50, 80); this.alpha = 1; // Set how fast the particles decay this.decay = random(0.01, 0.03); } // Updates the particle, should be called each frame Particle.prototype.update = function(index) { // Update the coordinates array this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); // Slow it down (based on friction) this.speed *= this.friction; // Apply velocity to the particle this.x += Math.cos(this.angle) * this.speed; this.y += Math.sin(this.angle) * this.speed + this.gravity; // Fade out the particle, and remove it if alpha is low enough this.alpha -= this.decay; if(this.alpha <= this.decay) { particles.splice(index, 1); } } // Draws the particle Particle.prototype.draw = function() { var lastCoordinate = this.coordinates[this.coordinates.length - 1]; canvasCtx.beginPath(); canvasCtx.moveTo(lastCoordinate[0], lastCoordinate[1]); canvasCtx.lineTo(this.x, this.y); canvasCtx.strokeStyle = 'hsla(' + this.hue + ',100%,' + this.brightness + '%,' + this.alpha + ')'; canvasCtx.stroke(); } // Create a bunch of particles at the given position function createParticles(x, y) { var particleCount = 30; while(particleCount--) { particles.push(new Particle(x, y)); } } // Add an event listener to the window so we're able to react to size changes window.addEventListener('resize', function(e) { canvas.width = canvasWidth = window.innerWidth; canvas.height = canvasHeight = window.innerHeight; }); // Add event listeners to the canvas to handle mouse interactions canvas.addEventListener('mousemove', function(e) { e.preventDefault(); mouse.x = e.pageX - canvas.offsetLeft; mouse.y = e.pageY - canvas.offsetTop; }); canvas.addEventListener('mousedown', function(e) { e.preventDefault(); mouse.down = true; }); canvas.addEventListener('mouseup', function(e) { e.preventDefault(); mouse.down = false; }); // Main application / script, called when the window is loaded function gameLoop() { // This function will rund endlessly by using requestAnimationFrame (or fallback to setInterval) requestAnimFrame(gameLoop); // Increase the hue to get different colored fireworks over time currentHue += 0.5; // 'Clear' the canvas at a specific opacity, by using 'destination-out'. This will create a trailing effect. canvasCtx.globalCompositeOperation = 'destination-out'; canvasCtx.fillStyle = 'rgba(0, 0, 0, 0.5)'; canvasCtx.fillRect(0, 0, canvasWidth, canvasHeight); canvasCtx.globalCompositeOperation = 'lighter'; // Loop over all existing fireworks (they should be updated & drawn) var i = fireworks.length; while(i--) { fireworks[i].draw(); fireworks[i].update(i); } // Loop over all existing particles (they should be updated & drawn) var i = particles.length; while(i--) { particles[i].draw(); particles[i].update(i); } // Launch fireworks automatically to random coordinates, if the user does not interact with the scene if(timerTick >= timerTotal) { if(!mouse.down) { fireworks.push(new Firework(canvasWidth / 2, canvasHeight, random(0, canvasWidth), random(0, canvasHeight / 2))); timerTick = 0; } } else { timerTick++; } // Limit the rate at which fireworks can be spawned by mouse if(clickLimiterTick >= clickLimiterTotal) { if(mouse.down) { fireworks.push(new Firework(canvasWidth / 2, canvasHeight, mouse.x, mouse.y)); clickLimiterTick = 0; } } else { clickLimiterTick++; } } window.onload = gameLoop();
CSS
* { margin: 0; padding: 0; } html, body { height: 100%; } body { background: #000; } canvas { display: block; cursor: crosshair; }
HTML
Canvas is not supported by your browser.
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email