用requestAnimationFrame替代setInterval制作匀速动画

news2024/11/19 20:34:18

了解过事件循环机制的朋友应该知道,siteTimeoutsetInterval并不是精准的时间间隔,他们要等待其他优先的执行队列执行完成以后才能继续执行。

于是就引入了一个新的动画执行方式-- window.requestAnimationFrame()。它告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

它采用的是系统时间间隔,以保证最佳的绘制效率,不会因为时间过短造成过度绘制,也不会因为时间间隔太长,产生动画卡顿的现象。让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果

特点
requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销

应用
requestAnimationFrame的用法与settimeout很相似,只是不需要设置时间间隔而已。requestAnimationFrame使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。它返回一个整数,表示定时器的编号,这个值可以传递给cancelAnimationFrame用于取消这个函数的执行

let retID = requestAnimationFrame(callback);

取消的话可直接使用canceAnimationFrame来进行取消即可

cancelAnimationFrame(retID)

先来看个setInterval动画的例子

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

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      #box {
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
        overflow: hidden;
      }
      .item-container {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        align-items: center;
        height: 500px;
        width: 100px;
      }
      .item {
        width: 50px;
        height: 50px;
        background-color: blue;
        border-radius: 50%;
        margin-top: 10px;
        z-index: 100;
      }
      .open {
        width: 100px;
        height: 100px;
        line-height: 100px;
        text-align: center;
      }
    </style>
  </head>
  <body>
    <button id="btn1">改变高度</button>
    <div id="box">
      <div class="open">展开</div>
      <div class="item-container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
      </div>
    </div>
    <script>
      window.addEventListener("load", function (ev) {
        var box = document.getElementById("box");
        var flag = true;
        // 执行动画,改变盒子高度
        document.getElementById("btn1").addEventListener("click", function (ev) {
          if (flag) {
            buffer(box, "height", 500);
            flag = false;
          } else {
            buffer(box, "height", 100);
            flag = true;
          }
        });
      });
      // 获取当前元素样式
      function getStyleAttr(obj, attr) {
        if (obj.currentStyle) {
          // IE 和 opera
          return obj.currentStyle[attr];
        } else {
          return window.getComputedStyle(obj, null)[attr];
        }
      }
      // 迅速动画函数
      function buffer(eleObj, attr, target) {
        //1.1先清后设
        clearInterval(eleObj.timer);

        var speed = 0,
          begin = 0;
        //1.2设置定时器
        eleObj.timer = setInterval(function () {
          //获取动画属性的初始值
          begin = parseInt(getStyleAttr(eleObj, attr));

          speed = (target - begin) * 0.2;
          speed = target > begin ? Math.ceil(speed) : Math.floor(speed);

          eleObj.style[attr] = begin + speed + "px";

          if (begin === target) {
            clearInterval(eleObj.timer);
          }
        }, 20);
      }
    </script>
  </body>
</html>

requestAnimationFrame代替setInterval重写buffer函数

 // 动画函数
        buffer(eleObj, attr, target) {
            // 先清后设
            cancelAnimationFrame(eleObj.timer)
            let speed = 0
            let begin = 0
            let _this = this
            eleObj.timer = requestAnimationFrame(function fn() {
                begin = parseInt(_this.getStyleAttr(eleObj, attr))
                // 动画速度
                speed = (target - begin) * 0.9
                speed = target > begin ? Math.ceil(speed) : Math.floor(speed)
                eleObj.style[attr] = begin + speed + "px"
                eleObj.timer = requestAnimationFrame(fn)
                if (begin === target) {
                    cancelAnimationFrame(eleObj.timer);
                }
            })
        },
        getStyleAttr(obj, attr) {
            if (obj.currentStyle) {
              // IE 和 opera
              return obj.currentStyle[attr];
            } else {
              return window.getComputedStyle(obj, null)[attr];
            }
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/444621.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

少儿编程 电子学会图形化编程等级考试Scratch二级真题解析(判断题)2022年9月

2022年9月scratch编程等级考试二级真题 判断题(共10题,每题2分,共20分) 26、程序中要判断角色是否碰到舞台边缘,可以使用运动模块中的“碰到舞台边缘”积木 答案:错 考点分析:考查积木分类,碰到舞台边缘积木是侦测模块中的积木而不是运动模块中的,所以错误 27、运行…

通信原理 数字基带信号之码间串扰

通信原理 数字基带信号之码间串扰目录 1.码间串扰 2.满足无码间串扰的条件 3.例题 1.码间串扰 2.满足无码间串扰的条件 nyquist带宽 Bfnw/2Π。 nyquist速率 RB2fn &#xff08;最高码元传输速率&#xff09;。 若RB满足等于nRB‘ n&#xff1d;1、2、3、4.....时 RB’为实际…

基于mybatis的网上招聘系统源码数据库论文

目 录 摘 要 Abstract 1 绪 论 1.1 开发背景 1.2 开发意义 1.3 国内外研究现状 1.4 论文结构 2 相关技术原理和开发工具 2.1 程序语言的选择 2.1.1 Java概述 2.1.2 Java特点 2.1.3 Servlet简介 2.2 Oracle数据库 2.3 B/S模式 2.3.1 B/S架构概…

城市轨道交通的GoA

导言 目前轨道系统中最常见的便是基于通信的列车控制系统&#xff08;Communication Based Train Control, CBTC)&#xff0c;其中各集成商各条线路采用了不同级别的自动化技术&#xff0c;本文将针对CBTC的运用&#xff0c;从其系统组成、系统升级改造、系统主要功能、自动化…

SAS学习第5章:方差分析之大纲及单因素试验

t检验能用来进行两个处理平均数之间的假设检验&#xff0c;但一般研究会出现多个处理优劣的比较&#xff0c;即需要进行多个处理平均数的假设检验&#xff0c;此时t检验不再适用&#xff0c;具体表现在检验量增加&#xff0c;如k个处理&#xff0c;要进行k*(k-1)/2次检验&#…

PyTorch简介

PyTorch是由Facebook AI实验室开发的一个深度学习框架&#xff0c;旨在提供高效的GPU加速和灵活的模型定义。PyTorch已经成为了深度学习领域的标准工具之一&#xff0c;广泛应用于图像识别、自然语言处理、计算机视觉等领域。 PyTorch的发展 自2017年发布以来&#xff0c;PyT…

day18_集合

今日内容 零、 复习昨日 一、集合框架体系 二、Collection 三、泛型 四、迭代 五、List 六、ArrayList 七、LinkedList 零、 复习昨日 晨考 一、集合框架体系 数组: 是一个容器,用来存放数据的 定长只能存储同一种数据类型的数据int[] 可以存储int值,Student[] 可以存储引用类型…

知识变现海哥|不具备这三种思维,劝你别做知识变现

&#xff08;本文首发公号跟海哥学知识变现&#xff0c;移步公号与100万知识变现/知识付费创业者&#xff0c;一起学知识变现知识付费干货&#xff0c;回‘领书’获取3本电子书&#xff1a;【知识付费秘籍】【知识创业者成长手册】【100个知识付费成功案例】&#xff09; 经常有…

单位公派|肿瘤科医生远赴英国伦敦大学学院访学交流

鉴于本单位数位同事都是委托知识人网落实的职位&#xff0c;所以F医生也找到我们。几番挑选又历经周转&#xff0c;最终远赴英国伦敦大学学院访学交流。 F医生背景&#xff1a; 申请类型&#xff1a;单位公派访问学者 工作背景&#xff1a;三甲医院 教育背景&#xff1a;博士…

腾讯云im:用户端来实现群组消息的功能

前言&#xff1a; 腾讯云im如果放在服务端来实现是非常便捷的&#xff0c;但是也受腾讯im的并发等限制&#xff0c;这里提供 用户端&#xff0c;也就是前端 来实现群组消息的相关功能。 实现效果&#xff1a; 实现具体功能需求&#xff1a; 1、群组中有主播、用户、助手、导…

Android 实现单指滑动、双指缩放照片

一、前景提示 最近接到一个查看大图的需求&#xff0c;现在图片展示还不够大&#xff0c;要求还要能缩小能放大还能保存照片。直接开始Google实现方式。 二、实现功能 根据查询到的结果分为两种&#xff0c;一个是使用手势监听来实现&#xff0c;第二种监听触摸事件来实现 …

引入Tuning function design的自适应反步控制方法 下篇

引入Tuning function design的自适应反步控制方法 下篇 目录 引入Tuning function design的自适应反步控制方法 下篇利用Turning function解决高阶不匹配系统的控制器设计问题问题描述控制器设计小结总结上一篇文章写了如何通过推迟参数设计的方法来解决不匹配条件下的系统反步…

怎样把flv转换成mp4,4种方法轻松学

怎样把flv转换成mp4&#xff1f;当我们下载到视频格式是flv的时候&#xff0c;我们就要想着把flv转换成mp4&#xff1f;为什么这么说呢&#xff1f;因为FLV流媒体格式是一种全新的视频格式&#xff0c;全称为Flash Video。由于它形成的文件极小、加载速度极快&#xff0c;使得网…

这里有小白最关心的亚马逊防关联问题

账号的安全问题&#xff0c;很多时候和关联问题相关&#xff0c;一旦被检测到关联就会导致账号被永久封号。亚马逊更是官方出过规定&#xff0c;一个卖家只能开一个账号&#xff0c;如果同一个ip登录两个以上的账户&#xff0c;就很容易导致关联。这样讲可能会有点模糊&#xf…

微服务_微服务的架构演进之路

目录 一、前言 二、单体架构 三、分布式架构 四、微服务 五、SpringCloud 六、服务拆分 5.1服务拆分原则 5.2服务拆分示例 一、前言 微服务是一种软件开发架构风格&#xff0c;它将单个应用程序拆分成多个小型服务&#xff0c;每个服务都具有自己的特定功能。这些服务…

用TS写出20个数组方法的声明

前言 前段时间看直播看到狼叔直播驳斥”前端已死论“&#xff0c;前端死没死不知道&#xff0c;反正前端是拿不到以前那么多工资了&#xff1b;好&#xff0c;进入正题&#xff0c;狼叔在直播间提到要求前端写出20个数组上的方法&#xff0c;这确实不太简单&#xff0c;但是只…

(补)4.13每日一题

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 题目连接&#xff1a;https://leetcode.cn/problems/longest-substring-without-repeating-characters/ 解题 开始我把这个题目想简单了&#xff0c;我想的是输入一个字符串&#xff0c;从第一…

Day946.厂商定制的Android系统为什么也要解耦? -系统重构实战

厂商定制的Android系统为什么也要解耦&#xff1f; Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于厂商定制的Android系统为什么也要解耦&#xff1f;的内容。 一、Android 系统架构 AOSP&#xff0c;全称是 Android Open Source Project&#xff0c;中文译为“An…

永磁同步电机流频比(I/F)控制及Matlab/Simulink仿真分析

文章目录 前言一、流频比I/F控制原理二、永磁同步电机I/F控制系统Matlab/Simulink仿真分析2.1.仿真电路分析2.1.1 I/F控制算法2.1.2 电流环2.1.3 输出处理2.1.4 主电路 2.2 仿真结果分析 总结 前言 本章节采用流频比I/F控制方法驱动永磁同步电机的转动&#xff0c;首先分析流频…

传统机器学习(二)逻辑回归算法(一)

传统机器学习(二)逻辑回归算法(一) 1.1 算法概述 1.1.1 逻辑回归及其梯度推导 ​ 线性回归的任务&#xff0c;就是构造一个预测函数来映射输入的特征矩阵x和标签值y的线性关系&#xff0c;而构造预测函数的核心就是找出模型的参数,著名的最小二乘法就是用来求解线性回归中参…