当前位置: 首页 > 科技观察

Amazing!巧用 CSS 视差实现酷炫交互动效

时间:2023-03-12 01:16:30 科技观察

惊人的!使用CSS视差实现很酷的交互效果技巧,做出一些有趣的交互效果。关于利用CSS实现滚动视差效果,之前有一篇文章详细介绍了具体的解决方案——CSS实现视差效果[1]。有兴趣的同学可以先看看这篇文章。这里会用到这样一个纯CSS的视差技术:使用transform:translate3d实现滚动视差这里使用CSS3D来实现滚动视差效果。原理是:我们给容器设置transform-style:preserve-3d和perspective:xpx,那么这个容器中的子元素就会位于3D空间。然后为子元素设置不同的transform:translateZ()。这时候不同元素在3DZ轴方向距离屏幕(我们的眼睛)的距离也是不同的。滚动滚动条时,由于子元素设置了不同的transform:translateZ(),它们滚动相对于屏幕(我们的眼睛)的垂直距离translateY也不同,从而达到滚动视差的效果。关于transform-style:preserve-3d和perspective本文不展开太多篇幅。读者默认是有一定了解的,不是特别清楚。你可以先了解一下CSS3D。核心代码表示为:translateZ(-1)

translateZ(-2)
translateZ(-3)
html{height:100%;溢出:隐藏;}正文{透视:1px;变换样式:保留-3d;高度:100%;溢出-y:滚动;overflow-x:hidden;}.g-container{height:150%;:平移Z(-2px);}.section-three{变换:translateZ(-3px);}}总结就是父元素设置了transform-style:preserve-3d和perspective:1px,子元素设置了不同的transform:translateZ,scrollingScrollbar,效果如下:css3dparallaxCodePenDemo--CSS3Dparallax[2].显然,当滚动条滚动时,不同子元素的位移程度在视觉上是不同的,达到了所谓的滚动视差效果。借助CSS视差实现炫酷的交互动画效果OK,有了上面的铺垫,我们来看看这两个有趣的交互效果吧。由wheatup友情提供,群内日服首张截图。先看第一个效果:效果是文字以不同高度层层交替显示,滚动过程中会有明显的3D视差效果。这个效果并不难,核心在于:使用transform-style:preserve-3d和perspective来构建不同的图层效果,创建视差效果。使用::before和::after元素创建3D效果。我们来看一个最小化的DEMO:.g-container{height:150vh;透视图:600px;}.g-box{宽度:200px;高度:200px;背景:#999;变换风格:保留-3d;&::before,&::after{内容:“”;位置:绝对;右:0;左:0;变换样式:保留3d;高度:200px;&::before{transform-origin:topcenter;顶部:0;变换:旋转X(-90度);}&::after{transform-origin:bottomcenter;底部:0;变换:旋转X(90度);}}滚动g-container容器得到3D效果:因为需要视差效果,我们需要给不同的layer分配不同的translateZ(),我们稍微修改一下代码,给每个g-box中间,加上more一层普通的div,然后给每个g-box加上一个translateZ()。.g-container{width:400px;高度:150vh;透视:800px;}.g-normal{宽度:200px;高度:200px;背景:#666;变换样式:保留3d;}.g-box{宽度:200px;高度:200px;背景:#999;:保留-3d;转换:translate3d(0,0,200px);&::before,&::after{//...保持不变}}由于g-box和g-normal的translateZ值不同,所以在滚动时会产生视差效果。由于g-box的translateZ值为translateZ(200px),两个伪元素的rotateX正负90deg,高度为200px,所以g-box和g-normal可以通过两个伪元素连接起来-g-box的元素。最终效果如上图:DEMO完整代码:CodePenDemo-3DParallaxScroll[3]。CSS滚动视差动画2OK,下面第二个滚动视差动画也很有意思。先看原版,同样来自wheatup[4]的CodePen:CodePenDemo--3DChatViewer[5]。这里的核心还是利用了CSS3D的能力,但是由于动画效果是通过滚动触发的,并且有一定的从模糊到清晰的淡入效果,所以还是有一定的JavaScript代码量。有兴趣的可以看看上面的源码。本文将尝试使用CSS的@Property和CSS的最新特性@scroll-timeline来还原JavaScript实现的部分效果。当然,无论是否使用JavaScript,核心3D部分首先使用CSS。我们首先需要这样一个结构://...重复N次.g-wrapper{width:100vw;高度:100vh;}.g-inner{位置:相对;高度:100%;显示:弹性;弹性方向:列;证明内容:居中;对齐项目:居中;gap:10px;}.g-item{width:300px;高度:100px;background:#000;}大概是这样的效果:然后,我们添加一些CSS3D转换:.g-wrapper{//...同上perspective:200px;transform-style:preserve-3d;}.g-inner{//...同上保持一致transform-style:preserve-3d;转换:translateY(calc(-50%+100px))translateZ(0)rotateX(90deg);transform-origin:bottomcenter;}可以得到这样的透视效果:由于容器g-inner绕X轴进行90deg翻转,即rotateX(90deg),我们给g-item反向旋转并翻转卡片背面:.g-wrapper{//..与上面代码一致perspective:200px;变换风格:压力erve-3d;}.g-inner{//...与上述代码一致transform-style:preserve-3d;转换:translateY(calc(-50%+100px))translateZ(0)rotateX(90deg);transform-origin:bottomcenter;}.g-item{//...和上面的代码一致transform:rotateX(-90deg);}可以得到这样的透视效果:此时,我们给容器一个translateZ的动画:.g-inner{animation:move10sinfinitelinear;}@keyframesmove{100%{transform:translateY(calc(-50%+100px))translateZ(calc(100vh+120px))rotateX(90deg);}}这样,整个动画的原型就完成了。通过控制父元素的透视大小和容器的translateZ,得到一个不断移动到透视前方的动画效果:CodePenDemo--CSS3DEffectDemo[6]结合css@scroll-timeline,用css控制滚动和动画,那么如何用css把这个动画和滚动操作结合起来呢?前不久介绍了CSS的一个重磅特性来了,终于来了,动画杀手@scroll-timeline[7],使用它可以实现CSS动画和滚动操作的结合,下面我们就用它来修改一下代码:Loremipsumdolorsitametconsecteturadipisicingelit.//...重复N@property--phase{syntax:'';继承:假的;初始值:15px;}.g-scroll{宽度:100%;高度:1000vh;}.g-wrapper{位置:固定;宽度:100vw;高度:100vh;视角:200px;变换样式:保留3d;}.g-inner{位置:相对;高度:100%;//省略一些flexlayout代码和上面一致transform-style:preserve-3d;转换:translateY(calc(-50%+100px))translateZ(var(--phase))rotateX(90deg);变换原点:底部中心;动画名称:移动;动画持续时间n:1秒;animation-timeline:box-move;}.g-item{width:300px;高度:200px;颜色:#fff;背景:#000;变换:rotateX(-90deg);}@scroll-timelinebox-move{source:selector("#g-scroll");方向:“垂直”;}@keyframes移动{0%{--phase:0;}100%{--phase:calc(100vh+100px);}}相比上面的DEMO,我们主要是增加了@scroll-timeline的代码,我们增加了一个超长的容器.g-scroll,其滚动动作使用了@scroll-timelinebox-move{}规则和动画-timeline:box-move是绑定的,这样我们就可以使用滚动来触发@keyframesmove{}CSS动画效果如下:在原来的效果中,有一些使用JavaScript结合滚动距离控制的模糊变化。这个,我们使用background-filter:blur()也可以简单的模拟一下。让我们简单地添加另一层g-mask:Loremipsumdolorsitametconsecteturadipisicingelit.//...重复N//其他不变.g-mask{position:fixed;宽度:100vw;高度:100vh;背景滤镜:模糊(5px);transform:translateZ(0);}这样基本还原了原来的效果,而我们使用且只使用CSS:CodePenDemo--PureCSSScrollAnimation2(ChromeOnly&&SupportScrollTimeline)[8]。综上所述,当然,在本文后面的效果中,使用了很多兼容性还很差的CSS属性,尤其是@scroll-timeline,目前还处于非常早期的阶段,兼容性是红色的。但是并不妨碍我们学习和感受CSS的美妙。参考资料[1]CSS实现视差效果:https://github.com/chokcoco/iCSS/issues/37。[2]CodePen演示——CSS3D视差:https://codepen.io/Chokcoco/pen/EpOeRm。[3]CodePen演示-3D视差滚动:https://codepen.io/Chokcoco/pen/NWXymNZ。[4]wheatup:https://codepen.io/wheatup。[5]CodePen演示——3D聊天查看器:https://codepen.io/wheatup/pen/LYLqLpJ。[6]CodePenDemo--CSS3D效果演示:https://codepen.io/Chokcoco/pen/NWXaoPy。[7]来了,终于来了,动画杀手@scroll-timeline:https://github.com/chokcoco/iCSS/issues/166。[8]CodePen演示——纯CSS滚动动画2(仅限Chrome&&支持ScrollTimeline):https://codepen.io/Chokcoco/pen/XWVBbER。