当前位置: 首页 > Web前端 > HTML5

前端日常实战:133#视频演示如何使用CSS和GSAP制作多关键帧的连续动画

时间:2023-04-05 11:17:28 HTML5

效果预览在当前页面点击右侧“点击预览”按钮进行预览,点击链接全屏预览。https://codepen.io/comehop??e/pen/eLMKJG互动视频本视频为互动视频,您可以随时暂停视频,编辑视频中的代码。请使用chrome、safari、edge打开观看。https://scrimba.com/p/pEgDAM/cdDRmH9源码下载日常前端实战系列完整源码请到github下载:https://github.com/comehop??e/front-end-daily-挑战代码解释定义dom,容器包含10个div子元素,每个div包含1个span元素:

居中显示:body{margin:0;高度:100vh;显示:弹性;对齐项目:居中;证明内容:居中;background-color:lightyellow;}定义容器的大小和样式:.container{width:400px;高度:400px;背景nd:线性渐变(45deg,番茄,金色);边界半径:3%;box-shadow:0010pxrgba(0,0,0,0.3);}在容器中绘制一个元素,它有一个外壳div,里面是一个白色的小方块span:.container{position:relative;}.containerdiv{位置:绝对;宽度:继承;身高:继承;显示:弹性;对齐项目:居中;证明内容:居中;}.containerdivspan{位置:绝对;宽度:40px;高度:40px;background-color:white;}为容器中的元素定义下标变量,让元素的壳依次旋转形成圆形,其中outline为辅助线:.containerdiv{outline:1pxdashedblack;变换:旋转(计算((var(--n)-1)*36deg));}.containerdiv:nth-??child(1){--n:1;}.containerdiv:nth-child(2){--n:2;}.containerdiv:nth-child(3){--n:3;}.containerdiv:nth-child(4){--n:4;}.containerdiv:nth-child(5){--n:5;}.containerdiv:nth-child(6){--n:6;}.containerdiv:nth-child(7){--n:7;}.containerdiv:nth-child(8){--n:8;}.containerdiv:nth-child(9){--n:9;}.containerdiv:nth-c希尔德(10){--n:10;}至此子元素绘制完成,接下来开始编写动画脚本导入GSAP库:定义一个代表子元素选择器的变量:letelements='.containerdivspan';声明一个时间轴对象:letanimation=newTimelineMax();首先设置entrymode由small(第1帧)变为large(第2帧),第2帧没有代码,语义上隐含:animation.from(elements,1,{scale:0});让子元素变成垂直条带并围绕(第3帧)展开:animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25});让垂直条旋转成小方块(第4帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(元素,1,{scaleY:0.25,旋转:180});让小方块变成横条,形成一个圆圈(第5帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(元素,1,{scaleY:0.25,旋转:180}).to(元素,1,{scaleX:1});请注意,由于录制过多帧时scrimba会崩溃,因此第6到11帧不会反映在视频中。让圆圈向内收敛,线变细(第6帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(元素,1,{scaleY:0.25,旋转:180}).to(元素,1,{scaleX:1}).to(元素,1,{y:'-60px',scaleY:0.1});使线条向左摆动(第7帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(elements,1,{y:'-60px',scaleY:0.1}).to(elements,1,{x:'-30px'});让线条向右摆动(第8帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(elements,1,{y:'-60px',scaleY:0.1}).to(elements,1,{x:'-30px'}).to(元素,1,{x:'30px'});然后把横线变成竖线,形状和第3帧类似,只是线更细,向内收敛(第9帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(元素,1,{scaleY:0.25,旋转:180}).to(elements,1,{scaleX:1}).to(elements,1,{y:'-60px',scaleY:0.1}).to(elements,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(元素,1,{x:'0',scaleX:0.1,scaleY:1});线变成水平线,形状类似于第5帧,但线更短(第10帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(elements,1,{y:'-60px',scaleY:0.1}).to(元素,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(元素,1,{x:'0',scaleX:0.1,scaleY:1}).to(elements,1,{scaleX:0.5,scaleY:0.1})水平线稍微展开,变成一个点(第11帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(元素,1,{y:'-60px',scaleY:0.1}).to(元素,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(e元素,1,{x:'0',scaleX:0.1,scaleY:1}).to(元素,1,{scaleX:0.5,scaleY:0.1}).to(元素,1,{y:'-80px',scaleY:0.5,borderRadius:'50%'});让点变成垂直线并向内收缩。这个变化的距离很长,所以动画时间应该更长(第12帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(elements,1,{y:'-60px',scaleY:0.1}).to(元素,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(元素,1,{x:'0',scaleX:0.1,scaleY:1}).to(elements,1,{scaleX:0.5,scaleY:0.1}).to(elements,1,{y:'-80px',scaleY:0.5,borderRadius:'50%'}).to(elements,1,{y:'-10px',scaleX:0.1,scaleY:0.5,borderRadius:'0%',rotation:0});让竖线从中心快速散开,在散开前停顿一下,就像正在发射线一样(第13帧):animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(元素,1,{scaleY:0.25,旋转:180}).to(元素,1,{scaleX:1}).to(元素,1,{y:'-60px',scaleY:0.1}).to(元素,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(元素,1,{x:'0',scaleX:0.1,scaleY:1}).to(元素,1,{scaleX:0.5,scaleY:0.1}).to(元素,1,{y:'-80px',scaleY:0.5,borderRadius:'50%'}).to(elements,1,{y:'-10px',scaleX:0.1,scaleY:0.5,borderRadius:'0%',rotation:0}).to(elements,1,{y:'-300px',delay:0.5});用时间轴缩放放数让动画播放速度加快一倍:animation.from(elements,1,{scale:0}).to(elements,1,{y:'-100px',scaleX:0.25}).to(elements,1,{scaleY:0.25,rotation:180}).to(elements,1,{scaleX:1}).to(元素,1,{y:'-60px',scaleY:0.1}).to(元素,1,{x:'-30px'}).to(元素,1,{x:'30px'}).to(元素,1,{x:'0',scaleX:0.1,scaleY:1}).to(元素,1,{scaleX:0.5,scaleY:0.1}).to(元素,1,{y:'-80px',scaleY:0.5,borderRadius:'50%'}).to(elements,1,{y:'-10px',scaleX:0.1,scaleY:0.5,borderRadius:'0%',rotation:0}).to(elements,1,{y:'-300px',delay:0.5}).timeScale(2);修改声明时间轴的代码,让动画重复播放:letanimation=newTimelineMax({repeat:-1,repeatDelay:1});至此,动画完成隐藏容器外的内容,删除辅助线;.container{overflow:hidden;}.containerdiv{/*outline:1pxdashedblack;*/}最后,装饰页面的一角:body{overflow:hidden;}body::before,body::after{content:'';位置:绝对;宽度:60vmin;高度:60vmin;边界半径:50%;背景:径向渐变(透明25%,金色25%,金色50%,番茄50%);}body::before{left:-30vmin;底部:-30vmin;}正文::之后{右:-30vmin;top:-30vmin;}大功告成!