canvas拖尾效果

本文详细介绍了如何利用HTML5的canvas元素来实现粒子的动态拖尾效果,包括粒子生成、运动轨迹记录以及拖尾绘制等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

canvas实现粒子的拖尾效果

/**
 * @Author   SuZhe
 * @DateTime 2019-03-15
 * @desc     兼容 requestAnimFrame
 * @return   {[Function]}    requestAnimFrame不兼容的浏览器使用定时器代替
 */
window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame       ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        function( callback ){
          window.setTimeout(callback, 1000 / 60);
        };
})();

/**
* @Author   SuZhe
* @DateTime 2019-03-15
* @desc     椭圆动画效果  star运动
* @param    {[Object]}   canvasId [画布布id]
*/
function CanvasAnimation(param){
    if(param.ele){
        this.canvas = param.ele;
        this.cxt = this.canvas.getContext('2d');
        this.param = param;
        if(param.type){
            //star
            this.starArr = [[],[],[],[]];  //star数量集合
            this.step = [80,-40,40,260];  //步长位置集合
            this.color = ['230,116,182','80,238,207','235,149,89','68,192,240']; //颜色集合
        }else{
            // arc
            this.a = 168; //长 半 径
            this.b = 53;  //短 半 径
            this.posi = []; //位置集合
            this.posiNext = [];
            this.radius = 2;
            this.time = 0; //步长
        }
        this.animation();
    }
}
CanvasAnimation.prototype = {
    animation: function(){
        var that = this;
        if(this.param.type){
            //star
            this.starAni();
        }else{
            //arc
            this.draw();
            this.drawNext();
        }
        window.requestAnimFrame(function(){
          that.animation();
        });
    },
    draw: function(){
        var y = 56,
        posi = this.posi;
        this.cxt.clearRect(0,0,340,160);
        this.trail(y,posi);
        this.time+=0.02;
    },
    drawNext: function(){
        var y = 106,
        posi = this.posiNext;
        this.trail(y,posi,true);
    },
    trail: function(y,posi,next){
        var context = this.cxt,
            x = 170,a,b,
            param = {};
        if(next){
            a = -this.a;
            b = -this.b;
        }else{
            a = this.a;
            b = this.b;
        }
        //圆弧坐标
        param.arcX = x + a*Math.cos(this.time),
        param.arcY = y + b*Math.sin(this.time);
        posi.push(param);
        if(posi.length > 25){
            posi.shift();
        }
        for(var i = 0, len = posi.length; i < len; i++){
            var alphar = 1;
            if(i < len-1){
                alphar = i/30;
            }
            if(next){
                context.fillStyle="rgba(255, 204, 0, "+alphar+")";
            }else{
                context.fillStyle="rgba(0, 246, 255, "+alphar+")";
            }
            context.beginPath();
            context.arc(posi[i].arcX,posi[i].arcY,this.radius,0,2*Math.PI);
            context.closePath();
            context.fill();
        }
    },
    starAni: function(){
        var context = this.cxt,
        posi = this.starArr,
        starNum = [{},{},{},{}];
        context.clearRect(0,0,700,462);
        for(var k = 0, lens = starNum.length; k < lens; k++){
            starNum[k].x = 90 * k * 2 + 40;
            starNum[k].y = 462 - this.step[k];
            if(starNum[k].y < 0){
              this.step[k] = 0;
            }
            posi[k].push(starNum[k]);
            if(posi[k].length > 45){
                posi[k].shift();
            }
            for(var j = 0, len = posi[k].length; j < len; j++){
                var alphar = 1,
                    redius = 2.5;
                if(j < len - 1){
                    alphar = j/50;
                    redius = j/48 *2 ;
                }
                if(j == len-1){
                    context.shadowOffsetY=-2;
                    context.shadowOffsetX=0;
                    context.shadowBlur=10;
                    context.shadowColor="rgb("+this.color[k]+")";
                }
                context.fillStyle="rgba("+this.color[k]+", "+alphar+")";
                context.beginPath();
                context.arc(posi[k][j].x,posi[k][j].y,redius,0,2*Math.PI);
                context.closePath();
                context.fill();
            }
            this.step[k] += 2;
        }
    }
}
<canvas class="canvas" width="340" height="160"></canvas>
	var arc = new CanvasAnimation({
        	ele:document.getElementsByClassName('canvas')[0]
        });
<canvas class="canvasStar" width="700" height="462"></canvas>
 var star = new CanvasAnimation({
 	ele: document.getElementsByClassName('canvasStar')[0],
 	type: 'star'
 });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值