canvas烟花锦集

Posted 前端小老虎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了canvas烟花锦集相关的知识,希望对你有一定的参考价值。

canvas可以实现不同动画效果,本文主要记录几种不同节日烟花效果实现。

实现一

效果地址

html

``` ```

css

``` body { background: #000; margin: 0; }

canvas {
cursor: crosshair;
display: block;
}

<h3>js</h3>

// when animating on canvas, it is best to use requestAnimationFrame instead of setTimeout or setInterval
// not supported in all browsers though and sometimes needs a prefix, so we need a shim
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();

// now we will setup our basic variables for the demo
var canvas = document.getElementById(\'canvas\'),
ctx = canvas.getContext(\'2d\'),
// full screen dimensions
cw = window.innerWidth,
ch = window.innerHeight,
// firework collection
fireworks = [],
// particle collection
particles = [],
// starting hue
hue = 120,
// when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks
limiterTotal = 5,
limiterTick = 0,
// this will time the auto launches of fireworks, one launch per 80 loop ticks
timerTotal = 80,
timerTick = 0,
mousedown = false,
// mouse x coordinate,
mx,
// mouse y coordinate
my;

// set canvas dimensions
canvas.width = cw;
canvas.height = ch;

// now we are going to setup our function placeholders for the entire demo

// get a random number within a range
function random(min, max) {
return Math.random() * (max - min) + min;
}

// calculate the distance between two points
function calculateDistance(p1x, p1y, p2x, p2y) {
var xDistance = p1x - p2x,
yDistance = p1y - p2y;
return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
}

// create firework
function Firework(sx, sy, tx, ty) {
// actual coordinates
this.x = sx;
this.y = sy;
// starting coordinates
this.sx = sx;
this.sy = sy;
// target coordinates
this.tx = tx;
this.ty = ty;
// distance from starting point to target
this.distanceToTarget = calculateDistance(sx, sy, tx, ty);
this.distanceTraveled = 0;
// track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trails
this.coordinates = [];
this.coordinateCount = 3;
// populate initial coordinate collection with the current coordinates
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
this.angle = Math.atan2(ty - sy, tx - sx);
this.speed = 2;
this.acceleration = 1.05;
this.brightness = random(50, 70);
// circle target indicator radius
this.targetRadius = 1;
}

// update firework
Firework.prototype.update = function (index) {
// remove last item in coordinates array
this.coordinates.pop();
// add current coordinates to the start of the array
this.coordinates.unshift([this.x, this.y]);

// cycle the circle target indicator radius
if (this.targetRadius < 8) {
    this.targetRadius += 0.3;
} else {
    this.targetRadius = 1;
}

// speed up the firework
this.speed *= this.acceleration;

// get the current velocities based on angle and speed
var vx = Math.cos(this.angle) * this.speed,
    vy = Math.sin(this.angle) * this.speed;
// how far will the firework have traveled with velocities applied?
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 (this.distanceTraveled >= this.distanceToTarget) {
    createParticles(this.tx, this.ty);
    // remove the firework, use the index passed into the update function to determine which to remove
    fireworks.splice(index, 1);
} else {
    // target not reached, keep traveling
    this.x += vx;
    this.y += vy;
}

}

// draw firework
Firework.prototype.draw = function () {
ctx.beginPath();
// move to the last tracked coordinate in the set, then draw a line to the current x and y
ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][
1
]);
ctx.lineTo(this.x, this.y);
ctx.strokeStyle = \'hsl(\' + hue + \', 100%, \' + this.brightness + \'%)\';
ctx.stroke();

ctx.beginPath();
// draw the target for this firework with a pulsing circle
ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2);
ctx.stroke();

}

// create particle
function Particle(x, y) {
this.x = x;
this.y = y;
// track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails
this.coordinates = [];
this.coordinateCount = 5;
while (this.coordinateCount--) {
this.coordinates.push([this.x, this.y]);
}
// set a random angle in all possible directions, in radians
this.angle = random(0, Math.PI * 2);
this.speed = random(1, 10);
// friction will slow the particle down
this.friction = 0.95;
// gravity will be applied and pull the particle down
this.gravity = 1;
// set the hue to a random number +-20 of the overall hue variable
this.hue = random(hue - 20, hue + 20);
this.brightness = random(50, 80);
this.alpha = 1;
// set how fast the particle fades out
this.decay = random(0.015, 0.03);
}

// update particle
Particle.prototype.update = function (index) {
// remove last item in coordinates array
this.coordinates.pop();
// add current coordinates to the start of the array
this.coordinates.unshift([this.x, this.y]);
// slow down the particle
this.speed *= this.friction;
// apply velocity
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed + this.gravity;
// fade out the particle
this.alpha -= this.decay;

// remove the particle once the alpha is low enough, based on the passed in index
if (this.alpha <= this.decay) {
    particles.splice(index, 1);
}

}

// draw particle
Particle.prototype.draw = function () {

ctx.beginPath();
// move to the last tracked coordinates in the set, then draw a line to the current x and y
ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][
    1
]);
ctx.lineTo(this.x, this.y);
ctx.strokeStyle = \'hsla(\' + this.hue + \', 100%, \' + this.brightness + \'%, \' + this.alpha + \')\';
ctx.stroke();

}

// create particle group/explosion
function createParticles(x, y) {
// increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though
var particleCount = 30;
while (particleCount--) {
particles.push(new Particle(x, y));
}
}

// main demo loop
function loop() {
// this function will run endlessly with requestAnimationFrame
requestAnimFrame(loop);

// increase the hue to get different colored fireworks over time
hue += 0.5;

// normally, clearRect() would be used to clear the canvas
// we want to create a trailing effect though
// setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely
ctx.globalCompositeOperation = \'destination-out\';
// decrease the alpha property to create more prominent trails
ctx.fillStyle = \'rgba(0, 0, 0, 0.5)\';
ctx.fillRect(0, 0, cw, ch);
// change the composite operation back to our main mode
// lighter creates bright highlight points as the fireworks and particles overlap each other
ctx.globalCompositeOperation = \'lighter\';

var text = "HAPPY NEW YEAR !";
ctx.font = "50px sans-serif";
var textData = ctx.measureText(text);
ctx.fillStyle = "rgba(" + parseInt(random(0, 255)) + "," + parseInt(random(0, 255)) + "," + parseInt(random(0,
    255)) + ",0.3)";
ctx.fillText(text, cw / 2 - textData.width / 2, ch / 2);

// loop over each firework, draw it, update it
var i = fireworks.length;
while (i--) {
    fireworks[i].draw();
    fireworks[i].update(i);
}

// loop over each particle, draw it, update it
var i = particles.length;
while (i--) {
    particles[i].draw();
    particles[i].update(i);
}

// launch fireworks automatically to random coordinates, when the mouse isn\'t down
if (timerTick >= timerTotal) {
    if (!mousedown) {
        // start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of the top half of the screen

        for (var h = 0; h < 50; h++) {
            fireworks.push(new Firework(cw / 2, ch / 2, random(0, cw), random(0, ch)));
        }

        timerTick = 0;
    }
} else {
    timerTick++;
}

// limit the rate at which fireworks get launched when mouse is down
if (limiterTick >= limiterTotal) {
    if (mousedown) {
        // start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target
        fireworks.push(new Firework(cw / 2, ch / 2, mx, my));
        limiterTick = 0;
    }
} else {
    limiterTick++;
}

}

// mouse event bindings
// update the mouse coordinates on mousemove
canvas.addEventListener(\'mousemove\', function (e) {
mx = e.pageX - canvas.offsetLeft;
my = e.pageY - canvas.offsetTop;
});

// toggle mousedown state and prevent canvas from being selected
canvas.addEventListener(\'mousedown\', function (e) {
e.preventDefault();
mousedown = true;
});

canvas.addEventListener(\'mouseup\', function (e) {
e.preventDefault();
mousedown = false;
});

// once the window loads, we are ready for some fireworks!
window.onload = loop;



<h2>实现二</h2>


![](http://images2017.cnblogs.com/blog/1302312/201801/1302312-20180122220225834-670382005.png)


<a href="http://www.bestvist.com/html/canvas-fireworks/firework2.html" target="_blank">效果地址</a>

<h3>html</h3>

2018

```

css

``` html, body { padding: 0px; margin: 0px; background: #222; font-family: \'Karla\', sans-serif; color: #FFF; height: 100%; overflow: hidden; }

h1 {
z-index: 1000;
position: fixed;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-100%);
font-size: 58px;
overflow: hidden;
}

span {
position: relative;
display: inline-block;
animation: drop 0.75s ease 0s;
}

canvas {
width: 100%;
height: 100%;
}

@keyframes drop {
0% {
transform: translateY(-100px);
opacity: 0;
}

90% {
    opacity: 1;
    transform: translateY(10px);
}
100% {
    transform: translateY(0px);
}

}


<h3>js</h3>

var ctx = document.querySelector(\'canvas\').getContext(\'2d\')
ctx.canvas.width = window.innerWidth
ctx.canvas.height = window.innerHeight

var sparks = []
var fireworks = []
var i = 20;
while (i--) {
fireworks.push(
new Firework(Math.random() * window.innerWidth, window.innerHeight * Math.random())
)
}

render()

function render() {
setTimeout(render, 1000 / 60)
ctx.fillStyle = \'rgba(0, 0, 0, 0.1)\';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
for (var firework of fireworks) {
if (firework.dead) continue
firework.move()
firework.draw()
}
for (var spark of sparks) {
if (spark.dead) continue
spark.move()
spark.draw()
}

if (Math.random() < 0.05) {
    fireworks.push(new Firework())
}

}

function Spark(x, y, color) {
this.x = x
this.y = y
this.dir = Math.random() * (Math.PI * 2)
this.dead = false
this.color = color
this.speed = Math.random() * 3 + 3;
this.walker = new Walker({
radius: 20,
speed: 0.25
})
this.gravity = 0.25
this.dur = this.speed / 0.1
this.move = function () {
this.dur--
if (this.dur < 0) this.dead = true

    if (this.speed < 0) return
    if (this.speed > 0) this.speed -= 0.1
    var walk = this.walker.step()
    this.x += Math.cos(this.dir + walk) * this.speed
    this.y += Math.sin(this.dir + walk) * this.speed
    this.y += this.gravity
    this.gravity += 0.05

}
this.draw = function () {
    drawCircle(this.x, this.y, 3, this.color)
}

}

function Firework(x, y) {
this.xmove = new Walker({
radius: 10,
speed: 0.5
})
this.x = x || Math.random() * ctx.canvas.width
this.y = y || ctx.canvas.height
this.height = Math.random() * ctx.canvas.height / 2
this.dead = false
this.color = randomColor()

this.move = function () {
    this.x += this.xmove.step()
    if (this.y > this.height) this.y -= 1;
    else this.burst()

}
this.draw = function () {
    drawCircle(this.x, this.y, 1, this.color)
}
this.burst = function () {
    this.dead = true
    var i = 100;
    while (i--) sparks.push(new Spark(this.x, this.y, this.color))
}

}

function drawCircle(x, y, radius, color) {
color = color || \'#FFF\'
ctx.fillStyle = color
ctx.fillRect(x - radius / 2, y - radius / 2, radius, radius)
}

function randomColor() {
return [\'#6ae5ab\', \'#88e3b2\', \'#36b89b\', \'#7bd7ec\', \'#66cbe1\'][Math.floor(Math.random() * 5)];
}

function Walker(options) {
this.step = function () {
this.direction = Math.sign(this.target) * this.speed
this.value += this.direction
this.target ?
this.target -= this.direction :
(this.value) ?
(this.wander) ?
this.target = this.newTarget() :
this.target = -this.value :
this.target = this.newTarget()
return this.direction
}

this.newTarget = function () {
    return Math.round(Math.random() * (this.radius * 2) - this.radius)
}

this.start = 0
this.value = 0
this.radius = options.radius
this.target = this.newTarget()
this.direction = Math.sign(this.target)
this.wander = options.wander
this.speed = options.speed || 1

}


<h2>实现三</h2>


![](http://images2017.cnblogs.com/blog/1302312/201801/1302312-20180122220238475-1538284884.png)

<a href="http://www.bestvist.com/html/canvas-fireworks/firework3.html" target="_blank">效果地址</a>

<h3>html</h3>

浏览器不支持canvas

新年快乐
阖家欢乐
万事如意
心想事成
```

css

```

body {
margin: 0;
padding: 0;
overflow: hidden;
}

.city {
width: 100%;
position: fixed;
bottom: 0px;
z-index: 100;
}

.city img {
width: 100%;
}

 
<h3>js</h3>

var canvas = document.getElementById("cas");
var ocas = document.createElement("canvas");
var octx = ocas.getContext("2d");
var ctx = canvas.getContext("2d");
ocas.width = canvas.width = window.innerWidth;
ocas.height = canvas.height = window.innerHeight;
var bigbooms = [];

window.onload = function () {
initAnimate()
}

function initAnimate() {
drawBg();

lastTime = new Date();
animate();

}

var lastTime;

function animate() {
ctx.save();
ctx.fillStyle = "rgba(0,5,24,0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();

var newTime = new Date();
if (newTime - lastTime > 500 + (window.innerHeight - 767) / 2) {
    var random = Math.random() * 100 > 2 ? true : false;
    var x = getRandom(canvas.width / 5, canvas.width * 4 / 5);
    var y = getRandom(50, 200);
    if (random) {
        var bigboom = new Boom(getRandom(canvas.width / 3, canvas.width * 2 / 3), 2, "#FFF", {
            x: x,
            y: y
        });
        bigbooms.push(bigboom)
    } else {
        var bigboom = new Boom(getRandom(canvas.width / 3, canvas.width * 2 / 3), 2, "#FFF", {
            x: canvas.width / 2,
            y: 200
        }, document.querySelectorAll(".shape")[parseInt(getRandom(0, document.querySelectorAll(
            ".shape").length))]);
        bigbooms.push(bigboom)
    }
    lastTime = newTime;
}

stars.foreach(function () {
    this.paint();
})

drawMoon();

bigbooms.foreach(function (index) {
    var that = this;
    if (!this.dead) {
        this._move();
        this._drawLight();
    } else {
        this.booms.foreach(function (index) {
            if (!this.dead) {
                this.moveTo(index);
            } else if (index === that.booms.length - 1) {
                bigbooms[bigbooms.indexOf(that)] = null;
            }
        })
    }
});

raf(animate);

}

function drawMoon() {
var moon = document.getElementById("moon");
var centerX = canvas.width - 200,
centerY = 100,
width = 80;
if (moon.complete) {
ctx.drawImage(moon, centerX, centerY, width, width)
} else {
moon.onload = function () {
ctx.drawImage(moon, centerX, centerY, width, width)
}
}
var index = 0;
for (var i = 0; i < 10; i++) {
ctx.save();
ctx.beginPath();
ctx.arc(centerX + width / 2, centerY + width / 2, width / 2 + index, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(240,219,120,0.005)";
index += 2;
ctx.fill();
ctx.restore();
}

}

Array.prototype.foreach = function (callback) {
for (var i = 0; i < this.length; i++) {
if (this[i] !== null) callback.apply(this[i], [i])
}
}

var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};

canvas.onclick = function () {
var x = event.clientX;
var y = event.clientY;
var bigboom = new Boom(getRandom(canvas.width / 3, canvas.width * 2 / 3), 2, "#FFF", {
x: x,
y: y
});
bigbooms.push(bigboom)
}

var Boom = function (x, r, c, boomArea, shape) {
this.booms = [];
this.x = x;
this.y = (canvas.height + r);
this.r = r;
this.c = c;
this.shape = shape || false;
this.boomArea = boomArea;
this.theta = 0;
this.dead = false;
this.ba = parseInt(getRandom(80, 200));
}
Boom.prototype = {
_paint: function () {
ctx.save();
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.c;
ctx.fill();
ctx.restore();
},
_move: function () {
var dx = this.boomArea.x - this.x,
dy = this.boomArea.y - this.y;
this.x = this.x + dx * 0.01;
this.y = this.y + dy * 0.01;

    if (Math.abs(dx) <= this.ba && Math.abs(dy) <= this.ba) {
        if (this.shape) {
            this._shapBoom();
        } else this._boom();
        this.dead = true;
    } else {
        this._paint();
    }
},
_drawLight: function () {
    ctx.save();
    ctx.fillStyle = "rgba(255,228,150,0.3)";
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r + 3 * Math.random() + 1, 0, 2 * Math.PI);
    ctx.fill();
    ctx.restore();
},
_boom: function () {
    var fragNum = getRandom(30, 200);
    var style = getRandom(0, 10) >= 5 ? 1 : 2;
    var color;
    if (style === 1) {
        color = {
            a: parseInt(getRandom(128, 255)),
            b: parseInt(getRandom(128, 255)),
            c: parseInt(getRandom(128, 255))
        }
    }

    var fanwei = parseInt(getRandom(300, 400));
    for (var i = 0; i < fragNum; i++) {
        if (style === 2) {
            color = {
                a: parseInt(getRandom(128, 255)),
                b: parseInt(getRandom(128, 255)),
                c: parseInt(getRandom(128, 255))
            }
        }
        var a = getRandom(-Math.PI, Math.PI);
        var x = getRandom(0, fanwei) * Math.cos(a) + this.x;
        var y = getRandom(0, fanwei) * Math.sin(a) + this.y;
        var radius = getRandom(0, 2)
        var frag = new Frag(this.x, this.y, radius, color, x, y);
        this.booms.push(frag);
    }
},
_shapBoom: function () {
    var that = this;
    putValue(ocas, octx, this.shape, 5, function (dots) {
        var dx = canvas.width / 2 - that.x;
        var dy = canvas.height / 2 - that.y;
        for (var i = 0; i < dots.length; i++) {
            color = {
                a: dots[i].a,
                b: dots[i].b,
                c: dots[i].c
            }
            var x = dots[i].x;
            var y = dots[i].y;
            var radius = 1;
            var frag = new Frag(that.x, that.y, radius, color, x - dx, y - dy);
            that.booms.push(frag);
        }
    })
}

}

function putValue(canvas, context, ele, dr, callback) {
context.clearRect(0, 0, canvas.width, canvas.height);
var img = new Image();
if (ele.innerHTML.indexOf("img") >= 0) {
img.src = ele.getElementsByTagName("img")[0].src;
imgload(img, function () {
context.drawImage(img, canvas.width / 2 - img.width / 2, canvas.height / 2 - img.width / 2);
dots = getimgData(canvas, context, dr);
callback(dots);
})
} else {
var text = ele.innerHTML;
context.save();
var fontSize = 200;
context.font = fontSize + "px 宋体 bold";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillStyle = "rgba(" + parseInt(getRandom(128, 255)) + "," + parseInt(getRandom(128, 255)) + "," +
parseInt(getRandom(128, 255)) + " , 1)";
context.fillText(text, canvas.width / 2, canvas.height / 2);
context.restore();
dots = getimgData(canvas, context, dr);
callback(dots);
}
}

function imgload(img, callback) {
if (img.complete) {
callback.call(img);
} else {
img.onload = function () {
callback.call(this);
}
}
}

function getimgData(canvas, context, dr) {
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
var dots = [];
for (var x = 0; x < imgData.width; x += dr) {
for (var y = 0; y < imgData.height; y += dr) {
var i = (y * imgData.width + x) * 4;
if (imgData.data[i + 3] > 128) {
var dot = {
x: x,
y: y,
a: imgData.data[i],
b: imgData.data[i + 1],
c: imgData.data[i + 2]
};
dots.push(dot);
}
}
}
return dots;
}

function getRandom(a, b) {
return Math.random() * (b - a) + a;
}

var maxRadius = 1,
stars = [];

function drawBg() {
for (var i = 0; i < 100; i++) {
var r = Math.random() * maxRadius;
var x = Math.random() * canvas.width;
var y = Math.random() * 2 * canvas.height - canvas.height;
var star = new Star(x, y, r);
stars.push(star);
star.paint()
}

}

var Star = function (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
Star.prototype = {
paint: function () {
ctx.save();
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255,255,255," + this.r + ")";
ctx.fill();
ctx.restore();
}
}

var focallength = 250;
var Frag = function (centerX, centerY, radius, color, tx, ty) {
this.tx = tx;
this.ty = ty;
this.x = centerX;
this.y = centerY;
this.dead = false;
this.centerX = centerX;
this.centerY = centerY;
this.radius = radius;
this.color = color;
}

Frag.prototype = {
paint: function () {
ctx.save();
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(" + this.color.a + "," + this.color.b + "," + this.color.c + ",1)";
ctx.fill()
ctx.restore();
},
moveTo: function (index) {
this.ty = this.ty + 0.3;
var dx = this.tx - this.x,
dy = this.ty - this.y;
this.x = Math.abs(dx) < 0.1 ? this.tx : (this.x + dx * 0.1);
this.y = Math.abs(dy) < 0.1 ? this.ty : (this.y + dy * 0.1);
if (dx === 0 && Math.abs(dy) <= 80) {
this.dead = true;
}
this.paint();
}
}


<h2>总结</h2>
几种不同canvas实现烟花动画,基本分为烟火类和碎屑类展现烟花的不同状态。
同时,祝大家新年快乐!

<p class="source">原文地址:<a href="http://www.bestvist.com/2018/01/15/canvas-fireworks/" rel="noopener" target="_blank">http://www.bestvist.com/2018/01/15/canvas-fireworks/</a></p>

以上是关于canvas烟花锦集的主要内容,如果未能解决你的问题,请参考以下文章

Canvas 烟花合集 -- 将粉丝头像做成烟花在天空绽放✨

Canvas 烟花合集 -- 将粉丝头像做成烟花在天空绽放✨

html5 canvas带音效的新年烟花特效,真的好看极了

前端:运用canvas标签绘制烟花,提前祝大家新年快乐

html5 canvas带音效的新年烟花特效,真的好看极了

html5 canvas带音效的新年烟花特效,真的好看极了