用canvas做粒子组成的动画

一般来说,用canvas做粒子都要经过几个步骤

1 先初始化画布的大小,画布的环境

2 计算好各个点对象的位置,半径大小,颜色

3 清空画布

4将所有的粒子对象画在指定的位置

5循环到步骤2


粒子中,静态的用粒子组成一条抛物线

在这个例子中,咱们定义的画布大小等于屏幕大小,所以写了一个函数来返回屏幕的高度和宽度:

var  Utils={
            getWindowSize: function() {
                return {
                    width: this.getWindowWidth(),
                    height: this.getWindowHeight()
                };
            },
            getWindowWidth: function() {
                //浏览器的兼容
                return window.innerWidth || document.documentElement.clientWidth;
            },
            getWindowHeight: function() {
                //浏览器的兼容
                return window.innerHeight || document.documentElement.clientHeight;
            }
        };

通过调用上面的函数,咱们来对画布的环境进行初始化:

init:function () {
                var windowSize = Utils.getWindowSize();  // 获取窗口大小
                this.canvas = document.getElementById('canvas');
                this.ctx = this.canvas.getContext('2d');
                if(this.ctx) {

                    // 设置canvas的宽高
                    this.canvas.width = windowSize.width;
                    this.canvas.height = windowSize.height;
                    //粒子的个数,也是x值
                    var times = 100;
                    var tem;
                    this.particles = [];
                    while(times--) {
                        tem=times*times/30;
                        this.particles.push(new Particle({
                            //粒子对象集合
                            x: times,
                            y: tem,
                            color: 'black',
                            scale: 1,
                            radius: 3
                        }));
                    }
                }

            },

    在上面函数里,我们已经得出了粒子集合的位置,大小,颜色,所以只要将他们画在正确的位置即可,为此,我们用组合构造对象模式来构造了粒子对象,用粒子对象的原型函数来实现画粒子:

function Particle(infor) {
            this.x=infor.x;
            this.y=infor.y;
            this.color=infor.color;
            this.scale=infor.scale;
            this.radius=infor.radius;
        }
        if(typeof Particle.prototype.draw==='undefined'){
            Particle.prototype.draw = function(ctx){
                ctx.beginPath();
                ctx.fillStyle=this.color;
                ctx.strokeStyle=this.color;
                ctx.arc(this.x, this.y, this.radius * this.scale, 0, 2 * Math.PI, false);
                ctx.closePath();
                ctx.fill();
            }
        }

接下来就是先清空画布,所有的粒子集合里的粒子调用粒子对象的原型函数:


draw: function() {

                var _this = this;
                // 每次重新绘制之前,需要先清空画布,把上一次的内容清空
                var windowSize = Utils.getWindowSize();
                this.ctx.clearRect(0, 0, windowSize.width, windowSize.height);
                // 绘制粒子

                this.particles.forEach(function (item) {
                    item.draw(_this.ctx);
                });
            }

然后让window.onload调用初始化函数和上面的函数,就能画出一条模拟抛物线的曲线:

window.οnlοad=function () {
            ParticleEffect.init();
            ParticleEffect.draw();
        }

整个代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>努力画一条抛物线</title>
</head>
<body>
    <canvas id="canvas">
        <p>
            你的浏览器不让我画画
        </p>
    </canvas>
    <script>
        function Particle(infor) {
            this.x=infor.x;
            this.y=infor.y;
            this.color=infor.color;
            this.scale=infor.scale;
            this.radius=infor.radius;
        }
        if(typeof Particle.prototype.draw==='undefined'){
            Particle.prototype.draw = function(ctx){
                ctx.beginPath();
                ctx.fillStyle=this.color;
                ctx.strokeStyle=this.color;
                ctx.arc(this.x, this.y, this.radius * this.scale, 0, 2 * Math.PI, false);
                ctx.closePath();
                ctx.fill();
            }
        }
        var  Utils={
            getWindowSize: function() {
                return {
                    width: this.getWindowWidth(),
                    height: this.getWindowHeight()
                };
            },
            getWindowWidth: function() {
                //浏览器的兼容
                return window.innerWidth || document.documentElement.clientWidth;
            },
            getWindowHeight: function() {
                //浏览器的兼容
                return window.innerHeight || document.documentElement.clientHeight;
            }
        };
        var ParticleEffect={
            ctx:null,
            canvas: null,
            init:function () {
                var windowSize = Utils.getWindowSize();  // 获取窗口大小
                this.canvas = document.getElementById('canvas');
                this.ctx = this.canvas.getContext('2d');
                if(this.ctx) {

                    // 设置canvas的宽高
                    this.canvas.width = windowSize.width;
                    this.canvas.height = windowSize.height;
                    //粒子的个数,也是x轴
                    var times = 100;
                    var tem;
                    this.particles = [];
                    while(times--) {
                        tem=times*times/30;
                        this.particles.push(new Particle({
                            //粒子对象集合
                            x: times,
                            y: tem,
                            color: 'black',
                            scale: 1,
                            radius: 3
                        }));
                    }
                }

            },
            draw: function() {

                var _this = this;
                // 每次重新绘制之前,需要先清空画布,把上一次的内容清空
                var windowSize = Utils.getWindowSize();
                this.ctx.clearRect(0, 0, windowSize.width, windowSize.height);
                // 绘制粒子

                this.particles.forEach(function (item) {
                    item.draw(_this.ctx);
                });
            }
        }
        window.οnlοad=function () {
            ParticleEffect.init();
            ParticleEffect.draw();
        }
    </script>
</body>
</html>

要是需要粒子的随机的飘动,增加定时刷新函数,计算x方向,y方向的速度,做好临界检测即可

move:function () {
                var windowSize = Utils.getWindowSize();
                this.particles.forEach(function(item){
                    item.x += item.vx;
                    item.y += item.vy;
                    if((item.x - item.radius < 0) || (item.x + item.radius > windowSize.width)) {
                        item.vx *= -1;
                    }

                    // 如果粒子碰到了上墙壁或下墙壁,则改变粒子的纵向运动方向
                    if((item.y - item.radius < 0) || (item.y + item.radius > windowSize.height)) {
                        item.vy *= -1;
                    }
                });
            }

具体动态图请看另一篇<<用canvas和css做动态雪花和雪人>>https://mp.csdn.net/postedit/79929119

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值