原来利用纯CSS也能实现文字轮播与图片轮播!
时间:2022-06-10 [网络编程]作者:fabuyuan 浏览:5 次
今天,分享一个实际业务中能够用得上的动画技巧。【推荐学习:css视频教程】
巧用逐帧动画,配合补间动画实现一个无限循环的轮播效果,像是这样:
看到上述示意图,有同学不禁会发问,这不是个非常简单的位移动画么?
我们来简单分析分析,从表面上看,确实好像只有元素的 transform: translate()
在位移,但是注意,这里有两个难点:
这是个无限轮播的效果,我们的动画需要支持任意多个元素的无限轮播切换
因为是轮播,所以,运行到最后一个的时候,需要动画切到第一个元素
到这里,你可以暂停思考一下,如果有 20 个元素,需要进行类似的无限轮播播报,使用 CSS 实现,你会怎么去做呢?
逐帧动画控制整体切换
首先,我需要利用到逐帧动画效果,也被称为步骤缓动函数,利用的是 animation-timing-function
中,的 steps,语法如下:
{ /* Keyword values */ animation-timing-function: step-start; animation-timing-function: step-end; /* Function values */ animation-timing-function: steps(6, start) animation-timing-function: steps(4, end); }
如果你对 steps
的语法还不是特别了解,强烈建议你先看看我的这篇文章 -- 深入浅出 CSS 动画,它对理解本文起着至关重要的作用。
好的,还是文章以开头的例子,假设我们存在这样 HTML 结构:
<div class="g-container"> <ul> <li>Lorem ipsum 1111111</li> <li>Lorem ipsum 2222222</li> <li>Lorem ipsum 3333333</li> <li>Lorem ipsum 4444444</li> <li>Lorem ipsum 5555555</li> <li>Lorem ipsum 6666666</li> </ul> </div>
首先,我们实现这样一个简单的布局:
在这里,要实现轮播效果,并且是任意个数,我们可以借助 animation-timing-function: steps()
:
:root { // 轮播的个数 --s: 6; // 单个 li 容器的高度 --h: 36; // 单次动画的时长 --speed: 1.5s; } .g-container { width: 300px; height: calc(var(--h) * 1px); } ul { display: flex; flex-direction: column; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { width: 100%; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(0, calc(var(--s) * var(--h) * -1px)); } }
别看到上述有几个 CSS 变量就慌了,其实很好理解:
calc(var(--speed) * var(--s))
:单次动画的耗时 * 轮播的个数,也就是总动画时长steps(var(--s))
就是逐帧动画的帧数,这里也就是steps(6)
,很好理解calc(var(--s) * var(--h) * -1px))
单个 li 容器的高度 * 轮播的个数,其实就是 ul 的总体高度,用于设置逐帧动画的终点值
上述的效果,实际如下:
如果给容器添加上 overflow: hidden
,就是这样的效果:
这样,我们就得到了整体的结构,至少,整个效果是循环的。
但是由于只是逐帧动画,所以只能看到切换,但是每一帧之间,没有过渡动画效果。所以,接下来,我们还得引入补间动画。
利用补间动画实现两组数据间的切换
我们需要利用补间动画,实现动态的切换效果。
这一步,其实也非常简单,我们要做的,就是将一组数据,利用 transform
,从状态 A 位移到 状态 B。
单独拿出一个来演示的话,大致的代码如下:
<div class="g-container"> <ul style="--s: 6"> <li>Lorem ipsum 1111111</li> <li>Lorem ipsum 2222222</li> <li>Lorem ipsum 3333333</li> <li>Lorem ipsum 4444444</li> <li>Lorem ipsum 5555555</li> <li>Lorem ipsum 6666666</li> </ul> </div>
:root { --h: 36; --speed: 1.2s; } ul li { height: 36px; animation: liMove calc(var(--speed)) infinite; } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(0, -36px); } }
非常简单的一个动画:
基于上述效果,我们如果把一开始提到的 逐帧动画 和这里这个 补间动画 结合一下,ul 的整体移动,和 li 的 单个移动叠在在一起:
:root { // 轮播的个数 --s: 6; // 单个 li 容器的高度 --h: 36; // 单次动画的时长 --speed: 1.5s; } .g-container { width: 300px; height: calc(var(--h) * 1px); } ul { display: flex; flex-direction: column; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { width: 100%; animation: liMove calc(var(--speed)) infinite; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(0, calc(var(--s) * var(--h) * -1px)); } } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(0, calc(var(--h) * -1px)); } }
就能得到这样一个效果:
Wow,神奇的化学反应产生了!基于 逐帧动画 和 补间动画 的结合,我们几乎实现了一个轮播效果。
当然,有一点瑕疵,可以看到,最后一组数据,是从第六组数据 transform 移动向了一组空数据:
末尾填充头部第一组数据
实际开发过轮播的同学肯定知道,这里,其实也很好处理,我们只需要在末尾,补一组头部的第一个数据即可:
改造下我们的 HTML:
<div class="g-container"> <ul> <li>Lorem ipsum 1111111</li> <li>Lorem ipsum 2222222</li> <li>Lorem ipsum 3333333</li> <li>Lorem ipsum 4444444</li> <li>Lorem ipsum 5555555</li> <li>Lorem ipsum 6666666</li> <!--末尾补一个首条数据--> <li>Lorem ipsum 1111111</li> </ul> </div>
这样,我们再看看效果:
Beautiful!如果你还有所疑惑,我们给容器加上 overflow: hidden
,实际效果如下,通过额外添加的最后一组数据,我们的整个动画刚好完美的衔接上,一个完美的轮播效果:
完整的代码,你可以戳这里:CodePen Demo -- Vertical Infinity Loop
https://codepen.io/Chokcoco/pen/RwQVByx
横向无限轮播
当然,实现了竖直方向的轮播,横向的效果也是一样的。
并且,我们可以通过在 HTML 结构中,通过 style 内填写 CSS 变量值,传入实际的 li 个数,以达到根据不同 li 个数适配不同动画:
<div class="g-container"> <ul style="--s: 6"> <li>Lorem ipsum 1111111</li> <li>Lorem ipsum 2222222</li> <li>Lorem ipsum 3333333</li> <li>Lorem ipsum 4444444</li> <li>Lorem ipsum 5555555</li> <li>Lorem ipsum 6666666</li> <!--末尾补一个首尾数据--> <li>Lorem ipsum 1111111</li> </ul> </div>
整个动画的 CSS 代码基本是一致的,我们只需要改变两个动画的 transform
值,从竖直位移,改成水平位移即可:
:root { --w: 300; --speed: 1.5s; } .g-container { width: calc(--w * 1px); overflow: hidden; } ul { display: flex; flex-wrap: nowrap; animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite; } ul li { flex-shrink: 0; width: 100%; height: 100%; animation: liMove calc(var(--speed)) infinite; } @keyframes move { 0% { transform: translate(0, 0); } 100% { transform: translate(calc(var(--s) * var(--w) * -1px), 0); } } @keyframes liMove { 0% { transform: translate(0, 0); } 80%, 100% { transform: translate(calc(var(--w) * -1px), 0); } }
这样,我们就轻松的转化为了横向的效果:
完整的代码,你可以戳这里:CodePen Demo -- Horizontal Infinity Loop
https://codepen.io/Chokcoco/pen/JjpNBXY
轮播图?不在话下
OK,上面的只是文字版的轮播,那如果是图片呢?
没问题,方法都是一样的。基于上述的代码,我们可以轻松地将它修改一下后得到图片版的轮播效果。
代码都是一样的,就不再列出来,直接看看效果:
完整的代码,你可以戳这里:CodePen Demo -- Horizontal Image Infinity Loop
https://codepen.io/Chokcoco/pen/GRQvqgq
掌握了这个技巧之后,你可以将它运用在非常多只需要简化版的轮播效果之上。
再简单总结一下,非常有意思的技巧:
利用 逐帧动画,实现整体的轮播的循环效果
利用 补间动画,实现具体的 状态A 向 状态B* 的动画效果
逐帧动画 配合 补间动画 构成整体轮播的效果
通过向 HTML 结构末尾补充一组头部数据,实现整体动画的衔接
通过 HTML 元素的 style 标签,利用 CSS 变量,填入实际的参与循环的 DOM 个数,可以实现 JavaScript 与 CSS 的打通
(学习视频分享:web前端)
以上就是原来利用纯CSS也能实现文字轮播与图片轮播!的详细内容,更多请关注站长家园其它相关文章!
本文标签: 前端css3cssjavascript动画
转载请注明来源:原来利用纯CSS也能实现文字轮播与图片轮播!
本文永久链接地址:https://www.adminjie.com/post/13342.html
免责声明:
本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
附:
二○○二年一月一日《计算机软件保护条例》第十七条规定:为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬!鉴于此,也希望大家按此说明研究软件!
版权声明:
一、本站致力于为软件爱好者提供国内外软件开发技术和软件共享,着力为用户提供优资资源。
二、本站提供的部分源码下载文件为网络共享资源,请于下载后的24小时内删除。如需体验更多乐趣,还请支持正版。
三、我站提供用户下载的所有内容均转自互联网。如有内容侵犯您的版权或其他利益的,若有侵犯你的权益请:提交版权证明文件到邮箱 2225329873#qq.com(#换为@) 站长会进行审查之后,情况属实的会在三个工作日内为您删除。
更多精彩内容
- VUE中V-IF条件判断改变元素的样式操作
- Discuz如何解决安装时报错run_sql_error
- 低版本VS项目在VS2019无法正常编译的问题
- PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
- Oracle数据库的实例/表空间/用户/表之间关系简单讲解
- RSA2是啥?PHP-RSA2签名验证怎么实现?
- app是什么应用程序的简称
- 华为dubal20是什么型号
- 小程序大小超限除了分包还能怎么做?如何避免和解决大小限制?
- 电脑显示信号线无连接是什么意思
- ana an00华为是什么型号
- html5中onclick是什么意思
- 超清视效是什么意思
- vivov1818a是什么手机型号
- html5的标题标记一共有几个等级

- 最新文章
-
-
linux中的mysql有10061错误怎么办
解决方法:1、root用户登录到mysql命令行,并利用“vi/etc/mysql/mysql.conf.d/mysqld.cnf”命令将“bind-addr...
-
归纳总结Excel超级表的应用
本篇文章给大家带来了关于excel的相关知识,其中主要整理了超级表应用的相关问题,包括了制作表格、汇总、动态范围等等内容,下面一起来看一下,希望对大家有帮助。手...
-
简单聊聊JavaScript中的事件监听事件的传播
本篇文章给大家带来了关于javascript的相关知识,其中主要整理了事件监听的相关问题,包括了什么是事件监听、设置事件监听的方法等等内容,下面一起来看一下,希...
-
一文掌握Java8新特性Stream流的概念和使用总结
本篇文章给大家带来了关于java的相关知识,其中主要整理了Stream流的概念和使用的相关问题,包括了Stream流的概念、Stream流的获取、Stream流...
-
Python图像处理之PIL库
本篇文章给大家带来了关于python的相关知识,其中主要整理了PIL库的相关问题,PIL库是一个具有强大图像处理能力的第三方库,不仅包含了丰富的像素、色彩操作功...
-
- 热门文章
-
-
VUE中V-IF条件判断改变元素的样式操作
这篇文章主要介绍了VUE中V-IF条件判断改变元素的样式操作,具有很好的参考价值,希望对大家有所帮助。一起跟随想过来看看吧...
-
Discuz如何解决安装时报错run_sql_error
问题环境VMware虚拟机Centos7.3PHP7.0MySQL8.0NGINX1.14Discuz3.4问题还原本地环境为PHP5.6+MySQL5.6在安...
-
低版本VS项目在VS2019无法正常编译的问题
低版本VS项目在VS2019无法正常编译的问题这里指的编译并不准确,只是为了方便说明。后有(未安装),201?...
-
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
实现原理使用redis链表来做,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,推荐使用。实现步骤第一步,先将商品库存入队列/**.trigge...
-
Oracle数据库的实例/表空间/用户/表之间关系简单讲解
完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例。Oracle是一种数据库管理系统,是一种关系型的数据库管理系统。我们用这些高级权限账号...
-