Canvas Fireworks
How do I make an canvas fireworks?
Click anywhere to launch fireworks. Click and drag to fire multiple fireworks. Settings can be adjusted in the top right. Be sure to try the presets. If things are running slow, try reducing reduce the partCount setting.. What is a canvas fireworks? How do you make a canvas fireworks? This script and codes were developed by Jack Rugile on 11 August 2022, Thursday.
Canvas Fireworks - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Canvas Fireworks</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <style> /* NOTE: The styles were added inline because Prefixfree needs access to your styles and they must be inlined if they are on local disk! */ html, body { margin: 0; padding: 0;
}
body { background: #171717; color: #999; font: 100%/18px helvetica, arial, sans-serif;
}
a { color: #2fa1d6; font-weight: bold; text-decoration: none;
}
a:hover { color: #fff;
}
#canvas-container { background: #000 url(http://jackrugile.com/lab/fireworks-v2/images/bg.jpg); height: 400px; left: 50%; margin: -200px 0 0 -300px; position: absolute; top: 50%; width: 600px; z-index: 2;
}
canvas { cursor: crosshair; display: block; position: relative; z-index: 3;
}
canvas:active { cursor: crosshair;
}
#skyline { background: url(http://jackrugile.com/lab/fireworks-v2/images/skyline.png) repeat-x 50% 0; bottom: 0; height: 135px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#mountains1 { background: url(http://jackrugile.com/lab/fireworks-v2/images/mountains1.png) repeat-x 40% 0; bottom: 0; height: 200px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#mountains2 { background: url(https://jackrugile.com/lab/fireworks-v2/images/mountains2.png) repeat-x 30% 0; bottom: 0; height: 250px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#gui { right: 0; position: fixed; top: 0; z-index: 3;
} </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body> <div id="gui"></div>
<div id="canvas-container"> <div id="mountains2"></div> <div id="mountains1"></div> <div id="skyline"></div>
</div> <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='http://jackrugile.com/lab/fireworks-v2/js/dat.gui.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
Canvas Fireworks - Script Codes CSS Codes
html, body { margin: 0; padding: 0;
}
body { background: #171717; color: #999; font: 100%/18px helvetica, arial, sans-serif;
}
a { color: #2fa1d6; font-weight: bold; text-decoration: none;
}
a:hover { color: #fff;
}
#canvas-container { background: #000 url(http://jackrugile.com/lab/fireworks-v2/images/bg.jpg); height: 400px; left: 50%; margin: -200px 0 0 -300px; position: absolute; top: 50%; width: 600px; z-index: 2;
}
canvas { cursor: crosshair; display: block; position: relative; z-index: 3;
}
canvas:active { cursor: crosshair;
}
#skyline { background: url(http://jackrugile.com/lab/fireworks-v2/images/skyline.png) repeat-x 50% 0; bottom: 0; height: 135px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#mountains1 { background: url(http://jackrugile.com/lab/fireworks-v2/images/mountains1.png) repeat-x 40% 0; bottom: 0; height: 200px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#mountains2 { background: url(https://jackrugile.com/lab/fireworks-v2/images/mountains2.png) repeat-x 30% 0; bottom: 0; height: 250px; left: 0; position: absolute; width: 100%; z-index: 1;
}
#gui { right: 0; position: fixed; top: 0; z-index: 3;
}
Canvas Fireworks - Script Codes JS Codes
var Fireworks = function(){ /*=============================================================================*/ /* Utility /*=============================================================================*/ var self = this; var rand = function(rMi, rMa){return ~~((Math.random()*(rMa-rMi+1))+rMi);} var hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2){return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);}; window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){window.setTimeout(a,1E3/60)}}(); /*=============================================================================*/ /* Initialize /*=============================================================================*/ self.init = function(){ self.dt = 0; self.oldTime = Date.now(); self.canvas = document.createElement('canvas'); self.canvasContainer = $('#canvas-container'); var canvasContainerDisabled = document.getElementById('canvas-container'); self.canvas.onselectstart = function() { return false; }; self.canvas.width = self.cw = 600; self.canvas.height = self.ch = 400; self.particles = []; self.partCount = 30; self.fireworks = []; self.mx = self.cw/2; self.my = self.ch/2; self.currentHue = 170; self.partSpeed = 5; self.partSpeedVariance = 10; self.partWind = 50; self.partFriction = 5; self.partGravity = 1; self.hueMin = 150; self.hueMax = 200; self.fworkSpeed = 2; self.fworkAccel = 4; self.hueVariance = 30; self.flickerDensity = 20; self.showShockwave = false; self.showTarget = true; self.clearAlpha = 25; self.canvasContainer.append(self.canvas); self.ctx = self.canvas.getContext('2d'); self.ctx.lineCap = 'round'; self.ctx.lineJoin = 'round'; self.lineWidth = 1; self.bindEvents(); self.canvasLoop(); self.canvas.onselectstart = function() { return false; }; }; /*=============================================================================*/ /* Particle Constructor /*=============================================================================*/ var Particle = function(x, y, hue){ this.x = x; this.y = y; this.coordLast = [ {x: x, y: y}, {x: x, y: y}, {x: x, y: y} ]; this.angle = rand(0, 360); this.speed = rand(((self.partSpeed - self.partSpeedVariance) <= 0) ? 1 : self.partSpeed - self.partSpeedVariance, (self.partSpeed + self.partSpeedVariance)); this.friction = 1 - self.partFriction/100; this.gravity = self.partGravity/2; this.hue = rand(hue-self.hueVariance, hue+self.hueVariance); this.brightness = rand(50, 80); this.alpha = rand(40,100)/100; this.decay = rand(10, 50)/1000; this.wind = (rand(0, self.partWind) - (self.partWind/2))/25; this.lineWidth = self.lineWidth; }; Particle.prototype.update = function(index){ var radians = this.angle * Math.PI / 180; var vx = Math.cos(radians) * this.speed; var vy = Math.sin(radians) * this.speed + this.gravity; this.speed *= this.friction; this.coordLast[2].x = this.coordLast[1].x; this.coordLast[2].y = this.coordLast[1].y; this.coordLast[1].x = this.coordLast[0].x; this.coordLast[1].y = this.coordLast[0].y; this.coordLast[0].x = this.x; this.coordLast[0].y = this.y; this.x += vx * self.dt; this.y += vy * self.dt; this.angle += this.wind; this.alpha -= this.decay; if(!hitTest(0,0,self.cw,self.ch,this.x-this.radius, this.y-this.radius, this.radius*2, this.radius*2) || this.alpha < .05){ self.particles.splice(index, 1); } }; Particle.prototype.draw = function(){ var coordRand = (rand(1,3)-1); self.ctx.beginPath(); self.ctx.moveTo(Math.round(this.coordLast[coordRand].x), Math.round(this.coordLast[coordRand].y)); self.ctx.lineTo(Math.round(this.x), Math.round(this.y)); self.ctx.closePath(); self.ctx.strokeStyle = 'hsla('+this.hue+', 100%, '+this.brightness+'%, '+this.alpha+')'; self.ctx.stroke(); if(self.flickerDensity > 0){ var inverseDensity = 50 - self.flickerDensity; if(rand(0, inverseDensity) === inverseDensity){ self.ctx.beginPath(); self.ctx.arc(Math.round(this.x), Math.round(this.y), rand(this.lineWidth,this.lineWidth+3)/2, 0, Math.PI*2, false) self.ctx.closePath(); var randAlpha = rand(50,100)/100; self.ctx.fillStyle = 'hsla('+this.hue+', 100%, '+this.brightness+'%, '+randAlpha+')'; self.ctx.fill(); } } }; /*=============================================================================*/ /* Create Particles /*=============================================================================*/ self.createParticles = function(x,y, hue){ var countdown = self.partCount; while(countdown--){ self.particles.push(new Particle(x, y, hue)); } }; /*=============================================================================*/ /* Update Particles /*=============================================================================*/ self.updateParticles = function(){ var i = self.particles.length; while(i--){ var p = self.particles[i]; p.update(i); }; }; /*=============================================================================*/ /* Draw Particles /*=============================================================================*/ self.drawParticles = function(){ var i = self.particles.length; while(i--){ var p = self.particles[i]; p.draw(); }; }; /*=============================================================================*/ /* Firework Constructor /*=============================================================================*/ var Firework = function(startX, startY, targetX, targetY){ this.x = startX; this.y = startY; this.startX = startX; this.startY = startY; this.hitX = false; this.hitY = false; this.coordLast = [ {x: startX, y: startY}, {x: startX, y: startY}, {x: startX, y: startY} ]; this.targetX = targetX; this.targetY = targetY; this.speed = self.fworkSpeed; this.angle = Math.atan2(targetY - startY, targetX - startX); this.shockwaveAngle = Math.atan2(targetY - startY, targetX - startX)+(90*(Math.PI/180)); this.acceleration = self.fworkAccel/100; this.hue = self.currentHue; this.brightness = rand(50, 80); this.alpha = rand(50,100)/100; this.lineWidth = self.lineWidth; this.targetRadius = 1; }; Firework.prototype.update = function(index){ self.ctx.lineWidth = this.lineWidth; vx = Math.cos(this.angle) * this.speed, vy = Math.sin(this.angle) * this.speed; this.speed *= 1 + this.acceleration; this.coordLast[2].x = this.coordLast[1].x; this.coordLast[2].y = this.coordLast[1].y; this.coordLast[1].x = this.coordLast[0].x; this.coordLast[1].y = this.coordLast[0].y; this.coordLast[0].x = this.x; this.coordLast[0].y = this.y; if(self.showTarget){ if(this.targetRadius < 8){ this.targetRadius += .25 * self.dt; } else { this.targetRadius = 1 * self.dt; } } if(this.startX >= this.targetX){ if(this.x + vx <= this.targetX){ this.x = this.targetX; this.hitX = true; } else { this.x += vx * self.dt; } } else { if(this.x + vx >= this.targetX){ this.x = this.targetX; this.hitX = true; } else { this.x += vx * self.dt; } } if(this.startY >= this.targetY){ if(this.y + vy <= this.targetY){ this.y = this.targetY; this.hitY = true; } else { this.y += vy * self.dt; } } else { if(this.y + vy >= this.targetY){ this.y = this.targetY; this.hitY = true; } else { this.y += vy * self.dt; } } if(this.hitX && this.hitY){ var randExplosion = rand(0, 9); self.createParticles(this.targetX, this.targetY, this.hue); self.fireworks.splice(index, 1); } }; Firework.prototype.draw = function(){ self.ctx.lineWidth = this.lineWidth; var coordRand = (rand(1,3)-1); self.ctx.beginPath(); self.ctx.moveTo(Math.round(this.coordLast[coordRand].x), Math.round(this.coordLast[coordRand].y)); self.ctx.lineTo(Math.round(this.x), Math.round(this.y)); self.ctx.closePath(); self.ctx.strokeStyle = 'hsla('+this.hue+', 100%, '+this.brightness+'%, '+this.alpha+')'; self.ctx.stroke(); if(self.showTarget){ self.ctx.save(); self.ctx.beginPath(); self.ctx.arc(Math.round(this.targetX), Math.round(this.targetY), this.targetRadius, 0, Math.PI*2, false) self.ctx.closePath(); self.ctx.lineWidth = 1; self.ctx.stroke(); self.ctx.restore(); } if(self.showShockwave){ self.ctx.save(); self.ctx.translate(Math.round(this.x), Math.round(this.y)); self.ctx.rotate(this.shockwaveAngle); self.ctx.beginPath(); self.ctx.arc(0, 0, 1*(this.speed/5), 0, Math.PI, true); self.ctx.strokeStyle = 'hsla('+this.hue+', 100%, '+this.brightness+'%, '+rand(25, 60)/100+')'; self.ctx.lineWidth = this.lineWidth; self.ctx.stroke(); self.ctx.restore(); } }; /*=============================================================================*/ /* Create Fireworks /*=============================================================================*/ self.createFireworks = function(startX, startY, targetX, targetY){ self.fireworks.push(new Firework(startX, startY, targetX, targetY)); }; /*=============================================================================*/ /* Update Fireworks /*=============================================================================*/ self.updateFireworks = function(){ var i = self.fireworks.length; while(i--){ var f = self.fireworks[i]; f.update(i); }; }; /*=============================================================================*/ /* Draw Fireworks /*=============================================================================*/ self.drawFireworks = function(){ var i = self.fireworks.length; while(i--){ var f = self.fireworks[i]; f.draw(); }; }; /*=============================================================================*/ /* Events /*=============================================================================*/ self.bindEvents = function(){ $(window).on('resize', function(){ clearTimeout(self.timeout); self.timeout = setTimeout(function() { self.ctx.lineCap = 'round'; self.ctx.lineJoin = 'round'; }, 100); }); $(self.canvas).on('mousedown', function(e){ var randLaunch = rand(0, 5); self.mx = e.pageX - self.canvasContainer.offset().left; self.my = e.pageY - self.canvasContainer.offset().top; self.currentHue = rand(self.hueMin, self.hueMax); self.createFireworks(self.cw/2, self.ch, self.mx, self.my); $(self.canvas).on('mousemove.fireworks', function(e){ var randLaunch = rand(0, 5); self.mx = e.pageX - self.canvasContainer.offset().left; self.my = e.pageY - self.canvasContainer.offset().top; self.currentHue = rand(self.hueMin, self.hueMax); self.createFireworks(self.cw/2, self.ch, self.mx, self.my); }); }); $(self.canvas).on('mouseup', function(e){ $(self.canvas).off('mousemove.fireworks'); }); } /*=============================================================================*/ /* Clear Canvas /*=============================================================================*/ self.clear = function(){ self.particles = []; self.fireworks = []; self.ctx.clearRect(0, 0, self.cw, self.ch); }; /*=============================================================================*/ /* Delta /*=============================================================================*/ self.updateDelta = function(){ var newTime = Date.now(); self.dt = (newTime - self.oldTime)/16; self.dt = (self.dt > 5) ? 5 : self.dt; self.oldTime = newTime; } /*=============================================================================*/ /* Main Loop /*=============================================================================*/ self.canvasLoop = function(){ requestAnimFrame(self.canvasLoop, self.canvas); self.updateDelta(); self.ctx.globalCompositeOperation = 'destination-out'; self.ctx.fillStyle = 'rgba(0,0,0,'+self.clearAlpha/100+')'; self.ctx.fillRect(0,0,self.cw,self.ch); self.ctx.globalCompositeOperation = 'lighter'; self.updateFireworks(); self.updateParticles(); self.drawFireworks(); self.drawParticles(); }; self.init(); var initialLaunchCount = 10; while(initialLaunchCount--){ setTimeout(function(){ self.fireworks.push(new Firework(self.cw/2, self.ch, rand(50, self.cw-50), rand(50, self.ch/2)-50)); }, initialLaunchCount*200); }
}
/*=============================================================================*/
/* GUI
/*=============================================================================*/
var guiPresets = { "preset": "Default", "remembered": { "Default": { "0": { "fworkSpeed": 2, "fworkAccel": 4, "showShockwave": false, "showTarget": true, "partCount": 30, "partSpeed": 5, "partSpeedVariance": 10, "partWind": 50, "partFriction": 5, "partGravity": 1, "flickerDensity": 20, "hueMin": 150, "hueMax": 200, "hueVariance": 30, "lineWidth": 1, "clearAlpha": 25 } }, "Anti Gravity": { "0": { "fworkSpeed": 4, "fworkAccel": 10, "showShockwave": true, "showTarget": false, "partCount": 150, "partSpeed": 5, "partSpeedVariance": 10, "partWind": 10, "partFriction": 10, "partGravity": -10, "flickerDensity": 30, "hueMin": 0, "hueMax": 360, "hueVariance": 30, "lineWidth": 1, "clearAlpha": 50 } }, "Battle Field": { "0": { "fworkSpeed": 10, "fworkAccel": 20, "showShockwave": true, "showTarget": true, "partCount": 200, "partSpeed": 30, "partSpeedVariance": 5, "partWind": 0, "partFriction": 5, "partGravity": 0, "flickerDensity": 0, "hueMin": 20, "hueMax": 30, "hueVariance": 10, "lineWidth": 1, "clearAlpha": 40 } }, "Mega Blast": { "0": { "fworkSpeed": 3, "fworkAccel": 3, "showShockwave": true, "showTarget": true, "partCount": 500, "partSpeed": 50, "partSpeedVariance": 5, "partWind": 0, "partFriction": 0, "partGravity": 0, "flickerDensity": 0, "hueMin": 0, "hueMax": 360, "hueVariance": 30, "lineWidth": 20, "clearAlpha": 20 } }, "Nimble": { "0": { "fworkSpeed": 10, "fworkAccel": 50, "showShockwave": false, "showTarget": false, "partCount": 120, "partSpeed": 10, "partSpeedVariance": 10, "partWind": 100, "partFriction": 50, "partGravity": 0, "flickerDensity": 20, "hueMin": 0, "hueMax": 360, "hueVariance": 30, "lineWidth": 1, "clearAlpha": 80 } }, "Slow Launch": { "0": { "fworkSpeed": 2, "fworkAccel": 2, "showShockwave": false, "showTarget": false, "partCount": 200, "partSpeed": 10, "partSpeedVariance": 0, "partWind": 100, "partFriction": 0, "partGravity": 2, "flickerDensity": 50, "hueMin": 0, "hueMax": 360, "hueVariance": 20, "lineWidth": 4, "clearAlpha": 10 } }, "Perma Trail": { "0": { "fworkSpeed": 4, "fworkAccel": 10, "showShockwave": false, "showTarget": false, "partCount": 150, "partSpeed": 10, "partSpeedVariance": 10, "partWind": 100, "partFriction": 3, "partGravity": 0, "flickerDensity": 0, "hueMin": 0, "hueMax": 360, "hueVariance": 20, "lineWidth": 1, "clearAlpha": 0 } } }, "closed": true, "folders": { "Fireworks": { "preset": "Default", "closed": false, "folders": {} }, "Particles": { "preset": "Default", "closed": true, "folders": {} }, "Color": { "preset": "Default", "closed": true, "folders": {} }, "Other": { "preset": "Default", "closed": true, "folders": {} } } };
var fworks = new Fireworks();
var gui = new dat.GUI({ autoPlace: false, load: guiPresets, preset: 'Default'
});
var customContainer = document.getElementById('gui');
customContainer.appendChild(gui.domElement);
var guiFireworks = gui.addFolder('Fireworks');
guiFireworks.add(fworks, 'fworkSpeed').min(1).max(10).step(1);
guiFireworks.add(fworks, 'fworkAccel').min(0).max(50).step(1);
guiFireworks.add(fworks, 'showShockwave');
guiFireworks.add(fworks, 'showTarget');
var guiParticles = gui.addFolder('Particles');
guiParticles.add(fworks, 'partCount').min(0).max(500).step(1);
guiParticles.add(fworks, 'partSpeed').min(1).max(100).step(1);
guiParticles.add(fworks, 'partSpeedVariance').min(0).max(50).step(1);
guiParticles.add(fworks, 'partWind').min(0).max(100).step(1);
guiParticles.add(fworks, 'partFriction').min(0).max(50).step(1);
guiParticles.add(fworks, 'partGravity').min(-20).max(20).step(1);
guiParticles.add(fworks, 'flickerDensity').min(0).max(50).step(1);
var guiColor = gui.addFolder('Color');
guiColor.add(fworks, 'hueMin').min(0).max(360).step(1);
guiColor.add(fworks, 'hueMax').min(0).max(360).step(1);
guiColor.add(fworks, 'hueVariance').min(0).max(180).step(1);
var guiOther = gui.addFolder('Other');
guiOther.add(fworks, 'lineWidth').min(1).max(20).step(1);
guiOther.add(fworks, 'clearAlpha').min(0).max(100).step(1);
guiOther.add(fworks, 'clear').name('Clear');
gui.remember(fworks);
Developer | Jack Rugile |
Username | jackrugile |
Uploaded | August 11, 2022 |
Rating | 4.5 |
Size | 6,200 Kb |
Views | 145,728 |
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 |
SpacePi js13k | 19,847 Kb |
Rainbow Loader | 2,022 Kb |
CSS Vinyl Record | 3,972 Kb |
Rainbow Firestorm | 3,052 Kb |
Canvas Simple Circle Loader | 2,946 Kb |
Scroll Progress as Canvas to Favicon | 2,407 Kb |
CSS3 Pseudo Sound Bars | 2,400 Kb |
Light Loader | 2,738 Kb |
Rainbow Grid | 2,760 Kb |
Fade and Blur on Hover Data Table | 3,399 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 |
Simple Buttons | Haydenmills | 1,750 Kb |
Commuter Line Tokyu 8500 | Pedox | 7,031 Kb |
Find The Penguin | Lelder | 2,212 Kb |
Custom Checkbox and radio inputs SCSS | Rgfx | 3,367 Kb |
Basecamp 3 Document | Lachlanjc | 3,811 Kb |
Animate elements with fixed gradient | Badabam | 4,406 Kb |
Cloud upload | Jaflo | 2,774 Kb |
Arrow Navigation | Hinducows | 1,973 Kb |
Subtle site navigation with description | Necks | 3,206 Kb |
Toggling Divs with jQuery | Yying6 | 1,967 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!