WHAT - CSS Animationtion 动画系列(四)- 移动端全屏动画
目录
- 一、背景
- 1.1 GIF & Video
- 1.2 存在的问题
- 二、技术方案
- 2.1 使用CSS动画和JavaScript
- 2.2 使用JavaScript库
- 2.3 使用序列帧
- 1. css animation 帧动画
- 2. JavaScript requestAnimationFrame 帧动画
- 2.4 使用Canvas
- 1. html 和 canvas 中的 video
- 2. 基于Canvas的动画库
今天我们主要介绍在移动端(IOS和安卓)实现全屏动画播放。
一、背景
1.1 GIF & Video
在移动端(iOS 和安卓)实现全屏动画播放,尤其是对于 webview h5 来说,想要播放一个比较复杂的动画,可能我们会马上想到要么使用 GIF 图片、要么使用 视频(video)。
使用视频(video)或 GIF 图片也是实现全屏动画的有效方案之一,它们具有一些优势和适用场景:
-
简单易用: 对于一些简单的动画效果,特别是循环播放的动画,使用 GIF 图片可能是最简单、最快速的解决方案。只需将 GIF 图片嵌入到页面中即可,不需要编写额外的代码。
-
跨浏览器兼容性好: GIF 图片和视频都有很好的跨浏览器兼容性,可以在各种现代浏览器和移动设备上播放。
-
文件大小较小: 对于简单的动画效果,GIF 图片通常比视频文件的大小更小,因此可以更快地加载和播放,节省带宽和用户流量。
-
支持透明度: GIF 图片支持透明度,可以实现更多种类的动画效果,比如带有透明背景的动画。
<img src="example.gif" alt="GIF Example" width="100%" height="100%"><video controls width="100%" height="100%"><source scr="example.mp4" type="video/mp4">Your browser does not support the video tag.
</video>
1.2 存在的问题
但是,全屏动画场景下,对于前者来说,容易造成资源太大导致页面加载卡顿的问题,因为在移动设备网络速度可能相对较慢,加载 GIF 图片需要发送 http 请求,加载和解析过程可能会影响页面的响应性和交互性,用户可能会感受到页面卡顿或响应不及时的问题;对于后者来说,虽然是边加载边播放,但各种终端不同兼容性让人抓狂,比如:虽然支持不同 source 源,但是对于某些机型只能读取第一个 source,而且对于各种视频格式并不是所有机型都能支持,另外视频还有自动播放问题和静音问题,甚至有些机型(如ios)会自动打开一个播放器来全屏播放,无法做到在 webview 内正常内联播放。
最后,尤其对于复杂的动画效果、需要交互性、需要动态生成内容或需要更高的性能要求的情况,可能更适合使用其他方案,如使用 CSS 动画、JavaScript 动画库或 Canvas 动画。这些方案提供了更多的灵活性和控制能力,可以实现更复杂、更高性能的动画效果。
二、技术方案
在移动端(iOS 和安卓)实现全屏动画播放,可以采用以下几种方案:
2.1 使用CSS动画和JavaScript
使用CSS动画来创建全屏动画效果,然后通过JavaScript来控制动画的播放、暂停和进度控制等功能。可以使用CSS中的@keyframes规则来定义动画,然后通过JavaScript来触发动画的播放和暂停。
下面是一个示例代码,演示了如何使用 CSS 动画创建全屏动画效果,并通过 JavaScript 控制动画的播放、暂停和进度控制:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fullscreen Animation</title>
<link rel="stylesheet" href="styles.css">
</head>
<body><div class="container"><div class="animation"></div></div><button onclick="playAnimation()">Play</button><button onclick="pauseAnimation()">Pause</button><input type="range" min="0" max="100" value="0" step="1" onchange="setAnimationProgress(this.value)">
</body>
<script src="script.js"></script>
</html>
CSS (styles.css):
.container {width: 100px;height: 300px;background-color: blue;position: relative;overflow: hidden;
}.animation {width: 10px;height: 10px;background-color: white;animation: slide 5s linear infinite;
}@keyframes slide {0% {transform: translateY(0);}100% {transform: translateY(calc(-100% + 300px));}
}
JavaScript (script.js):
var animation = document.querySelector('.animation');
var animationPaused = false;function playAnimation() {animation.style.animationPlayState = 'running';animationPaused = false;
}function pauseAnimation() {animation.style.animationPlayState = 'paused';animationPaused = true;
}function setAnimationProgress(progress) {if (!animationPaused) {pauseAnimation();}const containerHeight = document.querySelector('.container').clientHeight;const animationHeight = animation.clientHeight;const maxTranslateY = containerHeight - animationHeight;const translateY = (maxTranslateY) * (progress / 100);animation.style.animation = 'none';animation.style.transform = 'translateY(' + translateY + 'px)';
}
在这个示例中,.container 容器包含一个高度为300px的动画元素.animation,通过 CSS 动画定义了一个垂直向上滑动的动画效果。页面中有三个按钮分别用于播放、暂停和设置动画进度。通过 JavaScript 控制动画的播放状态和进度,playAnimation() 函数用于播放动画,pauseAnimation() 函数用于暂停动画,setAnimationProgress() 函数用于设置动画的进度,参数是一个介于0和100之间的值,表示动画播放进度的百分比。

2.2 使用JavaScript库
该方案主要是对于第一种方案的优化,通过第三方动画库丰富的、方便使用的 API 来实现动画。
使用现成的JavaScript动画库,如GSAP(GreenSock Animation Platform)或者Anime.js等,这些库提供了丰富的动画功能和API,可以方便地实现全屏动画效果,并且具有良好的跨浏览器兼容性和性能优化。

2.3 使用序列帧
前面两种方案主要是针对各种比较规律的动画的实现,那假如要全屏展示一段复杂的动画或视频内容呢?
有两种方案:
- 序列帧
- canvas
我们先介绍序列帧。
序列帧又分为 css animation 帧和 JavaScript requestAnimationFrame 帧。
1. css animation 帧动画
使用 sprite 图和 background-position ,再加上 animation 的 step 函数,可以实现序列帧动画。
以一个 3s 的全屏动画为例,我们可以拆为 36 张图,1s 12帧,一张图宽度375px,那么36张图合成一张横图13500px。再利用 css animation 播放:
.video {width: 100%;height: 100%;background: url('test.png')overflow: hidden;animation: a_video 3s steps(36);
}@keyframe a_video {from {background-position: 0 0;}to {background-position: 13500px 0;}
}
当然,很明显合成一个完整的图片会太长,而且图片大小非常夸张,
这种图片在移动端也会造成卡顿的。当然,如果是小范围 div 内(非全
屏)的动画需求,应该可以忽略资源大小的问题。
因此,我们可以进一步分成多个阶段,比如:
3s 我们可以分成 3 个 1s,做 3 张图,1 张图包含 1s 内的 15 帧:

具体代码:
.video {width: 100%;height: 100%;position: absolute;left: 0px;top: 0px;background-size: 500% 300%;background-repeat: no-repeat;animation: a_video 3s steps(1, end);
}@keyframe a_video {0% {background-image: url("video-1.jpg");background-position: 0 0;}6% {background-image: url("video-1.jpg");background-position: 25% 0;}12% {background-image: url("video-1.jpg");background-position: 50% 0;}18% {background-image: url("video-1.jpg");background-position: 75% 0;}24% {background-image: url("video-1.jpg");background-position: 100% 0;}30% {background-image: url("video-1.jpg");background-position: 0% 50%;}36% {background-image: url("video-1.jpg");background-position: 25% 50%;}/*...*/60% {background-image: url("video-1.jpg");background-position: 0% 100%;}66% {background-image: url("video-1.jpg");background-position: 25% 100%;}/*...*/100% {background-image: url("video-1.jpg");background-position: 100% 100%;}
}
2. JavaScript requestAnimationFrame 帧动画
使用 requestAnimationFrame 来逐帧渲染雪碧图可以实现流畅的动画效果。下面是一个简单的示例,演示了如何使用 requestAnimationFrame 来实现逐帧渲染雪碧图:
css:
#sprite {width: 100px;height: 150px;background-image: url('spritesheet.png');background-size: cover;}
JavaScript (script.js):
const sprite = document.getElementById('sprite');
const frameWidth = 100; // 每帧宽度
const frameHeight = 150; // 每帧高度
const totalFrames = 15; // 总帧数
const framesPerSecond = 10; // 每秒播放帧数let currentFrame = 0;
let lastFrameTime = 0;function animate(timestamp) {// 在 requestAnimationFrame 回调函数中,timestamp 是一个 DOMHighResTimeStamp 类型的参数,表示当前回调函数被触发的时间戳// 该时间戳是一个高分辨率的值,通常以 ms 为单位,相对于页面加载开始时的性能时间原点// 这里我们用这个 timestamp 来计算动画的进度const elapsed = timestamp - lastFrameTime;if (elapsed > (1000 / framesPerSecond)) { // 每秒要播放10帧 一帧持续100ms// 当超过 100ms 即表示要切换到下一帧lastFrameTime = timestamp;// 计算当前帧的位置const frameX = currentFrame % 3 * frameWidth;const frameY = Math.floor(currentFrame / 3) * frameHeight;// 设置背景位置sprite.style.backgroundPosition = `-${frameX}px -${frameY}px`;// 更新当前帧(的索引)// 注意 这里 % totalFrames 的作用是实现循环播放currentFrame = (currentFrame + 1) % totalFrames;}requestAnimationFrame(animate);
}// 开始动画
requestAnimationFrame(animate);
在这个示例中,我们首先定义了一个包含 15 帧的 3x5 的雪碧图,每帧的宽度为 100px,高度为 150px。然后,我们使用 requestAnimationFrame 来启动动画循环,在每帧中更新雪碧图的背景位置,从而实现逐帧渲染的效果。
2.4 使用Canvas
使用HTML5 Canvas元素来绘制全屏动画效果。
1. html 和 canvas 中的 video
在 HTML 和 Canvas 中使用视频(video)有一些不同之处,主要涉及到了它们的用途、控制方式和性能等方面:
-
用途:
- 在 HTML 中使用视频(video)元素主要用于在网页中展示和播放视频内容。视频元素可以通过 HTML 标签直接嵌入到页面中,并提供了一些内置的控制功能,如播放、暂停、音量调节等。
- 在 Canvas 中使用视频通常是为了在画布上绘制视频的每一帧,并实现更加灵活的视频处理和展示效果。Canvas 提供了绘图 API,可以将视频的每一帧绘制到画布上,并进行自定义的处理和动画效果。
-
控制方式:
- 在 HTML 中,视频元素具有内置的控制功能,用户可以通过浏览器提供的默认 UI 来控制视频的播放、暂停、音量调节等操作,也可以通过 JavaScript 来动态控制视频的行为。
- 在 Canvas 中,要实现对视频的控制,通常需要使用 JavaScript 来处理视频的播放和暂停等操作,以及绘制视频的每一帧到画布上。
-
性能:
- 在 HTML 中使用视频元素通常具有较好的性能和兼容性,因为视频的播放和渲染是由浏览器内核直接处理的,可以充分利用硬件加速来提高性能。
- 在 Canvas 中使用视频需要将视频的每一帧绘制到画布上,这涉及到大量的图像处理和绘制操作,可能会对性能产生一定影响,特别是在处理大尺寸或高分辨率视频时。
总的来说,HTML 中的视频元素适用于简单的视频展示和播放场景,而 Canvas 中的视频处理适用于需要更多自定义和交互性的视频处理和展示效果。选择使用哪种方式取决于具体的需求和场景。
另外,在 Canvas 中渲染视频通常不会涉及到使用原生播放器,因为视频的播放和渲染是由 Canvas 直接控制的,而不是依赖于浏览器提供的原生播放器。因此,与使用 HTML5 <video> 元素播放视频相比,Canvas 中渲染视频可以更灵活地控制视频的播放、渲染和效果。
但是,需要注意的是,Canvas 中渲染视频可能会涉及到一些其他方面的问题,例如:
-
性能问题:在 Canvas 中渲染视频可能需要大量的计算和绘制操作,特别是在处理高分辨率或大尺寸的视频时,可能会对性能造成一定的影响,需要进行优化和考虑性能问题。
-
兼容性问题:Canvas 的功能和性能在不同浏览器和设备上可能会有所不同,需要进行兼容性测试和调整。
-
实现复杂度:相比于使用原生播放器播放视频,Canvas 中渲染视频可能需要更多的编程和实现复杂度,包括视频的解码、帧的处理、渲染效果的实现等。当然利用第三方库可以一定程度避免该问题。
总的来说,Canvas 中渲染视频可以提供更多的自定义和控制能力,但也需要考虑到性能、兼容性和实现复杂度等方面的问题。
2. 基于Canvas的动画库
有许多基于 Canvas 的动画库可以帮助开发者更轻松地创建各种动态和交互式的 Canvas 动画。以下是一些常用的基于 Canvas 的动画库:
-
PixiJS:PixiJS 是一个功能强大的 WebGL 渲染引擎,提供了丰富的 API 和工具,用于创建高性能的交互式 2D 游戏和图形应用。它可以与 Canvas 兼容,并且支持 WebGPU、WebGL 和 Canvas 2D 渲染。它提供了易于使用的 API,适合用于创建各种类型的 Canvas 动画和游戏。
-
CreateJS:CreateJS 是一个包含多个模块的 JavaScript 库,其中包括 EaselJS、TweenJS、SoundJS 和 PreloadJS。其中的 EaselJS 模块提供了一套简单易用的 API,用于在 Canvas 上绘制图形和创建动画。它可以用来创建各种类型的 Canvas 动画和交互式应用。
-
Two.js:Two.js 是一个轻量级的 2D 绘图库,它提供了一系列的 API 和工具,用于在 Canvas 上创建图形、动画和交互式应用。它具有简单易用的 API,适合用于创建简单的 Canvas 动画和图形应用。
-
Three.js: 一个用于创建 3D 图形的 JavaScript 库,虽然它主要用于 WebGL,但也可以在 Canvas 上创建 3D 图形,并提供了丰富的 3D 渲染功能和特效支持。
这些基于 Canvas 的动画库都具有不同的特点和适用场景,开发者可以根据自己的需求和偏好选择合适的库来创建 Canvas 动画和应用。
更多关于 Canvas 内容可以阅读 HOW - Canvas 入门系列(一)
相关文章:
WHAT - CSS Animationtion 动画系列(四)- 移动端全屏动画
目录 一、背景1.1 GIF & Video1.2 存在的问题 二、技术方案2.1 使用CSS动画和JavaScript2.2 使用JavaScript库2.3 使用序列帧1. css animation 帧动画2. JavaScript requestAnimationFrame 帧动画 2.4 使用Canvas1. html 和 canvas 中的 video2. 基于Canvas的动画库 今天我…...
springboot004网页时装购物系统
springboot004网页时装购物系统 亲测完美运行带论文:获取源码,私信评论或者v:niliuapp 运行视频 包含的文件列表(含论文) 数据库脚本:db.sql其他文件:ppt.pptx论文/文档:开题报告.docx论文&…...
海外住宅IP介绍
住宅IP,通俗的来讲就是分配给家庭的IP地址,ISP默认分配用户为家庭用户,其真实性与安全性都有一定保障。海外住宅IP是指由海外互联网服务提供商分配给家庭用户的IP地址,IP地址通常是静态的,稳定的,可以为用户…...
Qt | QTimer 类(计时器)
01、相关知识回顾 Qt C++ | QTimer经验总结Qt | QDateTimeEdit、QDateEdit类和QTimeEdit类02、QTimer 类 1、QTimer 类是 QObejct 的直接子类,该类用于实现计时器,QTimer 类未继承自 QW...
SQL 面试系列(一)【留存率问题】
前言 在学 HQL 之前是不太了解 SQL 的,以为 SQL 只可以实现 CRUD ,直到面试的公司让我下去多了解一些 SQL ,我才最近开始再次深入学习 MySQL 和 Oracle。而且越学越发现 SQL 真的是一门很有深度的语言,我以前的使用只是皮毛而已&a…...
2024OD机试卷-游戏分组 (java\python\c++)
题目:游戏分组 题目描述 部们准备举办一场 王者荣耀 表演赛,有 10 名游戏爱好者参与,分为两队,每队 5 人。 每位参与者都有一个评分,代表着他的游戏水平。为了表演赛尽可能精彩,我们需要把 10 名参赛者分为实力尽量相近的两队。 一队的实力可以表示为这一队 5 名队员的…...
重装前端整体流程
用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程(非常详细)从零基础入门到精通,看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候,去看,淘…...
Oracle Database 23ai Free版本体验
Oracle Database 23ai 体验链接: Oracle Database 23ai Free (https://www.oracle.com/database/free/get-started/) Autonomous Database 23ai Container Image (https://www.oracle.com/autonomous-database/free-trial/) Oracle GoldenGate 23ai (https://www…...
84.网络游戏逆向分析与漏洞攻防-游戏技能系统分析-筛选与技能有关的数据包
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果,代码看不懂是正常的,只要会抄就行,抄着抄着就能懂了 内容…...
维护表空间中的数据文件
目录 向表空间中添加数据文件 从表空间中删除数据文件 删除users表空间中的users02.dbf数据文件 对数据文件的自动扩展设置 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 维护表空间中的数据文件主要包括向表空间中添…...
2024五月母亲节嘉年华活动方案
2024以花之名 致谢母亲簪花趣味亲子五月母亲节嘉年华活动方案-43P 活动策划信息: 方案页码:43页 文件格式:PPT 方案简介: 岁月温柔治愈 母爱闪闪发光 一年一度的PY圈孝子孝女大赛即将到来 本次母亲节,“以花之名…...
Linux 第三十三章
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要等到什么都没有了…...
低空经济:无人机竞赛详解
无人机竞赛市场近年来呈现出蓬勃发展的态势,其市场价值不仅体现在竞赛本身,还体现在推动无人机技术创新、拓展应用场景以及促进产业链发展等多个方面。 一、比赛项目介绍 无人机竞赛通常分为多个项目,包括竞速赛、技巧赛、航拍赛等。每个项目…...
CAD插入文字到另一图形样式变相同
CAD从一张图形复制到另外一张图形后,文字样式变成一样是因为两张图所用的文字样式名称一样,但是样式里面的使用字体样式不一样。如下图所示,找到工具栏中的注释 ,点击文字样式。里面就会显示当前图形中使用的样式名称及其对应的字…...
算法随想录第八天打卡|344.反转字符串,541. 反转字符串II, 卡码网:54.替换数字, 151.翻转字符串里的单词,卡码网:55.右旋转字符串
344.反转字符串 建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数 题目链接/文章讲解/视频讲解:代码随想录 Python class Solution:def reve…...
外卖系统的JWT实现登录
1、什么是JWT jwt可以生成一个加密的token,作为用户登录的令牌,当用户登陆成功之后,发放给客户端。请求需要登录的资源或者接口的时候,将token携带,后端验证token是否合法。jwt有三部分组成: A:…...
基于springboot实现的家具销售电商平台
开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包&…...
STM32中的Systick的使用
SysTick,全称System Tick Timer,是Cortex-M microcontrollers内核中提供的一个简单而有效的系统定时器,设计用来给操作系统提供时间基准,或用于生成周期性的中断。STM32系列微控制器,作为基于ARM Cortex-M内核的设备&a…...
做一个桌面悬浮翻页时钟
毛玻璃效果翻页桌面悬浮时钟,TopMost(Topmost“True”),不在任务栏显示(ShowInTaskbar“False”),在托盘区显示图标,双击托盘区图标实现最小化和还原,右键托盘图标可选“…...
Transformers中加载预训练模型的过程剖析(一)
使用HuggingFace的Transformers库加载预训练模型来处理下游深度学习任务很是方便,然而加载预训练模型的方法多种多样且过程比较隐蔽,这在一定程度上会给人带来困惑。因此,本篇文章主要讲一下使用不同方法加载本地预训练模型的区别、加载预训练模型及其配置的过程,藉此做个记…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
智能职业发展系统:AI驱动的职业规划平台技术解析
智能职业发展系统:AI驱动的职业规划平台技术解析 引言:数字时代的职业革命 在当今瞬息万变的就业市场中,传统的职业规划方法已无法满足个人和企业的需求。据统计,全球每年有超过2亿人面临职业转型困境,而企业也因此遭…...
密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored
https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…...
