当前位置:首页 > 科技  > 软件

CSS 实现3d轮播图的一些思路,你学会了吗?

来源: 责编: 时间:2024-07-03 17:21:20 285观看
导读最近在项目中碰到一个比较典型的3d轮播图动效,如下所示:图片说难不难,说简单也不简单,这是一个无限循环的轮播效果,并且个数是固定的,你会如何实现呢?原效果是通过vue的transition组件实现的,感觉有些笨重,思考了一番,发现纯 CS
最近在项目中碰到一个比较典型的3d轮播图动效,如下所示:

oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

说难不难,说简单也不简单,这是一个无限循环的轮播效果,并且个数是固定的,你会如何实现呢?oE328资讯网——每日最新资讯28at.com

原效果是通过vue的transition组件实现的,感觉有些笨重,思考了一番,发现纯 CSS也能实现这样的效果,而且性能更好,实现也更简洁,一起来看看吧!oE328资讯网——每日最新资讯28at.com

一、CSS 动画实现思路

首先来分析一下思路。看着是一个连贯的轮播效果,其实单独看每一个子项,都是完全相同的运动轨迹。oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

然后是这个动画,其实就是6个关键帧,逐一去位移和缩放,如下:oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

然后给每个子项不同的“负延迟”,是不是就刚好错开,形成一个完整的轮播效果了呢?oE328资讯网——每日最新资讯28at.com

无论CSS怎么实现,动画原理就这些了,下面来看几个实现方式oE328资讯网——每日最新资讯28at.com

二、CSS 动画关键帧

首先简单布局一下,先用一个元素实现动画;oE328资讯网——每日最新资讯28at.com

<div class="item"></div>

加点修饰;oE328资讯网——每日最新资讯28at.com

html,body{  font-family: -apple-system, "BlinkMacSystemFont", sans-serif;  margin: 0;  height: 100%;  display: flex;  justify-content: center;  flex-direction: column;  align-items: center;  background: aliceblue;  counter-reset: num;}.item{  position: absolute;  display: grid;  place-content: center;  width: 100px;  height: 100px;  border-radius: 8px;  background-color: #3E65FF;  color: #fff;  font-size: 30px;  counter-increment: num;}

这里的数字是用CSS计数器生成的,效果如下:oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

根据前面的关键帧,很容易用代码实现,就是。oE328资讯网——每日最新资讯28at.com

.item{  animation: slide 12s infinite;}@keyframes slide {  0%,100% {    transform: translate(0%, 0%) scale(1);  }  16.67% {    transform: translate(120%, -30%) scale(0.9);  }  33.33% {    transform: translate(100%, -70%) scale(0.8);  }  50% {    transform: translate(0, -90%) scale(0.7);  }  66.67% {    transform: translate(-100%, -70%) scale(0.8);  }  83.33% {    transform: translate(-120%, -30%) scale(0.9);  }}

这里的16.67%关键帧是将100%进行6等分得到的,如下所示:oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

效果如下:oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

虽然有动画了,但是效果有点奇怪,每次改变位置的时候好像没有停顿,显得过渡有些缓慢,只是有减速和加速的过程,这是默认的ease-in-out的淡入淡出缓冲效果。oE328资讯网——每日最新资讯28at.com

那么,如何拉开一定的间隔呢?也就是希望每次运动的快一点,然后停留一会。其实也很简单,在之前的每个关键点前再添加一个相同的关键帧,比如在16.67%的前面一点6.67%,由于是相同的,所以这段时间内是没有动画的,也就相当于停留了一会。oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

用代码实现就是:oE328资讯网——每日最新资讯28at.com

@keyframes slide {  0%,90%,100% {    transform: translate(0%, 0%) scale(1);  }  6.67%,  16.67% {    transform: translate(120%, -30%) scale(0.9);  }  23.33%,  33.33% {    transform: translate(100%, -70%) scale(0.8);  }  40%,  50% {    transform: translate(0, -90%) scale(0.7);  }  56.67%,  66.67% {    transform: translate(-100%, -70%) scale(0.8);  }  73.33%,  83.33% {    transform: translate(-120%, -30%) scale(0.9);  }}

这样是不是就好多了?oE328资讯网——每日最新资讯28at.com

图片图片oE328资讯网——每日最新资讯28at.com

实现了一个,多个子元素也就好办了。oE328资讯网——每日最新资讯28at.com

<div class="item" style="--i: 0"></div><div class="item" style="--i: 1"></div><div class="item" style="--i: 2"></div><div class="item" style="--i: 3"></div><div class="item" style="--i: 4"></div><div class="item" style="--i: 5"></div>

我们给每个子元素加个CSS变量,然后给每个动画加个“负延迟”,让这个动画提前运行到指定位置;oE328资讯网——每日最新资讯28at.com

.item{   animation: slide 12s calc(-2s * var(--i)) infinite;}

效果如下:oE328资讯网——每日最新资讯28at.com

基本就实现这个这个轮播动画,不过层级还有点问题。oE328资讯网——每日最新资讯28at.com

所以还需要再关键帧里加入层级变化;oE328资讯网——每日最新资讯28at.com

@keyframes slide {  0%,90%,100% {    z-index: 4;    transform: translate(0%, 0%) scale(1);  }  6.67%,  16.67% {    z-index: 3;    transform: translate(120%, -30%) scale(0.9);  }  23.33%,  33.33% {    z-index: 2;    transform: translate(100%, -70%) scale(0.8);  }  40%,  50% {    z-index: 1;    transform: translate(0, -90%) scale(0.7);  }  56.67%,  66.67% {    z-index: 2;    transform: translate(-100%, -70%) scale(0.8);  }  73.33%,  83.33% {    z-index: 3;    transform: translate(-120%, -30%) scale(0.9);  }}

这样就完美了。oE328资讯网——每日最新资讯28at.com

这种实现兼容性最好,只用到了 CSS 动画,兼容市面所有浏览器,可以放心使用oE328资讯网——每日最新资讯28at.com

  • CSS 3d swiper (codepen.io)[1]
  • CSS 3d swiper (juejin.cn)[2]

三、CSS @property

其实目前来说,用上面这种方式就足够了,没有任何问题。oE328资讯网——每日最新资讯28at.com

不过,上面对于中间停顿的处理方式可能有些繁琐,下面再介绍另一种思路,可能更符合常规。oE328资讯网——每日最新资讯28at.com

先思考一下,如果是用 JS要如何实现?是不是可以直接每隔2秒改变位移和缩放,然后通过transition实现过渡效果?oE328资讯网——每日最新资讯28at.com

首先,我们还是需要像之前一样,定义一些关键帧,不过不是直接改变位移和缩放,而是改变一些 CSS变量。oE328资讯网——每日最新资讯28at.com

@keyframes slide {  0%,100% {    --translate: 0,0;    --scale: 1;    --z: 4;  }  16.67% {    --translate: 120%,-30%;    --scale: 0.9;    --z: 3;  }  33.33% {    --translate: 100%,-70%;    --scale: 0.8;    --z: 2;  }  50% {    --translate: 0%,-90%;    --scale: 0.7;    --z: 1;  }  66.67% {    --translate: -100%,-70%;    --scale: 0.8;    --z: 2;  }  83.33% {    --translate: -120%,-30%;    --scale: 0.9;    --z: 3;  }}

然后每个子项就需要用transfrom来应用这些变量了;oE328资讯网——每日最新资讯28at.com

.item{  transform: translate(var(--translate)) scale(var(--scale));  transition: .5s transform;  animation: slide 12s calc(-2s * var(--i)) infinite;}

我们来看看效果:oE328资讯网——每日最新资讯28at.com

好像并没有过渡动画?这是因为animation覆盖了transition,所以需要分离开来,我们嵌套一层父级。oE328资讯网——每日最新资讯28at.com

<div class="item-wrap" style="--i: 0">  <div class="item"></div></div><div class="item-wrap" style="--i: 1">  <div class="item"></div></div><div class="item-wrap" style="--i: 2">  <div class="item"></div></div><div class="item-wrap" style="--i: 3">  <div class="item"></div></div><div class="item-wrap" style="--i: 4">  <div class="item"></div></div><div class="item-wrap" style="--i: 5">  <div class="item"></div></div>

然后将动画写在父级上;oE328资讯网——每日最新资讯28at.com

.item-wrap{  animation: slide 12s calc(-2s * var(--i)) infinite;  display: contents;}

这样就不影响了,效果如下:oE328资讯网——每日最新资讯28at.com

不过还是有点怪怪的。这是因为animation的默认效果也是ease-in-out,所以有这种渐入渐出的效果。我们需要瞬间变化,不需要过渡效果,因为过渡效果可以由transition完成。oE328资讯网——每日最新资讯28at.com

这里我们可以用steps来实现,steps(1)表示直接切换,中间没有任何过渡。oE328资讯网——每日最新资讯28at.com

.item-wrap{  animation: slide 12s calc(-2s * var(--i)) steps(1) infinite;}

这样效果就和前面基本一致了。oE328资讯网——每日最新资讯28at.com

你也可以访问以下链接来查看实际效果:oE328资讯网——每日最新资讯28at.com

  • CSS 3d swiper @property (codepen.io)[3]
  • CSS 3d swiper @property (juejin.cn)[4]

虽然里面没有提到CSS @property,但实际上是依赖这个特性的,因此兼容性稍差,需要Safari 16.4+,Firefox目前还不支持。oE328资讯网——每日最新资讯28at.com

四、CSS 样式查询

抛开兼容性,其实还有一种方式可以实现,而且更容易理解,也更符合JS的思路。oE328资讯网——每日最新资讯28at.com

我们要做的动画很简单,只需要改变一个 CSS变量就行,如下:oE328资讯网——每日最新资讯28at.com

@property --index {  syntax: "<number>";  initial-value: 0;  inherits: false;}@keyframes slide {  0% {    --index: 0;  }  100% {    --index: 6;  }}

通过@property可以让--index变量从0→6一次变化。oE328资讯网——每日最新资讯28at.com

关于这个技巧,之前在多篇文章中都有提到。oE328资讯网——每日最新资讯28at.com

你可能不需要 JS!CSS实现一个计时器。oE328资讯网——每日最新资讯28at.com

如何让CSS计数器支持小数的动态变化?oE328资讯网——每日最新资讯28at.com

还在使用定时器吗?CSS 也能实现电子时钟。oE328资讯网——每日最新资讯28at.com

动画合成小技巧!CSS 实现动感的倒计时效果。oE328资讯网——每日最新资讯28at.com

自定义计数器小技巧!CSS 实现长按点赞累积动画。oE328资讯网——每日最新资讯28at.com

oE328资讯网——每日最新资讯28at.com

实现如下:oE328资讯网——每日最新资讯28at.com

.item-wrap{  display: contents;  animation: slide 12s calc(-2s * var(--i)) steps(6) infinite;}

这样就实现了一个--index不断变化的动画。oE328资讯网——每日最新资讯28at.com

当然仅仅只是这样还不够,我们需要根据这个变量来匹配具体的样式,这就要用到CSS样式查询了,具体实现如下:oE328资讯网——每日最新资讯28at.com

@container style(--index: 0) {  .item {    transform: translate(0, 0) scale(1);    z-index: 4;  }}@container style(--index: 1) {  .item {    transform: translate(120%, -30%) scale(0.9);    z-index: 3;  }}@container style(--index: 2) {  .item {    transform: translate(100%, -70%) scale(0.8);    z-index: 2;  }}@container style(--index: 3) {  .item {    transform: translate(0, -90%) scale(0.7);    z-index: 1;  }}@container style(--index: 4) {  .item {    transform: translate(-100%, -70%) scale(0.8);    z-index: 2;  }}@container style(--index: 5) {  .item {    transform: translate(-120%, -30%) scale(0.9);    z-index: 3;  }}

这段应该很好理解,比如@container style(--index: 5) 表示,当查询到--index为5的时候,下面的样式就生效了,非常像通过 JS 来改变类名一样,这种方式也能实现类似的效果。oE328资讯网——每日最新资讯28at.com

你也可以访问以下链接来查看实际效果:oE328资讯网——每日最新资讯28at.com

  • CSS 3d swiper @style (codepen.io)[5]
  • CSS 3d swiper @style (juejin.cn)[6]

由于要用到样式查询,所以兼容性更差一点,需要Chrome 111+,酌情使用。oE328资讯网——每日最新资讯28at.com

五、总结一下

以上就是本文的全部内容了,共介绍了3种不同的实现思路,兼容性从高到低,大家可以自行选择。oE328资讯网——每日最新资讯28at.com

对了,还有一点,有时候我们需要鼠标hover时暂停动画,这个就体现出CSS的优势了,直接用:hover实现,类似这样oE328资讯网——每日最新资讯28at.com

.wrap:hover .item{    animation-play-state: paused;}

下面总结一下实现要点:oE328资讯网——每日最新资讯28at.com

  1. 整体看着是一个连贯的轮播效果,其实单独看每一个子项,都是完全相同的运动轨迹。
  2. 给每个子项不同的“负延迟”,就能形成一个完整的轮播效果。
  3. 动画本质上是6个关键帧,只是位移和缩放的变化。
  4. 直接使用关键帧虽然有动画,但是效果有点奇怪,每次改变位置的时候好像没有停顿,显得过渡有些缓慢。
  5. 可以手动在每个关键点前再添加一个相同的关键帧,手动停顿一下。
  6. 给每个子元素加个CSS变量,通过这个变量可以计算每个动画的“负延迟”,让这个动画提前运行到指定。
  7. 我们还定义一些关键帧,不过不是直接改变位移和缩放,而是改变一些 CSS变量。
  8. 这样可以实现每隔2秒改变位移和缩放,然后通过transition实现过渡效果。
  9. 这种思路依赖CSS @property,兼容性稍差,需要Safari 16.4+,Firefox目前还不支持。
  10. 还可以通过样式查询,自动匹配每种变量的位移和缩放,更符合常规思路,需要Chrome 111+

本文链接:http://www.28at.com/showinfo-26-98557-0.htmlCSS 实现3d轮播图的一些思路,你学会了吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 六个常见的 Go 接口设计错误

下一篇: 掌握 Python:15 个关于字符串操作的神级单行代码

标签:
  • 热门焦点
  • 影音体验是真的强 简单聊聊iQOO Pad

    大公司的好处就是产品线丰富,非常细分化的东西也能给你做出来,例如早先我们看到了新的vivo Pad2,之后我们又在iQOO Neo8 Pro的发布会上看到了iQOO的首款平板产品iQOO Pad。虽
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 三言两语说透设计模式的艺术-简单工厂模式

    一、写在前面工厂模式是最常见的一种创建型设计模式,通常说的工厂模式指的是工厂方法模式,是使用频率最高的工厂模式。简单工厂模式又称为静态工厂方法模式,不属于GoF 23种设计
  • 企业采用CRM系统的11个好处

    客户关系管理(CRM)软件可以为企业提供很多的好处,从客户保留到提高生产力。  CRM软件用于企业收集客户互动,以改善客户体验和满意度。  CRM软件市场规模如今超过580
  • 自动化在DevOps中的力量:简化软件开发和交付

    自动化在DevOps中扮演着重要角色,它提升了DevOps的效能。通过自动化工具和方法,DevOps团队可以实现以下目标:消除手动和重复性任务。简化流程。在整个软件开发生命周期中实现更
  • 本地生活这块肥肉,拼多多也想吃一口

    出品/壹览商业 作者/李彦编辑/木鱼拼多多也看上本地生活这块蛋糕了。近期,拼多多在App首页&ldquo;充值中心&rdquo;入口上线了本机生活界面。壹览商业发现,该界面目前主要
  • 微博大门常打开,迎接海外画师漂洋东渡

    作者:互联网那些事&ldquo;起猛了,我能看得懂日语了&rdquo;。&ldquo;为什么日本人说话我能听懂?&rdquo;&ldquo;中文不像中文,日语不像日语,但是我竟然看懂了&rdquo;&hellip;&hell
  • iQOO Neo8 Pro评测:旗舰双芯加持 最强性能游戏旗舰

    【Techweb评测】去年10月,iQOO推出了一款Neo7手机,该机搭载了联发科天玑9000+,配备独显芯片Pro+,带来了同价位段最佳的游戏体验,一经上市便受到了诸多用
Top