js高级部分实现烟花动画

window.requestAnimationFrame=(function (){
    return window.requestAnimationFrame ||
            window.webkitrequestAnimationFrame ||                                    //浏览器兼容性
            window.mozRequestAnimationFrame ||
            function (callback){
                window.setTimeout(callback,10);
            }
})();

var canvas=document.getElementById("can_txt");                                  //设置宽和高
canvas.width=document.documentElement.clientWidth;
canvas.height=document.documentElement.clientHeight;
cw=document.documentElement.clientWidth;
ch=document.documentElement.clientHeight;
//转化2d模型
var ctx=canvas.getContext("2d");
//烟花数组
var firework=[];
//烟花碎片数组
var particles=[];
var hue=50;//颜色的色调
timerTick = 0;
timerTotal=20;
//随机min max之间的随机值
function random(min,max){
    return Math.random()*(max-min)+min;
}
//计算两点之间的距离
function distances(sx,sy,tx,ty){
    var xdistances=sx-tx;
    var ydistances=sy-ty;
    return Math.sqrt(Math.pow(xdistances,2)+Math.pow(ydistances,2));
}

//定义烟花对象
/*sx,sy  初始坐标  ,tx,ty 目标坐标*/
function Firework(sx,sy,tx,ty){
    this.x=sx;
    this.y=sy;
    this.sx=sx;
    this.sy=sy;
    this.tx=tx;
    this.ty=ty;
    //计算两点之间的距离
    this.targetDistances=distances(sx,sy,tx,ty);
    //运行距离
    this.distancesY=0;
    //定义运动轨迹
    this.guiji=[];
    this.guijicount=3;
    while(this.guijicount--){
        this.guiji.push([this.x,this.y]);
    }
    //设置相关属性
    //计算角度
    this.angle=Math.atan2(ty-sy,tx-sx);
    //计算速度
    this.speed=2;
    //计算加速度
    this.a=1.05;
    //透明度
    this.brightness=random(50,70);
    //目标圆的半径
    this.targetRad=5;
}
//开始更新烟花的位置
Firework.prototype.update=function (index){
    this.guiji.pop();
    this.guiji.push([this.x,this.y]);
    //目标圆运动(由小变大的过程)
    if(this.targetRad<8)
    {
        this.targetRad+=0.3;
    }
    else{
        this.targetRad=1;
    }
    //根据加速度计算速度
    this.speed*=this.a;
    var vx=Math.cos(this.angle)*this.speed;//x方向的速度
    var vy=Math.sin(this.angle)*this.speed;//y方向的速度
    //重新计算之间的距离
    this.distancesY=distances(this.sx,this.sy,this.x+vx,this.y+vy);
    //判断是否到达目标位置
    if(this.distancesY>=this.targetDistances)
    {
        createParticles(this.tx, this.ty);(实现烟花爆炸的关键)
        firework.splice(index,1);//烟花上升结束并消失
    }
    else{
        this.x+=vx;
        this.y+=vy;//烟花继续上升
    }

}
//开始画烟花上升运行轨迹
Firework.prototype.draw=function (){
    ctx.beginPath();
    ctx.moveTo(this.guiji[this.guiji.length-1][0],this.guiji[this.guiji.length-1][1]);
    ctx.lineTo(this.x,this.y);
    ctx.strokeStyle='hsl(' + hue + ',100%,' + this.brightness + '%)';hsl值
    ctx.stroke();
    //画出目标位置小圆
    ctx.beginPath();
    ctx.arc(this.tx,this.ty,this.targetRad,0,Math.PI*2);
    ctx.stroke();
}
//烟花爆炸
function Particle(x, y) {
    this.x = x;
    this.y = y;
    this.guiji = [];
    this.guijicount = 10;
    while (this.guijicount--) {
        this.guiji.push([this.x, this.y]);
    }
    //生成任意方向的碎屑
    this.angle = random(0, 2 * Math.PI);
    this.speed = random(2, 10);//随机速度
    this.friction = 0.95;//摩擦力
    this.gravity = 1;//重力
    this.hue = random(hue - 20, hue + 20);//生成色彩相近的碎屑
    this.brightness = random(50, 80);//随机透明
    this.alpha = 1;//初始化透明度
    this.decay = random(0.015, 0.03);//碎屑消失时间
}

Particle.prototype.update = function (index) {
    this.guiji.pop();
    this.guiji.unshift([this.x, this.y]);
    this.speed *= this.friction;
    this.x += Math.cos(this.angle) * this.speed;
    this.y += Math.sin(this.angle) * this.speed + this.gravity;
    this.alpha -= this.decay;
    if (this.alpha <= this.decay) {
        particles.splice(index, 1);
    }
}
//画碎屑轨迹
Particle.prototype.draw = function () {
    ctx.beginPath();
    ctx.moveTo(this.guiji[this.guiji.length - 1][0], this.guiji[this.guiji.length - 1][1]);
    ctx.lineTo(this.x, this.y);
    ctx.strokeStyle = 'hsla(' + this.hue + ',100%,' + this.brightness + '%,' + this.alpha + ')';
    ctx.stroke();
}
function createParticles(x, y) {
    //生成300个烟花碎屑
    var particleCount = 300;
    while (particleCount--) {
        particles.push(new Particle(x, y));
    }
}
function loop() {
    requestAnimationFrame(loop);
    hue += 0.5;
    ctx.globalCompositeOperation = 'destination-out';//修改源图  当前绘制的显示  源图隐藏
    ctx.fillRect(0, 0, cw, ch);
    ctx.globalCompositeOperation = 'lighter';
    var i = firework.length;
    while (i--) {
        firework[i].draw();
        firework[i].update(i);
    }
    var i = particles.length;
    while (i--) {
        particles[i].draw();
        particles[i].update(i);
    }
    if (timerTick >= timerTotal) {
        //创建烟花对象
        firework.push(new Firework(cw / 2, ch, random(0, cw), random(0, ch)));
        timerTick = 0;//当前时间
    }
    else {
        timerTick++;
    }
}
    window.onload = loop();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值