requestAnimationFrame原理及实战粒子特效(一)

在Web开发中,创建平滑且高效的动画是一项常见的需求。requestAnimationFrame API 提供了一种优化动画渲染的方法,它能确保动画与浏览器的刷新率同步,从而提高性能和用户体验。本文将详细介绍 requestAnimationFrame 的工作原理、使用方法及实际应用案例,帮助你更好地掌握这一关键技术。

1. requestAnimationFrame 的原理

requestAnimationFrame 是一种用于在浏览器的下一帧渲染时机执行指定函数的API。其核心优势在于能够与浏览器的刷新率同步,通常是每秒60帧(60Hz),从而确保动画的流畅性和效率。当调用 requestAnimationFrame(callback) 时,浏览器会在下一次重绘之前调用 callback 函数。如果浏览器处于空闲状态或标签页不在活动窗口中,requestAnimationFrame 会自动调整调用频率以节省资源。

2. 使用 requestAnimationFrame

requestAnimationFrame 接受一个函数作为参数,该函数将在下一帧渲染前被调用。函数内部可以访问一个可选的时间戳参数,表示从页面加载开始到现在的时间(以毫秒为单位)。

javascript// 调用 requestAnimationFrame
requestAnimationFrame(function(timestamp) {
    // 在这里编写动画逻辑
});
3. 实战案例:粒子系统动画

让我们通过创建一个粒子系统动画来深入理解 requestAnimationFrame 的使用。

html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Particle Animation with requestAnimationFrame</title>
<style>
    canvas {
        display: block;
        margin: auto;
        background: #222;
    }
</style>
</head>
<body>
<canvas id="particleCanvas"></canvas>
<script>
    // 获取 canvas 元素和 2D 上下文
    const canvas = document.getElementById('particleCanvas');
    const ctx = canvas.getContext('2d');

    // 初始化画布尺寸
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 粒子类定义
    class Particle {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.size = Math.random() * 10 + 5;
            this.speedX = (Math.random() - 0.5) * 10;
            this.speedY = (Math.random() - 0.5) * 10;
        }

        update() {
            // 更新粒子位置
            this.x += this.speedX;
            this.y += this.speedY;

            // 边界反弹
            if (this.x > canvas.width || this.x < 0) this.speedX *= -1;
            if (this.y > canvas.height || this.y < 0) this.speedY *= -1;
        }

        draw() {
            // 绘制粒子
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
            ctx.fill();
        }
    }

    let particles = [];
    let requestId;

    // 初始化粒子
    function init() {
        for (let i = 0; i < 100; i++) {
            particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height));
        }
    }

    // 动画循环
    function drawParticles() {
        // 清除画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // 更新并绘制所有粒子
        particles.forEach(particle => {
            particle.update();
            particle.draw();
        });

        // 请求下一帧
        requestId = requestAnimationFrame(drawParticles);
    }

    // 启动动画
    init();
    drawParticles();

    // 示例:添加按钮来控制动画
    const toggleButton = document.createElement('button');
    toggleButton.textContent = "Stop Animation";
    document.body.appendChild(toggleButton);

    toggleButton.addEventListener('click', () => {
        if (requestId) {
            // 取消动画
            cancelAnimationFrame(requestId);
            toggleButton.textContent = "Start Animation";
            requestId = null;
        } else {
            // 重新开始动画
            requestId = requestAnimationFrame(drawParticles);
            toggleButton.textContent = "Stop Animation";
        }
    });
</script>
</body>
</html>

效果如下:
在这里插入图片描述

  • 16
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的粒子特效的HTML代码示例,使用Canvas和JavaScript实现: ```html <!DOCTYPE html> <html> <head> <title>粒子特效</title> <style type="text/css"> canvas{ border: 1px solid black; } </style> </head> <body> <canvas id="canvas" width="500" height="500"></canvas> <script type="text/javascript"> // 获取画布对象 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // 创建粒子对象 var particles = []; for(var i=0; i<100; i++){ particles.push({ x: Math.random()*canvas.width, y: Math.random()*canvas.height, radius: Math.random()*5+1, color: "rgb("+parseInt(Math.random()*255, 10)+","+parseInt(Math.random()*255, 10)+","+parseInt(Math.random()*255, 10)+")", speedX: Math.random()*3-1.5, speedY: Math.random()*3-1.5 }); } // 绘制粒子 function draw(){ ctx.clearRect(0, 0, canvas.width, canvas.height); for(var i=0; i<particles.length; i++){ var p = particles[i]; ctx.beginPath(); ctx.arc(p.x, p.y, p.radius, 0, Math.PI*2, false); ctx.fillStyle = p.color; ctx.fill(); p.x += p.speedX; p.y += p.speedY; if(p.x < -50) p.x = canvas.width+50; if(p.y < -50) p.y = canvas.height+50; if(p.x > canvas.width+50) p.x = -50; if(p.y > canvas.height+50) p.y = -50; } requestAnimationFrame(draw); } // 开始绘制 draw(); </script> </body> </html> ``` 在这个示例中,我们创建了100个随机位置、大小、颜色、速度的粒子,在画布上绘制出来,并且让它们自动运动并且循环出现在画布的另一侧。你可以根据自己的需求,调整粒子的数量、大小、颜色、速度等参数,来实现不同的特效效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值