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 图片也是实现全屏动画的有效方案之一,它们具有一些优势和适用场景:

  1. 简单易用: 对于一些简单的动画效果,特别是循环播放的动画,使用 GIF 图片可能是最简单、最快速的解决方案。只需将 GIF 图片嵌入到页面中即可,不需要编写额外的代码。

  2. 跨浏览器兼容性好: GIF 图片和视频都有很好的跨浏览器兼容性,可以在各种现代浏览器和移动设备上播放。

  3. 文件大小较小: 对于简单的动画效果,GIF 图片通常比视频文件的大小更小,因此可以更快地加载和播放,节省带宽和用户流量。

  4. 支持透明度: 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 使用序列帧

前面两种方案主要是针对各种比较规律的动画的实现,那假如要全屏展示一段复杂的动画或视频内容呢?

有两种方案:

  1. 序列帧
  2. 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)有一些不同之处,主要涉及到了它们的用途、控制方式和性能等方面:

  1. 用途

    • 在 HTML 中使用视频(video)元素主要用于在网页中展示和播放视频内容。视频元素可以通过 HTML 标签直接嵌入到页面中,并提供了一些内置的控制功能,如播放、暂停、音量调节等。
    • 在 Canvas 中使用视频通常是为了在画布上绘制视频的每一帧,并实现更加灵活的视频处理和展示效果。Canvas 提供了绘图 API,可以将视频的每一帧绘制到画布上,并进行自定义的处理和动画效果。
  2. 控制方式

    • 在 HTML 中,视频元素具有内置的控制功能,用户可以通过浏览器提供的默认 UI 来控制视频的播放、暂停、音量调节等操作,也可以通过 JavaScript 来动态控制视频的行为。
    • 在 Canvas 中,要实现对视频的控制,通常需要使用 JavaScript 来处理视频的播放和暂停等操作,以及绘制视频的每一帧到画布上。
  3. 性能

    • 在 HTML 中使用视频元素通常具有较好的性能和兼容性,因为视频的播放和渲染是由浏览器内核直接处理的,可以充分利用硬件加速来提高性能。
    • 在 Canvas 中使用视频需要将视频的每一帧绘制到画布上,这涉及到大量的图像处理和绘制操作,可能会对性能产生一定影响,特别是在处理大尺寸或高分辨率视频时。

总的来说,HTML 中的视频元素适用于简单的视频展示和播放场景,而 Canvas 中的视频处理适用于需要更多自定义和交互性的视频处理和展示效果。选择使用哪种方式取决于具体的需求和场景。

另外,在 Canvas 中渲染视频通常不会涉及到使用原生播放器,因为视频的播放和渲染是由 Canvas 直接控制的,而不是依赖于浏览器提供的原生播放器。因此,与使用 HTML5 <video> 元素播放视频相比,Canvas 中渲染视频可以更灵活地控制视频的播放、渲染和效果。

但是,需要注意的是,Canvas 中渲染视频可能会涉及到一些其他方面的问题,例如:

  1. 性能问题:在 Canvas 中渲染视频可能需要大量的计算和绘制操作,特别是在处理高分辨率或大尺寸的视频时,可能会对性能造成一定的影响,需要进行优化和考虑性能问题。

  2. 兼容性问题:Canvas 的功能和性能在不同浏览器和设备上可能会有所不同,需要进行兼容性测试和调整。

  3. 实现复杂度:相比于使用原生播放器播放视频,Canvas 中渲染视频可能需要更多的编程和实现复杂度,包括视频的解码、帧的处理、渲染效果的实现等。当然利用第三方库可以一定程度避免该问题。

总的来说,Canvas 中渲染视频可以提供更多的自定义和控制能力,但也需要考虑到性能、兼容性和实现复杂度等方面的问题。

2. 基于Canvas的动画库

有许多基于 Canvas 的动画库可以帮助开发者更轻松地创建各种动态和交互式的 Canvas 动画。以下是一些常用的基于 Canvas 的动画库:

  1. PixiJS:PixiJS 是一个功能强大的 WebGL 渲染引擎,提供了丰富的 API 和工具,用于创建高性能的交互式 2D 游戏和图形应用。它可以与 Canvas 兼容,并且支持 WebGPU、WebGL 和 Canvas 2D 渲染。它提供了易于使用的 API,适合用于创建各种类型的 Canvas 动画和游戏。

  2. CreateJS:CreateJS 是一个包含多个模块的 JavaScript 库,其中包括 EaselJS、TweenJS、SoundJS 和 PreloadJS。其中的 EaselJS 模块提供了一套简单易用的 API,用于在 Canvas 上绘制图形和创建动画。它可以用来创建各种类型的 Canvas 动画和交互式应用。

  3. Two.js:Two.js 是一个轻量级的 2D 绘图库,它提供了一系列的 API 和工具,用于在 Canvas 上创建图形、动画和交互式应用。它具有简单易用的 API,适合用于创建简单的 Canvas 动画和图形应用。

  4. Three.js: 一个用于创建 3D 图形的 JavaScript 库,虽然它主要用于 WebGL,但也可以在 Canvas 上创建 3D 图形,并提供了丰富的 3D 渲染功能和特效支持。

这些基于 Canvas 的动画库都具有不同的特点和适用场景,开发者可以根据自己的需求和偏好选择合适的库来创建 Canvas 动画和应用。

更多关于 Canvas 内容可以阅读 HOW - Canvas 入门系列(一)

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

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

相关文章

【Linux】动态库与静态库的底层比较

送给大家一句话&#xff1a; 人生最遗憾的&#xff0c;莫过于&#xff0c;轻易地放弃了不该放弃的&#xff0c;固执地坚持了不该坚持的。 – 柏拉图 (x(x_(x_x(O_o)x_x)_x)x) (x(x_(x_x(O_o)x_x)_x)x) (x(x_(x_x(O_o)x_x)_x)x) 底层比较 1 前言2 编译使用比较2 如何加载Than…

java项目之企业OA管理系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的企业OA管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 企业OA管理系统的主要使用…

Nios-II编程入门实验

文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 …

Vue3 查看真实请求地址

上回说到Vue2查看真实请求地址&#xff0c;那么Vue3该如何查看呢&#xff1f; 传送门&#xff1a; Vue2 查看真实请求地址 1. bypass函数 使用bypass函数获取代理结果&#xff0c;设置响应头&#xff08;请求头设置未生效&#xff0c;也可以在响应头上看&#xff09;。 2. …

软件全套资料梳理(需求、开发、实施、运维、安全、测试、交付、认证、评审、投标等)

软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&#xff0c;概要设计说明书&#xff0c…

BGP学习一:关于对等体建立和状态组改变

目录 一.BGP基本概念 &#xff08;1&#xff09;.BGP即是协议也是分类 1.早期EGP 2.BGP满足不同需求 3.BGP区域间传输的优势 &#xff08;1&#xff09;安全性——只传递路由信息 &#xff08;2&#xff09;跨网段建立邻居 4.BGP总结 5.BGP的应用 &#xff08;1&#…

Coursera吴恩达深度学习专项课程01: Neural Networks and Deep Learning 学习笔记 Week 02

Week 02 of Neural Networks and Deep Learning Course Certificate 本文是学习 https://www.coursera.org/learn/neural-networks-deep-learning 这门课的笔记 Course Intro 文章目录 Week 02 of Neural Networks and Deep LearningLearning Objectives [1] Logistic Regres…

YOLOv8_seg预测流程-原理解析[实例分割理论篇]

YOLOv8_seg的网络结构图在博客YOLOv8网络结构介绍已经更新了,由网络结构图可以看到相对于目标检测网络,实例分割网络只是在Head层不相同,如下图所示,在每个特征层中增加了Mask层(浅紫色),这和同一层的Box,cls的shape大小一样;另外还利用8080尺度的特征图,经过卷积+上…

如何快速的追加文章的内容(在不知道内容的情况下)

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、打开工具&#xff0c;切换到文章模块下&#xff0c;快捷键&#xff1a;Ctrl1 2、新建一个文章做演示&#xff0c;001 3、添加一个内容&#xff0c;就随便…

冯喜运:5.12黄金回撤继续上涨,下周原油走势分析

【黄金消息面分析】&#xff1a;本周&#xff0c;黄金市场迎来了自4月中旬以来的最佳单周表现。周五&#xff08;3月9日&#xff09;&#xff0c;金价攀升至2360.54美元/盎司&#xff0c;涨幅0.62%&#xff0c;而纽约商品交易所6月交割的黄金期货价格上涨1.5%&#xff0c;收报2…

bevformer详解(1):论文介绍

3D 视觉感知任务,包括基于多摄像头的3D检测和地图分割对于自动驾驶系统至关重要。本文提出了一种名为BEVFormer的新框架,它通过使用空间和时间的Transformer 学习统一的BEV表示来支持多个自动驾驶感知任务。简而言之,BEVFormer通过预定义的网格形式的Bev Query与空间和时间空…

No module named ‘sklearn.metrics.ranking‘ 解决方法

错误代码 from sklearn.metrics.classification import * from sklearn.metrics.ranking import * 错误原因 sklearn这个文件夹下的_classification和_ranking前面有下划线&#xff01; 解决方法 第一步&#xff1a;找到sklearn位置&#xff0c;可以打开命令行输入 pip sh…

使用 Spring Boot 配合策略模式增强系统接口扩展能力

使用 Spring Boot 配合策略模式增强系统接口扩展能力 在软件开发中&#xff0c;系统的可扩展性是一个至关重要的方面。而策略模式是一种常见的设计模式&#xff0c;它可以帮助我们实现灵活的算法选择和系统功能扩展。结合 Spring Boot 框架&#xff0c;我们可以更加方便地利用策…

systrace使用

systrace使用 chrome://tracing/ 抓trace方法 1.脚本 在sdk/platformtools/systrace文件目录下执行&#xff1a; python2 systrace.py -b 32000 -o setting_qian.html gfx input view webview wm am audio video camera app ss sched irq freq idle disk load sync workq reg…

Java入门基础学习笔记18——赋值运算符

赋值运算符&#xff1a; 就是“”&#xff0c;就是给变量赋值的&#xff0c;从右边往左边看。 int a 10; // 把数据赋值给左边的变量a存储。 扩展赋值运算符&#xff1a; 注意&#xff1a;扩展的赋值运算符隐含了强制类型转换。 package cn.ensource.operator;public class…

1062: 有向图的边存在判断

解法&#xff1a; #include<iostream> #include<vector> using namespace std; int arr[100][100]; int main() {int n;int x, y;cin >> n >> x >> y;for (int i 0; i < n; i) {for (int j 0; j < n; j) {cin >> arr[i][j];}}if …

后端常用技能:基于easy-poi实现excel一对多、多对多导入导出【附带源码】

0. 引言 在业务系统开发中&#xff0c;我们经常遇到excel导入导出的业务场景&#xff0c;普通的excel导入导出我们可以利用 apache poi、jxl以及阿里开源的easyexcel来实现&#xff0c;特别easyexcel更是将excel的导入导出极大简化&#xff0c;但是对于一些负载的表格形式&…

Linux配置两个局域网间的网络转发

网络拓扑如上图所示&#xff0c;有192.168.1.0(255.255.255.0)&#xff0c;192.168.2.0(255.255.255.0)两个局域网。若要使host1可直接通过ip地址访问host3&#xff0c;则需在host2中配置路由转发。 host2 配置静态路由&#xff08;系统一般会自动配置&#xff09; # 添加静…

WEB后端复习——JSP、EL、JSTL

JSP:Java Serve Pages(Java服务器页面) 运行在服务器的脚本、在静态网页HTML代码中嵌入java 优势特点 1.被编译后可以多次直接运行&#xff0c;代码执行效率高&#xff08;一次加载、多次可用&#xff09; 2.动态代码封装&#xff0c;组件可重用性高&#xff08;JavaBean EJ…

《Fundamentals of Power Electronics》——转换器的传递函数

转换器的工程设计过程主要由以下几个主要步骤组成&#xff1a; 1. 定义了规范和其他设计目标。 2. 提出了一种电路。这是一个创造性的过程&#xff0c;利用了工程师的物理洞察力和经验。 3. 对电路进行了建模。组件和系统的其他部分适当建模&#xff0c;通常使用供应商提供的…