canvas 梦幻的随机例子效果

本文介绍如何使用HTML5 Canvas实现动态粒子效果,包括单个及多个粒子的绘制与动画控制,解决粒子静止与反弹问题,确保动画流畅运行。

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

效果如下:

step1 绘制一个圆的动态效果


var canvas = document.getElementById('canvas1');
var context = canvas.getContext('2d'); //获取2d环境下的画布上下文(获取一个画笔)
var cX = canvas.width / 2;
var cY = canvas.height / 2;
var r = 10;

setInterval(function() {
    context.beginPath();
    cX += 2;
    cY += 2;
    context.arc(cX, cY, r, 0, 2 * Math.PI);
    context.fillStyle = 'red';
    context.fill();
}, 1000 / 20);
复制代码

以上代码存在一个问题,即画出来的圆不断生成

解决办法:在定时器代码里添加清空画布的操作

context.clearRect(0, 0, canvas.width, canvas.height);
复制代码

step2 绘制多个圆的动态效果(以下是项目的完整代码)


var canvas = document.getElementById('canvas1');
var context = canvas.getContext('2d'); //获取2d环境下的画布上下文(获取一个画笔)
var setArr = []; //存放圆形的数组
var maxNum = 30; //生成圆形数量的最大值

/*绘制随机的圆*/
var timer1 = setInterval(function() {

    /*为了控制浏览器的性能,避免圆形不断地生成,影响性能*/
    if (setArr.length > maxNum) {
        clearInterval(timer1);
    }

    var cX = 200 + Math.ceil(Math.random() * 400); //生成200-400之间圆的x坐标
    var cY = 200 + Math.ceil(Math.random() * 400); //生成200-400之间圆的y坐标
    var r = 5 + Math.ceil(Math.random() * 10);  //5-12之间圆的半径
    /*生成rgba颜色的值*/
    var red = Math.floor(Math.random() * 256); 
    var green = Math.floor(Math.random() * 256);
    var blue = Math.floor(Math.random() * 256);
    var alpha = 0.5 + Math.random() * 0.3;
    var bgColor = 'rgba(' + red + ',' + green + ',' + blue + ',' + alpha + ')';
    /*设置速度*/
    var sX = -2 + Math.ceil(Math.random() * 8);
    var sY = -2 + Math.ceil(Math.random() * 8);

    var obj = {
        cX: cX,
        cY: cY,
        r: r,
        sX: sX,
        sY: sY,
        bgColor: bgColor
    };

    /*避免出现圆形出现在原地 没有动画效果*/
    if (sX != 0 || sY != 0) {
        setArr.push(obj);
    }

}, 1000/20);

/*控制随机圆的动效 一秒钟执行60次*/
setInterval(function() {

    /*每次绘制一个圆都要清空画布,否则每个圆都会连接在一起形成直线*/
    context.clearRect(0, 0, canvas.width, canvas.height);

    for (var i = 0; i < setArr.length; i++) {

        if(setArr[i].cY + setArr[i].r >= canvas.height || setArr[i].cY - setArr[i].r <= 0){
            // 触碰上下边界
            setArr[i].sY *= -1;
        }
        if(setArr[i].cX + setArr[i].r >= canvas.width || setArr[i].cX - setArr[i].r <= 0){
            // 触碰左右边界
            setArr[i].sX *= -1;
        }

        /*绘制一个圆形*/
        setArr[i].cX += setArr[i].sX;
        setArr[i].cY += setArr[i].sY;
        context.beginPath();
        context.arc(setArr[i].cX, setArr[i].cY, setArr[i].r, 0, 2 * Math.PI);
        context.fillStyle = setArr[i].bgColor;
        context.fill();
    }

}, 1000/60);
复制代码

在开发过程中遇到的问题:

1、生成的多个粒子部分在原位不动,没有任何变化

2、粒子如何反弹?

第一个解决办法,则是当速度都不为0的时候才把粒子添加到setArr数组中

/*避免出现圆形出现在原地 没有动画效果*/
if (sX != 0 || sY != 0) {
    setArr.push(obj);
}
复制代码

第二个问题分析,如下图所示,当具有以下情况的时候进行反弹:

for (var i = 0; i < setArr.length; i++) {

    if(setArr[i].cY + setArr[i].r >= canvas.height || setArr[i].cY - setArr[i].r <= 0){
        // 触碰上下边界
        setArr[i].sY *= -1;
    }
    if(setArr[i].cX + setArr[i].r >= canvas.width || setArr[i].cX - setArr[i].r <= 0){
        // 触碰左右边界
        setArr[i].sX *= -1;
    }
}
复制代码

转载于:https://juejin.im/post/5c36e2f4f265da6142741954

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值