Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict'
- //constants
- const { PI: π, sin, cos, floor, round } = Math
- const g = 0.2
- //variables
- let c, ctx, W, H
- //animation variables
- let fc = 0 //frame count
- let pd = 2 //pixel density
- let paused = false
- let lastTimeCalled, fps
- let btn
- let fireworks = []
- let explParticles = []
- //functions
- class Particle {
- constructor() {
- this.x = random(W)
- this.y = H
- this.r = 4
- this.dx = random(-4, 4)
- this.dy = random(-20, -12)
- this.red = round(random(255))
- this.green = round(random(255))
- this.blue = round(random(255))
- this.a = 1
- }
- update() {
- //update speed
- this.dy += g
- //update position
- this.x += this.dx
- this.y += this.dy
- }
- draw() {
- //only draw particles inside the screen
- if (0 < this.x && this.x < W && 0 < this.y && this.y < H) {
- ctx.beginPath()
- ctx.arc(this.x, this.y, this.r, 0, 2 * π)
- ctx.fillStyle =
- 'rgba(' +
- this.red +
- ',' +
- this.green +
- ',' +
- this.blue +
- ',' +
- this.a +
- ')'
- ctx.fill()
- }
- }
- stoped() {
- return this.dy >= 0
- }
- explode() {
- for (let i = 0; i <= round(random(75, 100)); i++) {
- explParticles.push(
- new ExplParticle(this.x, this.y, this.red, this.green, this.blue)
- )
- }
- }
- }
- class ExplParticle extends Particle {
- constructor(x, y, red, green, blue) {
- super()
- this.x = x
- this.y = y
- this.r = random(1, 2)
- this.dx = random(25) * sin(random(0, 2 * π))
- this.dy = random(25) * sin(random(0, 2 * π))
- this.red = red
- this.green = green
- this.blue = blue
- this.a = 1
- this.da = random(0.012, 0.015)
- }
- update() {
- //air friction
- this.dx *= 0.85
- this.dy *= 0.85
- //update speed
- this.dy += g
- //update position
- this.x += this.dx
- this.y += this.dy
- //decrease opacity
- this.a -= this.da
- }
- faded() {
- return this.a < 0
- }
- }
- window.onload = () => {
- //timestamp
- lastTimeCalled = Date.now()
- fps = document.getElementById('Fps')
- //canvas setup
- c = document.getElementById('Canvas')
- ctx = c.getContext('2d')
- //canvas --> full screen
- setSize(window.innerWidth, window.innerHeight, pd)
- //add event listeners
- c.addEventListener('click', sp)
- c.addEventListener('dblclick', clearAll)
- btn = document.getElementById('Info')
- btn.addEventListener('click', info)
- //begin animation
- requestAnimationFrame(animate)
- }
- function animate(timestamp) {
- calcFPS()
- clear()
- if (random() < 0.06 && explParticles.length < 500) {
- fireworks.push(new Particle())
- }
- for (let i = fireworks.length - 1; i >= 0; i--) {
- fireworks[i].update()
- fireworks[i].draw()
- //remove exploded particles for performance
- if (fireworks[i].stoped()) {
- fireworks[i].explode()
- fireworks.splice(i, 1)
- }
- }
- //separate loop for explosion particles
- for (let i = explParticles.length - 1; i >= 0; i--) {
- explParticles[i].update()
- explParticles[i].draw()
- //remove faded particles for performance
- if (explParticles[i].faded()) {
- explParticles.splice(i, 1)
- }
- }
- if (!paused) {
- //call next animation recursively
- fc = requestAnimationFrame(animate)
- }
- }
- //utility functions
- function calcFPS() {
- //current time-last timestamp
- let timeDiff = Date.now() - lastTimeCalled
- //update timestamp
- lastTimeCalled = Date.now()
- //1000ms/time passed
- fps.innerText = 'fps: ' + floor(1000 / timeDiff)
- }
- function sp() {
- if (!paused) {
- window.cancelAnimationFrame(fc)
- paused = true
- } else {
- window.requestAnimationFrame(animate)
- paused = false
- }
- }
- function clear() {
- ctx.fillStyle = 'rgba(0,0,0,0.45)'
- ctx.fillRect(0, 0, W, H)
- }
- function clearAll() {
- fireworks = []
- explParticles = []
- clear()
- }
- function setSize(w, h, pd) {
- //canvas apparent size
- c.style.width = w + 'px'
- c.style.height = h + 'px'
- //canvas actual size
- c.width = W = w * pd
- c.height = H = h * pd
- }
- function random(min = 0, max = 1) {
- return Math.random() * (max - min) + min
- }
- function info() {
- alert(
- 'Vanilla js fireworks!\n\nClick --> Start/Pause.\nDouble click --> Reset.\n\nUpdates:\n1) Cleaned & updated to es6 and also finally added round explosions.\n2) Further cleaned the code using object inheritance.'
- )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement