1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > HTML粒子碰撞烟花 html5 canvas漂亮的粒子烟花背景动画特效

HTML粒子碰撞烟花 html5 canvas漂亮的粒子烟花背景动画特效

时间:2022-03-21 08:05:01

相关推荐

HTML粒子碰撞烟花 html5 canvas漂亮的粒子烟花背景动画特效

特效描述:html5 canvas 漂亮的粒子烟花 背景动画特效。html5 canvas漂亮的粒子烟花背景动画特效

代码结构

1. HTML代码

class Vector2 {

constructor(x = 0, y = 0) {

this.x = x;

this.y = y;

}

add(v) {

this.x += v.x;

this.y += v.y;

return this;

}

multiplyScalar(s) {

this.x *= s;

this.y *= s;

return this;

}

clone() {

return new Vector2(this.x, this.y);

}

}

class Time {

constructor() {

const now = Time.now();

this.delta = 0;

this.elapsed = 0;

this.start = now;

this.previous = now;

}

update() {

const now = Time.now();

this.delta = now - this.previous;

this.elapsed = now - this.start;

this.previous = now;

}

static now() {

return Date.now() / 1000;

}

}

class Particle {

constructor(position, velocity = new Vector2, color = 'white', radius = 1, lifetime = 1, mass = 1) {

this.position = position;

this.velocity = velocity;

this.color = color;

this.radius = radius;

this.lifetime = lifetime;

this.mass = mass;

this.isInCanvas = true;

this.createdOn = Time.now();

}

update(time) {

if (!this.getRemainingLifetime()) {

return;

}

this.velocity.add(Particle.GRAVITATION.clone().multiplyScalar(this.mass));

this.position.add(this.velocity.clone().multiplyScalar(time.delta));

}

render(canvas, context) {

const remainingLifetime = this.getRemainingLifetime();

if (!remainingLifetime) return;

const radius = this.radius * remainingLifetime;

context.globalAlpha = remainingLifetime;

context.globalCompositeOperation = 'lighter';

context.fillStyle = this.color;

context.beginPath();

context.arc(this.position.x, this.position.y, radius, 0, Math.PI * 2);

context.fill();

}

getRemainingLifetime() {

const elapsedLifetime = Time.now() - this.createdOn;

return Math.max(0, this.lifetime - elapsedLifetime) / this.lifetime;

}

}

Particle.GRAVITATION = new Vector2(0, 9.81);

class Trail extends Particle {

constructor(childFactory, position, velocity = new Vector2, lifetime = 1, mass = 1) {

super(position, velocity);

this.childFactory = childFactory;

this.children = [];

this.lifetime = lifetime;

this.mass = mass;

this.isAlive = true;

}

update(time) {

super.update(time);

// Add a new child on every frame

if (this.isAlive && this.getRemainingLifetime()) {

this.children.push(this.childFactory(this));

}

// Remove particles that are dead

this.children = this.children.filter(function(child) {

if (child instanceof Trail) {

return child.isAlive;

}

return child.getRemainingLifetime();

});

// Kill trail if all particles fade away

if (!this.children.length) {

this.isAlive = false;

}

// Update particles

this.children.forEach(function(child) {

child.update(time);

});

}

render(canvas, context) {

// Render all children

this.children.forEach(function(child) {

child.render(canvas, context);

});

}

}

class Rocket extends Trail {

constructor(childFactory, explosionFactory, position, velocity = new Vector2) {

super(childFactory, position, velocity);

this.explosionFactory = explosionFactory;

this.lifetime = 10;

}

update(time) {

if (this.getRemainingLifetime() && this.velocity.y > 0) {

this.explosionFactory(this);

this.lifetime = 0;

}

super.update(time);

}

}

const canvas = document.createElement('canvas');

const context = canvas.getContext('2d');

const time = new Time;

let rockets = [];

const getTrustParticleFactory = function(baseHue) {

function getColor() {

const hue = Math.floor(Math.random() * 15 + 30);

return `hsl(${hue}, 100%, 75%`;

}

return function(parent) {

const position = this.position.clone();

const velocity = this.velocity.clone().multiplyScalar(-.1);

velocity.x += (Math.random() - .5) * 8;

const color = getColor();

const radius = 1 + Math.random();

const lifetime = .5 + Math.random() * .5;

const mass = .01;

return new Particle(position, velocity, color, radius, lifetime, mass);

};

};

const getExplosionFactory = function(baseHue) {

function getColor() {

const hue = Math.floor(baseHue + Math.random() * 15) % 360;

const lightness = Math.floor(Math.pow(Math.random(), 2) * 50 + 50);

return `hsl(${hue}, 100%, ${lightness}%`;

}

function getChildFactory() {

return function(parent) {

const direction = Math.random() * Math.PI * 2;

const force = 8;

const velocity = new Vector2(Math.cos(direction) * force, Math.sin(direction) * force);

const color = getColor();

const radius = 1 + Math.random();

const lifetime = 1;

const mass = .1;

return new Particle(parent.position.clone(), velocity, color, radius, lifetime, mass);

};

}

function getTrail(position) {

const direction = Math.random() * Math.PI * 2;

const force = Math.random() * 128;

const velocity = new Vector2(Math.cos(direction) * force, Math.sin(direction) * force);

const lifetime = .5 + Math.random();

const mass = .075;

return new Trail(getChildFactory(), position, velocity, lifetime, mass);

}

return function(parent) {

let trails = 32;

while (trails--) {

parent.children.push(getTrail(parent.position.clone()));

}

};

};

const addRocket = function() {

const trustParticleFactory = getTrustParticleFactory();

const explosionFactory = getExplosionFactory(Math.random() * 360);

const position = new Vector2(Math.random() * canvas.width, canvas.height);

const thrust = window.innerHeight * .75;

const angle = Math.PI / -2 + (Math.random() - .5) * Math.PI / 8;

const velocity = new Vector2(Math.cos(angle) * thrust, Math.sin(angle) * thrust);

const lifetime = 3;

rockets.push(new Rocket(trustParticleFactory, explosionFactory, position, velocity, lifetime));

rockets = rockets.filter(function(rocket) {

return rocket.isAlive;

});

};

const render = function() {

requestAnimationFrame(render);

time.update();

context.clearRect(0, 0, canvas.width, canvas.height);

rockets.forEach(function(rocket) {

rocket.update(time);

rocket.render(canvas, context);

});

};

const resize = function() {

canvas.height = window.innerHeight;

canvas.width = window.innerWidth;

};

canvas.onclick = addRocket;

document.body.appendChild(canvas);

window.onresize = resize;

resize();

setInterval(addRocket, 2000);

render();

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。