首页 > 其他分享 >从卡顿到丝滑:揭秘 requestAnimationFrame 的魔力

从卡顿到丝滑:揭秘 requestAnimationFrame 的魔力

时间:2025-01-18 23:32:33浏览次数:3  
标签:动画 const 魔力 timestamp requestAnimationFrame number startTime 从卡顿

从卡顿到丝滑:揭秘 requestAnimationFrame 的魔力

你有没有遇到过这样的场景:页面上的动画看起来不流畅,画面有时一跳一跳,甚至在你点击或滚动时也感觉迟钝。别担心,这不全是你的代码问题,而是你还没找到实现完美动画的秘密武器!今天,我们就来揭开 requestAnimationFrame 这位动画背后的“幕后英雄”的神秘面纱,让你的页面动画从卡顿到丝滑如初。


动画为何总是不流畅?

在你手动编写动画时,如果只依赖传统的 setTimeoutsetInterval,你会发现动画效果时好时坏,时常会出现掉帧、卡顿的情况。这是因为这些定时器与浏览器的刷新频率并不同步,导致每一帧的执行时间不稳定。

requestAnimationFrame 是专为解决这一问题而生的,它能确保动画的每一帧与屏幕的刷新频率保持一致,从而实现流畅、自然的动画效果。接下来,让我们一起看看它究竟是如何工作的。


requestAnimationFrame 是什么?

requestAnimationFrame 是浏览器提供的一个 API,用于在浏览器的下一个重绘之前执行动画回调函数。与传统的 setTimeoutsetInterval 不同,它与屏幕的刷新周期紧密同步,确保每秒有 60 帧的画面更新,从而大大提升动画的流畅性。

工作原理:
  • 每次调用 requestAnimationFrame(callback),浏览器会在下一次重绘前调用该回调。
  • 浏览器会自动计算每帧的执行时间,确保动画帧率的稳定性。
  • 页面不可见时,动画会自动暂停,节省资源。

动画实现:从基础到复杂

1. 让盒子动起来:简单的平移动画

const box = document.getElementById('box');
let startTime: number | null = null;

function moveBox(timestamp: number) {
    if (!startTime) startTime = timestamp;
    const progress = (timestamp - startTime) / 1000; // 1秒内完成
    box!.style.transform = `translateX(${Math.min(progress * 300, 300)}px)`;

    if (progress < 3) {
        requestAnimationFrame(moveBox);
    }
}

requestAnimationFrame(moveBox);

解释:通过 timestamp(时间戳)计算元素的运动进度,确保动画每秒有约 60 帧的更新,让动画既流畅又稳定。


2. 让运动更真实:缓动动画

线性动画虽然流畅,但缺乏自然感。使用缓动函数,你可以模拟加速或减速的效果,让动画看起来更符合物理规律。

function easeOutQuad(t: number): number {
    return t * (2 - t); // 快到慢的缓动效果
}

function easingMove(timestamp: number) {
    if (!startTime) startTime = timestamp;
    const progress = Math.min(easeOutQuad((timestamp - startTime) / 1000), 1);

    box!.style.transform = `translateX(${progress * 300}px)`;

    if (progress < 1) {
        requestAnimationFrame(easingMove);
    }
}

requestAnimationFrame(easingMove);

解释easeOutQuad 让动画从快到慢的平滑过渡,这种效果在现实世界中更常见,如物体停止时的惯性。


3. 协同运动:多元素动画

在更复杂的场景中,你可能需要多个元素协同工作,例如小球沿抛物线运动。

const ball = document.getElementById('ball');
let startTime: number | null = null;

function parabolaMove(timestamp: number) {
    if (!startTime) startTime = timestamp;
    const t = (timestamp - startTime) / 1000;
    const x = t * 200;  // 水平匀速移动
    const y = 100 - (t * t * 200);  // 垂直方向抛物线运动

    ball!.style.transform = `translate(${x}px, ${y}px)`;

    if (t < 2) {
        requestAnimationFrame(parabolaMove);
    }
}

requestAnimationFrame(parabolaMove);

解释:通过数学公式计算小球的抛物线轨迹,模拟更复杂的物理运动效果,适用于游戏或动画场景。


深度优化:让动画更流畅、更省资源
  1. 利用 GPU 加速:通过 transformopacity 等 CSS 属性可以让浏览器利用 GPU 渲染,从而实现更流畅的动画。
  2. 避免阻塞主线程:确保动画计算尽量简单,复杂的数学计算可以预先缓存。
  3. 资源管理:动画结束后,务必清理动画的回调函数,避免不必要的资源浪费。

总结:控制动画的每一帧

requestAnimationFrame 不仅仅是一个 API,它是 Web 动画开发的灵魂。它解决了传统动画方法的帧率不稳定、资源浪费等问题,能让你的动画如丝般顺滑。如果你还在使用 setInterval 来做动画,或许是时候尝试一下这个强大的工具了——让动画飞起来,向流畅的 Web 动画世界迈进!

标签:动画,const,魔力,timestamp,requestAnimationFrame,number,startTime,从卡顿
From: https://blog.csdn.net/weixin_62520914/article/details/145234676

相关文章

  • Agentforce 2.0究竟有什么魔力,Salesforce要做数字领军者?
     2024年12月17日,全球科技巨头Salesforce正式推出其全新平台——Agentforce2.0。首席执行官马克·贝尼奥夫在发布会上宣布,Salesforce计划招聘2000名销售人员,以加速推广这一重大人工智能平台,并预计于2025年2月正式向全球企业提供服务。 Agentforce自今年9月首次亮相以来,便迅......
  • requestAnimationFrame是宏任务还是微任务?为什么?
    requestAnimationFrame既不是宏任务(macro-task)也不是微任务(micro-task),但它通常被视为一个特殊的“宏任务”。以下是对这一观点的详细解释:定义与特性:宏任务:在JavaScript的事件循环中,宏任务包括整体代码script、setTimeout、setInterval、I/O、UI渲染等。它们会在每个事件循环......
  • Object.freeze冻结属性和v-if结合requestAnimationFrame分帧渲染解决白屏
    计算100W条数据的长度造成2s延迟<template><div><h1>数据总长度{{arrList.length}}</h1></div></template><script>exportdefault{data(){return{arrList:[]}},created(){cons......
  • 解锁 Java 解释器模式:赋予程序理解 “新语言” 的魔力
    解锁Java解释器模式:赋予程序理解“新语言”的魔力在Java编程的广袤天地中,我们时常面临需要处理自定义规则、语法或逻辑表达式的场景。此时,解释器模式(InterpreterPattern)宛如一位神奇的翻译官,能够将这些看似晦涩难懂的“新语言”,转化为计算机能够理解并执行的指令,为......
  • 还在使用定时器吗?试试requestAnimationFrame
    目录基本认识简介停止自动停止手动停止使用场景js动画前言:相信能点进来看我博客的小伙子们,应该都是前端吧。那想必是知道定时器或者requestAnimationFrame 吧。这里说的重点呢就是 requestAnimationFrame。如果你对它并不了解,那我下文中也会对它进行补充说明的。......
  • 解锁 JavaScript 魔力:不容错过的代码小妙招(一)
    JavaScript开发小技巧:编程魔法大揭秘......
  • 解锁 JavaScript 魔力:不容错过的代码小妙招(二)
    嘿,各位编程大侠们!在上一篇《解锁JavaScript魔力:不容错过的代码小妙招(一)》中,我们一同领略了JavaScript世界里部分神奇小妙招的魅力。现在,让我们继续这场充满惊喜的编程之旅,探索更多能让你的代码如魔法般酷炫的小技巧。......
  • 你有用过HTML5的requestAnimationFrame吗?它运用的场景有哪些呢?
    是的,我了解HTML5的requestAnimationFrameAPI。它主要用于创建流畅的网页动画和视觉效果。与setTimeout或setInterval相比,requestAnimationFrame有几个关键优势,使其成为执行动画的首选方法:requestAnimationFrame的优势:浏览器优化:requestAnimationFrame由浏览器优......
  • 魔力宝贝6.0+单机版安装教程+无需虚拟机
    今天给大家带来一款单机游戏的架设:魔力宝贝6.0。官方任务无任何bug优化的很完美,添加了半山系列;系列系列;砍狗系列;暗流系列;炼金系列等。另外:本人承接各种游戏架设(单机+联网)本人为了学习和研究软件内含的设计思想和原理,带了架设教程仅供娱乐。教程是本人亲自搭建成功的,绝对是完整......
  • 数据飞轮的魔力:如何在文娱行业激活数据中台
    在数据驱动的时代,文娱行业尤其见证了数据技术的短板与潜力。从流媒体的智能推荐到广告监测,再到用户行为分析,每一步都离不开高效、精准的数据处理。本文将探讨数据飞轮如何在文娱行业中“唤醒”数据,让数据中台不仅仅是一个数据集散地,而是一个充满活力的策略核心。数据中台的转变与......