有你的地方就是年——请查收你的春节烟花(零点定时跳转)
“ PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛”
新年快乐
现在各地纷纷出台政策禁止燃放烟花爆竹,过年确实平白少了很多乐趣。虽然自己已经长大,很多小时候的热爱都已经不再喜欢,但是年底家家户户燃放的烟花,依然是对年味最初的执念。🏮🏮🏮
这种酸酸地不可言说的感情,应该就叫情怀吧。
情感总是我们心中最柔软的地方。这一年,我们依旧忙碌,依旧为生活焦头烂额。断断续续的疫情可能让你的团聚进退两难,虽然不在彼此身边,但是这份新年烟花送去的不仅仅是几秒钟的绚烂,更传递着你我的思念
综述🔦
定时烟花实现一共分为三部分
-
第一部分是初始化显示的一个html页面,显示自定义祝愿文字或者悄悄话,鼠标滑动轨迹生成爱心;
-
第二部分是定时器功能,实现定时跳转到烟花绽放页面;
-
第三部分是烟花绽放页面,烟花绽放;✨
第一部分:canvas实现爱心轨迹
要在画板上画画,第一步肯定是要有一块画板的吧
//html
<canvas></canvas>
//js
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
然后构思画的尺寸,选一块合适大小的画布
var ww,wh;
function onResize(){
// windows窗口的大小
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
}
准备一下作画用的颜料,红黄蓝?
ctx.strokeStyle = "red";
ctx.shadowBlur = 25;
// 色相,饱和度,亮度,透明度
ctx.shadowColor = "hsla(0, 100%, 60%,0.5)";
// https://www.w3schools.com/html/html_colors.asp 这里有关于css中关于颜色的不同定义方法
构思一下到底画一些什么,画多少合适
var Heart = function(x,y){
this.x = x || Math.random()*ww;
this.y = y || Math.random()*wh;
this.size = Math.random()*2 + 1;
// 阴影模糊度
this.shadowBlur = Math.random() * 10;
// 速度
this.speedX = (Math.random()+0.2-0.6) * 8;
this.speedY = (Math.random()+0.2-0.6) * 8;
this.speedSize = Math.random()*0.05 + 0.01;
this.opacity = 1;
this.vertices = [];
for (var i = 0; i < precision; i++) {
var step = (i / precision - 0.5) * (Math.PI * 2);
// 使用心型方程式绘制爱心
var vector = {
x : (16 * Math.pow(Math.sin(step), 3)),
y : -(13 * Math.cos(step) - 5 * Math.cos(2 * step) - 2 * Math.cos(3 * step) - Math.cos(4 * step))
}
this.vertices.push(vector);
}
}
心型公式
构思好了是不是要琢磨一下使用一些什么绘画手法呢
Heart.prototype.draw = function(){
this.size -= this.speedSize;
this.x += this.speedX;
this.y += this.speedY;
// 把当前状态(旋转,缩放,颜色等)的一份拷贝压入到一个保存图像状态的栈中
ctx.save();
// 重新定义画布(0,0)点的位置,之后绘制的图形都基于该点为(0,0)点进行绘制
ctx.translate(-1000,this.y);
// 缩放
ctx.scale(this.size, this.size);
ctx.beginPath();
for (var i = 0; i < precision; i++) {
var vector = this.vertices[i];
ctx.lineTo(vector.x, vector.y);
}
ctx.globalAlpha = this.size;
ctx.shadowBlur = Math.round((3 - this.size) * 10);
ctx.shadowColor = "hsla(0, 100%, 60%,0.5)";
// 设置阴影距形状的水平距离
ctx.shadowOffsetX = this.x + 1000;
ctx.globalCompositeOperation = "screen"
//结束绘制
ctx.closePath();
//填充轮廓
ctx.fill()
// 上面临时地改变图像状态后, restore()可以恢复以前的值。
// 也就是爱心消失后,再次绘制时直接使用上次保存的状态绘制爱心
ctx.restore();
};
现在准备工作都做好了,请开始你的表演
function render(a){
requestAnimationFrame(render);
hearts.push(new Heart())
ctx.clearRect(0,0,ww,wh);
for (var i = 0; i < hearts.length; i++) {
hearts[i].draw();
if(hearts[i].size <= 0){
hearts.splice(i,1);
i--;
}
}
}
onResize();
window.addEventListener("mousemove", onMove);
window.addEventListener("touchmove", onMove);
// 缩放窗口时调用
window.addEventListener("resize", onResize);
// 每刷新一次调用一次
requestAnimationFrame(render);
第二部分:定时跳转
定时跳转大概原理就是通过new date获取时间戳,将定时器时间设为未来时间和现在时间的差值,当两者时间相等时,实现跳转效果。
//页面加载便调用
window.onload=function starttime(){
time(h1,'2022/1/29'); // 2021年春节时间
ptimer = setTimeout(starttime,1000); // 添加计时器
}
function time(obj,futimg){
var nowtime = new Date().getTime() + 1900000; // 现在时间转换为时间戳
var futruetime = new Date(futimg).getTime(); // 未来时间转换为时间戳
// 1643385600000
// console.log(nowtime,'-------',futruetime)
var msec = futruetime-nowtime; // 毫秒 未来时间-现在时间
// 定时跳转
setTimeout("javascript:location.href='demo.html'", msec);
var time = (msec/1000); // 毫秒/1000
var day = parseInt(time/86400); // 天 24*60*60*1000
var hour = parseInt(time/3600)-24*day; // 小时 60*60 总小时数-过去的小时数=现在的小时数
var minute = parseInt(time%3600/60); // 分 -(day*24) 以60秒为一整份 取余 剩下秒数 秒数/60 就是分钟数
var second = parseInt(time%60); // 以60秒为一整份 取余 剩下秒数
obj.innerHTML="<p2>小王新年快乐<br>I can never let you go<br></p2>"+"<span>距离2022年还有:<span><br>"+day+"天"+hour+"小时"+minute+"分"+second+"秒"+"<br>"
return true;
}
第三部分:烟花效果
这里实现烟花效果过程中使用到了jquery,所以需要先引入
<body>
<div class="demo">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script src="index.js"></script>
<script>
$('.demo').fireworks({
sound: true,
opacity: 0.8,
width: '100%',
height: '100%'
});
</script>
</body>
创建烟花效果的画布
var canvas = document.createElement('canvas');
canvas.id = 'fireworksField';
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
canvas.style.width = SCREEN_WIDTH + 'px';
canvas.style.height = SCREEN_HEIGHT + 'px';
canvas.style.position = 'absolute';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.opacity = options.opacity;
var context = canvas.getContext('2d');
定义烟花粒子基础属性
function Particle(pos) {
this.pos = {
x: pos ? pos.x : 0,
y: pos ? pos.y : 0
};
this.vel = {
x: 0,
y: 0
};
this.shrink = 0.97;
this.size = 2;
this.resistance = 1;
this.gravity = 0;
this.flick = false;
this.alpha = 1;
this.fade = 0;
this.color = 0;
}
定义烟花粒子下落时属性的变化
Particle.prototype.update = function() {
// apply
this.vel.x *= this.resistance;
this.vel.y *= this.resistance;
// 根据重力下降
this.vel.y += this.gravity;
// 根据速度更新位置
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
// 下落时变小
this.size *= this.shrink;
// 淡出
this.alpha -= this.fade;
};
生成烟花粒子
Particle.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
gradient.addColorStop(0.1, "rgba(255,255,255," + this.alpha + ")");
gradient.addColorStop(0.8, "hsla(" + this.color + ", 100%, 50%, " + this.alpha + ")");
gradient.addColorStop(1, "hsla(" + this.color + ", 100%, 50%, 0.1)");
c.fillStyle = gradient;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
实现爆炸效果
Rocket.prototype.explode = function() {
if (options.sound) {
var randomNumber = function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}(0, 2);
audio.src = sounds[randomNumber].prefix + sounds[randomNumber].data;
audio.play();
}
var count = Math.random() * 10 + 80;
for (var i = 0; i < count; i++) {
var particle = new Particle(this.pos);
var angle = Math.random() * Math.PI * 2;
// emulate 3D effect by using cosine and put more particles in the middle
var speed = Math.cos(Math.random() * Math.PI / 2) * 15;
particle.vel.x = Math.cos(angle) * speed;
particle.vel.y = Math.sin(angle) * speed;
particle.size = 10;
particle.gravity = 0.2;
particle.resistance = 0.92;
particle.shrink = Math.random() * 0.05 + 0.93;
particle.flick = true;
particle.color = this.explosionColor;
particles.push(particle);
}
};
源码链接,github.com/ahua-GitHub…,记得帮点亮⭐⭐和💖💖
转载自:https://juejin.cn/post/7058287374219870222