只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(下)

news2024/12/24 10:18:56

目录

前言

介绍

基本使用

关键帧

KeyframeEffect的三种类的声明

keyframes

options

动画对象

全局Animation类

标签中的animate函数

总结

相关代码:


前言

接着上文往下介绍,上篇文章我们对JS原生动画和贝塞尔曲线有了一个详细的认识,基于定时器或动画帧,我们可以实现元素的动画缓动,本文将分享浏览器中功能强大的Animations API,有兴趣的朋友请接着往下看吧

介绍

Web Animations API(简称WAAPI)于2016年成为Web标准的一部分,它的功能比之前提到的动画要丰富的多,它的核心理念是时间轴和动画效果。它提供了一组功能强大的方法和属性,用于定义、操作和管理动画效果。

时间轴(Timeline)是WAAPI中的核心概念之一。它类似于一个全局时钟,用于管理和协调所有正在运行的动画。通过时间轴,开发者可以控制动画的播放、暂停、重置等操作。

动画效果(Animation Effect)指的是要应用到动画目标上的转换或变化。WAAPI提供了多种类型的动画效果,如位移(translate)、缩放(scale)、旋转(rotate)等。开发者可以使用这些效果来创建各种动画效果。

基本使用

关键帧

还记得之前的CSS关键帧吗?使用from to或者百分比来定义动画阶段的效果,在JS中使用KeyframeEffect类可以创建关键帧动画

const box = document.querySelector(".box")
const keyframes = [
    { left: 0 },
    { left: '100px' }
];
const keyframe = new KeyframeEffect(box, keyframes, 1000);

上述代码中,KeyframeEffect类接收三个参数:第一个是目标标签,第二个是关键帧,第三个是动画时间

KeyframeEffect的三种类的声明

  1. KeyframeEffect(keyframeEffect):复制关键帧配置
  2. KeyframeEffect(element, keyframes, duration):在标签element上生成新的动画,关键帧为keyframes,持续duration毫秒
  3. KeyframeEffect(element, keyframes, options):在标签element上生成新的动画,关键帧为keyframes,动画配置options

keyframes

关键帧的写法有两种,分别是数组的方式和样式对象的写法

  • 数组
const keyframes = [
    { left: 0, top: "50px" },
    { left: '100px', top: "100px" },
    { top: "150px" }
];
  • 对象
const keyframes = {
    left: [0, '100px', '100px'], top: ["50px", "100px", "150px"]
}

options

KeyframeEffect的第三个参数类型是数字或options配置项,数字代表动画时长,options则有以下属性:

  1. delay:动画开始之前的延迟时间,以毫秒为单位,默认值为0。对应css的animation-delay
  2. direction:动画的播放方向,可以是 "normal"(正常播放)、"reverse"(反向播放)、"alternate"(交替播放)或 "alternate-reverse"(交替反向播放)。默认值为 "normal"。对应css的animation-direction
  3. duration:动画的持续时间,以毫秒为单位,默认值为0。对应css的animation-duration
  4. easing:动画的缓动函数,可以使用 CSS 缓动函数,如 "linear"、"ease"、"ease-in" 等,或者自定义的缓动函数。默认值为 "linear"。对应css的animation-timing-function
  5. endDelay:动画结束后的延迟时间,以毫秒为单位,默认值为0。
  6. fill:动画在非活动时间段的行为,可以是none(默认,动画结束后不会保留任何效果)、forwards(动画结束后保持最后一帧的效果)或backwards(动画开始前应用第一帧的效果)。也可以是both,表示同时应用forwards和backwards的效果。对应css的animation-fill-mode
  7. iterationStart:动画的迭代开始位置,以小数表示(例如,0.5表示从动画的中间位置开始迭代),默认值为0。
  8. iterations:动画的迭代次数,可以是一个正整数或Infinity(无限循环),默认值为1。对应css的animation-iteration-count
  9. keyframes:动画的关键帧,可以是一个关键帧规则对象或关键帧数组。
  10. playbackRate:用于控制动画播放速率的属性。它可以用于加速或减慢动画的播放速度。
  11. composite(CompositeOperation):动画的合成行为。可以是replace或add。默认值为replace。replace表示动画将覆盖目标属性的当前值,而add表示动画将与目标属性的当前值叠加。
  12. iterationComposite(IterationCompositeOperation):动画迭代之间的值合成行为。可以是replace或accumulate。默认值为replace。replace表示每次迭代时动画的值将替换目标属性的当前值,而accumulate表示每次迭代时动画的值将累积到目标属性的当前值上。
  13. pseudoElement:应用动画的伪元素。可以是一个字符串,表示伪元素的名称,例如before或after,或者可以是null,表示应用于主元素而非伪元素。

示例

<!DOCTYPE html>
<html lang="CH">

<head>
    <meta charset="UTF-8" />
    <title>webAnimationsAPI</title>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            position: relative;
        }

        .box {
            width: 200px;
            height: 200px;
            top: 50px;
            position: absolute;
            background: lightblue;
        }

        .box::after {
            width: 100px;
            height: 100px;
            content: "";
            left: 50px;
            position: absolute;
            background: lightcoral;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <button onclick="playHandler()">开始</button>
    <script>
        const box = document.querySelector(".box")
        const keyframes = [
            { transform: "rotate(0)" },
            { transform: "rotate(180deg)" },
            { transform: "rotate(360deg)" },
        ];
        const options = {
            delay: 500,// 延迟500毫秒开始动画
            duration: 1000,// 持续时间为1000毫秒
            easing: 'ease-in-out',// 缓动函数为ease-in-out
            iterations: Infinity,// 迭代3次
            direction: 'alternate',// 交替播放
            endDelay: 1000,// 延迟1000毫秒开始动画
            fill: "forwards",// 结束后保持最后一帧的效果
            iterationStart: .2,// 从动画的20%位置开始迭代
            composite: 'add',//使用add合成行为
            keyframes: keyframes,//指定关键帧
            playbackRate: 2.0,//播放速率为2倍
            iterationComposite: 'accumulate',//使用accumulate合成行为
            pseudoElement: '::after'//应用于after伪元素
        }
        const keyframe = new KeyframeEffect(box, keyframes, options);
        function playHandler() {
            const animation = new Animation(keyframe, document.timeline);
            animation.play();
        }
    </script>
</body>

</html>

效果

动画对象

全局Animation类

创建完成动画的关键帧后,我们可以使用全局的Animation类创建动画,动画的形式就是上面的关键帧

const box = document.querySelector(".box")
const keyframes = [
    { left: 0, top: "50px" },
    { left: '100px', top: "100px" },
    { top: "150px" }
];
const keyframe = new KeyframeEffect(box, keyframes, 1000);
function playPauseHandler() {
    const animation = new Animation(keyframe);
    animation.play();
}

使用new Animation(keyframe)创建新的动画,然后使用play函数对动画进行激活

效果如下

Animation构造函数的参数有两个:关键帧对象AnimationEffect和时间线AnimationTimeline,前者就是上面说到的KeyframeEffect,AnimationTimeline一般可以使用document.timeline来描述

const animation = new Animation(keyframe, document.timeline);

animation对象中有许多属性和方法

属性

  • id:返回动画的唯一标识符。
  • startTime:动画开始的时间戳。
  • currentTime:当前动画的时间,以毫秒为单位。
  • playbackRate:动画的播放速率,默认值为1。
  • effect:动画的效果,KeyframeEffect对象。
  • timeline:动画所使用的时间轴,AnimationTimeline对象。
  • playState:动画的当前播放状态,可能的值为 "idle"、"pending"、"running"、"paused"、"finished"。
  • pending:动画的等待状态,即动画是否处于 pending 状态。

方法

  • play(): 播放动画。
  • pause(): 暂停动画。
  • cancel(): 取消动画。
  • finish(): 完成动画。
  • reverse(): 反转动画的播放方向。
  • updatePlaybackRate(playbackRate): 更新动画的播放速率。
  • addEventListener(type, listener): 在动画上添加事件监听器。如:finish(完成)、cancel(取消)和pause(暂停)等
  • removeEventListener(type, listener): 从动画上移除事件监听器。
  • oncancel: 一个事件处理程序,当动画被取消时执行。
  • onfinish: 一个事件处理程序,当动画完成时执行。

使用示例

<!DOCTYPE html>
<html lang="CH">

<head>
    <meta charset="UTF-8" />
    <title>webAnimationsAPI</title>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            position: relative;
        }

        .box {
            width: 200px;
            height: 200px;
            top: 50px;
            position: absolute;
            background: lightblue;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <button onclick="playHandler()">开始</button>
    <button onclick="pauseHandler()">暂停</button>
    <button onclick="cancelHandler()">取消、重置</button>
    <button onclick="reverseHandler()">反向运行</button>
    <button onclick="finishHandler()">完成动画</button>
    <button onclick="playbackRateHandler()">更新动画速率</button>
    <button onclick="playStateHandler()">获取状态</button>
    <button onclick="currentTimeHandler()">获取时间轴位置</button>
    <script>
        const box = document.querySelector(".box")
        const keyframes = [
            { left: 0 },
            { left: '300px' },
        ];
        const keyframe = new KeyframeEffect(box, keyframes, {
            duration: 1000,
            iterations: Infinity,
            direction: 'alternate',
            fill: "forwards",
        });
        const animation = new Animation(keyframe, document.timeline);
        animation.addEventListener("finish", console.info)
        animation.addEventListener("cancel", console.info)
        animation.addEventListener("remove", console.info)
        function playHandler() {
            animation.play();
        }
        function pauseHandler() {
            animation.pause();
        }
        function cancelHandler() {
            animation.cancel();
        }
        function reverseHandler() {
            animation.reverse();
        }
        function finishHandler() {
            animation.finish();// 当iterations等于infinity时无法触发完成
        }

        function playStateHandler() {
            console.log(animation.playState);
        }
        function playbackRateHandler() {
            animation.updatePlaybackRate(2)
        }
        function currentTimeHandler() {
            console.log(animation.currentTime);
        }
    </script>
</body>

</html>

效果如下

标签中的animate函数

全局的Element标签对象继承于Animatable接口

该接口描述了两个方法:animate为当标签增加动画与getAnimations获取当前标签全部动画

interface Animatable {
    animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;
    getAnimations(options?: GetAnimationsOptions): Animation[];
}

用法和KeyframeEffect+Animation类似

<!DOCTYPE html>
<html lang="CH">

<head>
    <meta charset="UTF-8" />
    <title>webAnimationsAPI</title>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            position: relative;
        }

        .box {
            width: 200px;
            height: 200px;
            top: 50px;
            position: absolute;
            background: lightblue;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <button onclick="playHandler()">开始</button>
    <button onclick="pauseHandler()">暂停</button>
    <script>
        const box = document.querySelector(".box")
        const keyframes = [
            { left: 0 },
            { left: '300px' },
        ];
        const opts = {
            duration: 1000,
            iterations: Infinity,
            direction: 'alternate',
            fill: "forwards",
        }
        const animation = box.animate(keyframes, opts)
        function playHandler() {
            animation.play();
        }
        function pauseHandler() {
            animation.pause();
        }
    </script>
</body>

</html>

总结

本文与大家分享了16年新推出的JS原生动画WAAPI,使用这种方式创建的动画对象功能十分强大,其中我们可以使用KeyframeEffect设置标签关键帧的样式,通过Animation对象运行标签的动画。与前面的两篇关于动画的文章相比,WAAPI虽然强大,但是使用时还需要考虑兼容性问题。

好了,以上就是文章的全部内容了,希望文章内容对你有帮助,如果觉得文章不错的话,还望三连支持一下博主,谢谢~

相关代码:

myCode: 基于js的一些小案例或者项目 - Gitee.com

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

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

相关文章

了解IL汇编异常处理语法

从网上拷过来一个IL汇编程序&#xff0c;编译时先报如下错&#xff0c; 看它是把空格识别为了下注红线的字符&#xff0c;这是字符编码的问题&#xff0c;用记事本替换功能替换了&#xff1b; 然后又报如下的错&#xff0c; 看不出来问题&#xff0c;拷一句正确的来&#xff0…

Netty面试题3

讲一讲你在网络通讯中遇到的坑或者比较棘手的问题 1、网络延迟问题 2、网络拥塞问题 某公司的Java项目需要向远程服务器发送大量的HTTP请求并获取响应&#xff0c;由于请求量较大&#xff0c;导致网络拥塞&#xff0c;请求响应延迟较高。针对这个问题&#xff0c;我们可以采取…

「2024」预备研究生mem-等差等比数列片段和 一般数列

一、等差数列 片段和 二、等比数列 片段和 三、一般数列

数据结构 | 树的定义及实现

目录 一、树的术语及定义 二、树的实现 2.1 列表之列表 2.2 节点与引用 一、树的术语及定义 节点&#xff1a; 节点是树的基础部分。它可以有自己的名字&#xff0c;我们称作“键”。节点也可以带有附加信息&#xff0c;我们称作“有效载荷”。有效载荷信息对于很多树算法…

AcWing 379. 捉迷藏(最小路径点覆盖匈牙利算法)

输入样例&#xff1a; 7 5 1 2 3 2 2 4 4 5 4 6输出样例&#xff1a; 3 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N220; int n,m,t; int d[N][N],vis[N]; int match[N]; bool find(int x){for(int i1;i<n;i){if(d[x][i]&&…

Mac unsupported architecture

&#xff08;瓜是长大在营养肥料里的最甜&#xff0c;天才是长在恶性土壤中的最好。——培根&#xff09; unsupported architecture 在mac的m系列芯片中容易出现此类问题&#xff0c;因为m系列是arm64的芯片架构&#xff0c;而有些nodejs版本或npm包的芯片架构是x86的&#x…

Visual Studio配置PCL库

Visual Studio配置PCL库 Debug和Release配置新建项目配置属性表测试参考 Debug和Release Debug和Release的配置过程一模一样&#xff0c;唯一区别就在于最后一步插入的附加依赖项不同&#xff0c;因此下面以debug为例。 配置新建项目 1、新建一个C空项目&#xff0c;模式设置…

Linux ——实操篇

Linux ——实操篇 前言vi 和 vim 的基本介绍vi和vim常用的三种模式正常模式插入模式命令行模式 vi和vim基本使用各种模式的相互切换vi和vim快捷键关机&重启命令基本介绍注意细节 用户登录和注销基本介绍使用细节 用户管理基本介绍添加用户基本语法应用案例细节说明 指定/修…

ROS实现机器人移动

开源项目 使用是github上六合机器人工坊的项目。 https://github.com/6-robot/wpr_simulation.git 机器人运动模型 运动模型如下所示&#xff1a;&#x1f447; 机器人运动的消息包&#xff1a; 实现思路&#xff1a;&#x1f447;   为什么要使用/cmd_vel话题。因为这…

Spring Cloud +UniApp 智慧工地云平台源码,智能监控和AI分析系统,危大工程管理、视频监控管理、项目人员管理、绿色施工管理

一套智慧工地云平台源码&#xff0c;PC管理端APP端平板端可视化数据大屏端源码 智慧工地可视化系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;通过工地中台、三维建模服务、视频AI分析服务等技术支撑&#xff0c;实现智慧工地高精度动态仿…

项目实战 — 消息队列(4){消息持久化}

目录 一、消息存储格式设计 &#x1f345; 1、queue_data.txt&#xff1a;保存消息的内容 &#x1f345; 2、queue_stat.txt&#xff1a;保存消息的统计信息 二、消息序列化 三、自定义异常类 四、创建MessageFileManger类 &#x1f345; 1、约定消息文件所在的目录和文件名…

重锤式表面电阻测试仪的原理和特点

重锤式表面电阻测试仪是一种用于测量材料表面电阻的仪器。它采用了重锤敲击和测量电流的方式进行测试。 工作原理&#xff1a; 重锤式表面电阻测试仪通过将一个金属锤头敲击在待测物体表面&#xff0c;产生一个封闭电路。测量仪器通过检测在敲击区域上下电极之间距离的电流流…

C语言代码的x86-64汇编指令分析过程记录

先通过Xcode创建一个terminal APP&#xff0c;语言选择C。代码如下&#xff1a; #include <stdio.h>int main(int argc, const char * argv[]) {int a[7]{1,2,3,4,5,6,7};int *ptr (int*)(&a1);printf("%d\n",*(ptr));return 0; } 在return 0处打上断点&…

相机传感器格式与镜头光圈参数

相机靶面大小 CCD/CMOS图像传感器尺寸&#xff08;sensor format&#xff09;1/2’‘、1/3’‘、1/4’实际是多大 1英寸——靶面尺寸为宽12.7mm*高9.6mm&#xff0c;对角线16mm。 2/3英寸——靶面尺寸为宽8.8mm*高6.6mm&#xff0c;对角线11mm。 1/2英寸——靶面尺寸为宽6.…

第4章 变量、作用域与内存

引言 由于js是一门只有在声明变量后才能明确类型的语言&#xff0c;并且在任意时刻都可以改变数据类型。这也引起了一些问题 原始值与引用值 原始值就是基本数据类型&#xff0c;引言值就是复杂数据类型 变量在赋值的时候。js会判断如果是原始值&#xff0c;访问时就是按值访问…

Air32 | 合宙Air001单片机内部FLASH读写示例

Air32 | 合宙Air001单片机内部FLASH读写示例 代码已经通过测试&#xff0c;开发环境KEIL-MDK 5.36。 测试代码 void FLASH_RdWrTest(void) {uint32_t Address;uint32_t PageReadBuffer[FLASH_PAGE_SIZE >> 2];uint32_t PageWriteBuffer[FLASH_PAGE_SIZE >> 2];mem…

仓储物流业如何实现精细化工时成本管理,提升出库效率?

面对日益复杂的物流需求&#xff0c;以及不断上涨的人力成本。仓储物流企业想要在市场竞争中脱颖而出&#xff0c;不仅需要提升出库效率&#xff0c;满足消费者次日达甚至当日达的高要求&#xff0c;更需要控制人力成本&#xff0c;保证企业持续盈利的能力。盖雅新推出的 「劳…

恒运资本:史上最强暑期档!总票房突破147亿,前三都是国产片!

暑期档电影又爆了&#xff01; 就在刚刚曩昔的周末&#xff0c;在《封神第一部》《巨齿鲨2&#xff1a;深渊》《火热》等电影的大卖&#xff0c;以及《背注一掷》点映及预售的加持下&#xff0c;短短两天的大盘票房就到达10亿元。 其间&#xff0c;据猫眼专业版数据&#xff0…

Windows下安装Kafka(图文记录详细步骤)

Windows下安装Kafka Kafka简介一、Kafka安装前提安装Kafka之前&#xff0c;需要安装JDK、Zookeeper、Scala。1.1、JDK安装&#xff08;version&#xff1a;1.8&#xff09;1.1.1、JDK官网下载1.1.2、JDK网盘下载1.1.3、JDK安装 1.2、Zookeeper安装1.2.1、Zookeeper官网下载1.2.…

Java方法重写

目录 1.什么是方法重写 2.方法重写的规则 3.重写与重载的区别 1.什么是方法重写 重写&#xff08;override&#xff0c;也称为覆盖&#xff09;&#xff1a;在子类中对父类中允许访问的方法的实现过程进行重新编写&#xff0c;子类中方法的名称、返回值类型、参数列表与父类…