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

CSS动画旋转魔方转盘

时间:2023-03-30 16:57:25 CSS

下面我将一步步讲解如何使用纯CSS实现旋转魔方转盘的效果。总的来说,我们需要实现以下两个主要功能:构建一个可以旋转的立方体,让立方体具备基本轮播的特性,但是在完成以上两点之前,我们需要了解或者熟悉一下基础知识CSS3实现其功能点:transitiontransformperspectivepreserve-3danimationtransition属性---过渡效果transition:属性durationtiming-functiondelay;这个属性大家应该很熟悉了,我就不多说了,把它所有的子属性都列出来。Transitionproperty---transitionduration---transitionfunction(curve)---transitiondelaytransition-timing-function:linear|ease|ease-in|ease-out|ease-in-out;basictransitionwithnativeFunctiontransform属性---元素的2D或3D转换它有几种常用的转换方式:scalescale3dtranslatetranslate3drotaterotate3d等。transform-origin:x轴y轴z轴;设置旋转元素的基点位置transform-style:preserve-3d;让变换后的子元素保留3D变换(与perspective一起使用)perspective属性---让元素实现3D透视效果perspective:1000px;transform有两种写法:perspective(1000px);该属性使物体具有立体的3D透视效果,值越大,此时物体离我们眼睛在屏幕上看到的物体越远,反之,如果它的值越小,则为更接近我们的视角,即屏幕上显示的尺寸更大。与preserve-3d一起使用,为需要实现3D效果的父元素构建舞台透视,使其子元素实现真正的3D变换。一个基本的立方体需要结合以上三个属性来实现。立方体

重要的CSS样式.cube-wrap{width:300px;高度:300px;视角:1000px;位置:相对;}.cube-wrap.cube{宽度:100%;高度:100%;位置:绝对;变换样式:保留3d;过渡:所有.5s缓和;}.cube-wrap.cube.cube-face{宽度:100%;高度:100%;位置:绝对;溢出:隐藏;不透明度:0.9;border:1pxsolid#ccc;}.cube-wrap.cube.立方体面img{宽度:100%;height:100%;}.cube-face.front{transform:translateZ(150px);}.cube-face.back{transform:rotateX(180deg)translateZ(150px);}.cube-face.left{transform:rotateY(-90deg)translateZ(150px);}.cube-face.right{transform:rotateY(90deg)translateZ(150px);}.cube-face.top{transform:rotateX(90deg)translateZ(150px);}.cube-face.bottom{transform:rotateX(-90deg)translateZ(150px);}这里父元素使用perspective和preserve-3d,然后是子元素的3D变换效果那么关键是,如何以上代码拼接成一个完整的立方体?在浏览器开发者工具中不难发现类名cube的元素位置在立方体中间的那一侧。这样我们就有了一个想法,如何使用代码来构造立方体的每一面。首先,必须明确transform相关变换时建立的空间直角坐标系x、y、z轴的方向。即以电脑屏幕为平面,水平方向为x轴,垂直方向为y轴,垂直于屏幕的方向为z轴。那么如何构造立方体的六个面就变得非常简单了。立方体面的初始位置在中间,整个立方体的长度为300px,所以translateZ(150px)就是正面。要构造背面,首先需要将初始表面逆时针反转180度。此时前面指向后面,只需要再平移Z(150px)即可。构造左侧需要先绕y轴旋转rotateY(-90deg),对应的右侧为rotateY(90deg),然后translateZ(150px),其余两条同理进行相应的逻辑。能。需要注意的是,当曲面绕轴旋转时,逆时针旋转为正值,顺时针旋转为负值。动画属性绝对是CSS3动画中最重要的属性,它的每一个子属性都值得仔细研究。animation:namedurationtiming-functiondelayiteration-countdirectionfill-modeplay-state;animation-delay:1s;设置为负值时,立即开始动画,跳过1秒前的动画animation-direction:normal|reverse|alternate|alternate-reverse;定义是否交替播放动画和反向交替播放动画。动画在奇数次(1,3,5...)正向播放,偶数次(2,4,6...)反向播放alternate-reverse动画在奇数次(1,3,5...)反向播放3,5...),偶数时间前进(2,4,6...)animation-fill-mode:none|forwards|backwards|both;指定动画不播放时元素所应用的样式forward动画结束后停留在最后一帧backward开始动画时的第一帧animation-delay属性both同时实现前进和后退的效果时间动画播放状态:暂停|运行;控制动画是暂停还是运行。@keyframes设置动画关键帧,这里我们使用from...to或者percentage来实现自定义动画动画细节接下来我们给已经建好的立方体添加动画动画:.cube-wrap.cube{....animation:旋转10s线性无限;}@keyframes旋转{来自{transform:rotateX(45deg)rotateY(45deg);}到{变换:rotateX(405deg)rotateY(765deg);}}轮播现在我们已经实现了立方体效果可以自由旋转的能力了,接下来还需要完成轮播的基本功能。左右按钮切换底部按钮切换在实现这两个功能之前,我们需要了解两个强大的HTML标签。它们的组合使用实现了轮播中点击和切换的效果。它们是label和input标签,我们先来看看它们的基本用法。点击label标签,id为1的input标签被选中。label标签中的for与input标签Link中的id相关,当input标签中的type为radio时,就是一个选择框的效果,里面有个checked属性(如果要实现效果一个单选框的,需要设置name="xxx",此时的名称必须一致,如下图就是使用这个效果)下面开始实现具体的效果。......首先实现左侧和底部的CSS样式.cube_left.cube_action{left:-75px;顶部:50%;transform:translateY(-50%);}.cube_right.cube_action{right:-75px;顶部:50%;transform:translateY(-50%);}.cube_action{background-color:#fafafa;边界半径:50%;游标:指针;显示:无;宽度:40px;高度:40px;不透明度:0.15;位置:绝对;transition:opacity0.5s缓和;z-index:5;}.cube_action:hover{opacity:1;}.cube_action::before{border-bottom:4pxsolid#111;border-right:4pxsolid#111;内容:'';显示:块;高度:25%;左:50%;位置:绝对;顶部:50%;宽度:25%;变换:平移(-70%,-50%)旋转(-45deg);}.cube_left.cube_action::before{变换:平移(-40%,-50%)旋转(135deg);}.indicators{位置:绝对;左:0;右:0;底部:-80px;填充:20px;文本对齐n:中心;不透明度:0;过渡:不透明度.3s;}.container:hover.indicators{不透明度:1;}.indicators.indicator{背景颜色:#fafafa;边界半径:50%;游标:指针;显示:内联块;宽度:14px;高度:14px;边距:6px;opacity:.15;}.controller{display:none;}写完上面的代码,我们是看不到我们想要的结果的,因为它们都需要hover事件来触发。现在让我们设置最外层容器的样式并定义一个入口动画。.container{宽度:600px;高度:600px;位置:绝对;顶部:50%;左:50%;边距顶部:-300px;左边距:-300px;过渡:所有.5s轻松;变换:缩放(0.25);}.容器:悬停{变换:缩放(1);}.容器:悬停.cube-wrap.cube{动画:入口.5s缓动;}@keyframes入口{来自{变换:rotateX(-225deg)旋转Y(-225deg);}}当鼠标移入立方体时,动画被旋转和进入所取代。那么重点又出现了,CSS是如何实现点击切换轮播图片的呢?原理很简单,其实就是上面提到的label标签和input标签的结合,达到了惊人的效果。.controller:nth-of-type(1):checked~.cube{transform:translateZ(-150px);}.controller:nth-of-type(2):checked~.cube{转换:translateZ(-150px)rotateX(-180deg);}.controller:nth-of-type(3):checked~.cube{变换:translateZ(-150px)rotateY(90deg);}.controller:nth-of-type(4):checked~.cube{transform:translateZ(-150px)rotateY(-90deg);}.controller:nth-of-type(5):checked~.cube{transform:translateZ(-150px)rotateX(-90deg);}.controller:nth-of-type(6):checked~.cube{transform:translateZ(-150px)rotateX(90deg);}无论是点击左右按钮还是点击底部按钮,都会触发label标签的for因此,该属性链接相应输入标签中的已检查属性。至于如何将对应的边反转为面向屏幕的一面,只需要在构造立方体各边的转换中将符号反转即可。值得注意的是,我们这里使用的CSS选择器也是一个技巧,:nth-of-type(n)选择同类型标签的第n个标签,~符号选择同级标签。现在让我们回过头来看看一开始的HTML结构。indicators中label标签中的for好像能看懂它的逻辑,就是点击哪个标签会触发input标签的checked属性进行相应的3D转换。但是为什么左右按钮的label标签中的for数字顺序看起来不对呢?这里我琢磨了半天,费了九牛二虎之力才弄明白,.cube_left或.cube_right中对应的六个标签重叠在一起,而且都是display:none,很有意思。让我们看下一段代码。.container:hover.controller:nth-of-type(1):checked~.cube_left.cube_action:nth-of-type(1),.container:hover.controller:nth-of-type(1):checked~.cube_right.cube_action:nth-of-type(1){display:block;}.container:hover.controller:nth-of-type(2):checked~.cube_left.cube_action:nth-of-type(2),.container:hover.controller:nth-of-type(2):checked~.cube_right.cube_action:nth-of-type(2){display:block;}................container:hover.controller:nth-of-type(6):checked~.cube_left.cube_action:nth-of-type(6),.container:hover.controller:nth-of-type(6):checked~.cube_right.cube_action:nth-of-type(6){display:block;}现在我们默认是controller中的第一个元素被选中,也就是它的checked属性为true。因此,左右按钮中的label标签中的第一个显示为display:block。如果现在点击左边的按钮,我们想让立方体的底部出现在屏幕的前面,所以for应该设置为6。如果你点击右边的按钮,那么第一个label的for应该设置为到2。按照这个逻辑,我们也就明白为什么.cube_left或.cube_right中的for属性是乱序的了。