Css3动画(一) 如何画3D旋转效果或者卫星围绕旋转效果
如何画3D旋转效果或者卫星围绕旋转效果,当然这个也是工作中的一个任务,我在网上翻了一下,并没有找到类似的东西,所以写下来还是费了一番功夫,因此我把它拿出来记录一下,当然替换了一部分内容。好了,话不多说,进入正题。
我们都知道,浏览器是一个平面的视觉效果,如何在一个平面上看出立体的3D效果呢,其实就是一个视觉差的问题。那我们就从一个平面视觉效果一步一步画出立体的3D效果来。
本文由 www.webfunny.cn 前端监控提供;只需要简单几步就可以搭建一套属于自己的前端监控系统,快来试试吧 ^ _ ^。
一、先画出平面视觉上卫星的旋转轨迹
卫星的轨迹一般都是圆的或者椭圆的,我们就先以一个圆形的轨迹为例。
非常简单,就是画一个圆形的轨迹,然后利用弧度公式计算出每个卫星在轨迹上的位置。比如:
三个卫星,弧度就是 var radian =2 * Math.PI /360 *60,更多的卫星就同理计算弧度
它们三个组成的三角形边长就是:var langWidth = Math.sin(radian) * rWidth
利用勾股定理是不是就可以计算出每个卫星的位置了。 现在我们把样式加上,就可以看到旋转的卫星了。 如代码中所示,我们在13s内,让整个div自转一周(360度),为了兼容更多的浏览器,所以写了一大坨,如果不明白可以看一下 CSS3 之动画及兼容性调优
涉及的知识点: 动画的过程拆分,三角形边长位置计算
.r1{
animation:rotate 13s linear infinite;
-webkit-animation:rotate 13s linear infinite;
-moz-animation:rotate 13s linear infinite;
-o-animation:rotate 13s linear infinite;
}
@keyframes rotate{
0%{
transform:rotate(0deg)skew(0deg)scale(1);
-ms-transform:rotate(0deg)skew(0deg)scale(1);
-moz-transform:rotate(0deg)skew(0deg)scale(1);
-webkit-transform:rotate(0deg)skew(0deg)scale(1);
-o-transform:rotate(0deg)skew(0deg)scale(1);
}
100%{
transform:rotate(360deg)skew(0deg)scale(1);
-ms-transform:rotate(360deg)skew(0deg)scale(1);
-moz-transform:rotate(360deg)skew(0deg)scale(1);
-webkit-transform:rotate(360deg)skew(0deg)scale(1);
-o-transform:rotate(360deg)skew(0deg)scale(1);
}
}
二、画出卫星3D立体的旋转的效果
现在我们要把这个平面的圆形以一条直径为转轴,旋转76度,是不是就了一点点的立体感觉了。其实它还是一个平面,为什么能看到立体的感觉呢? 因为我们都知道一个远小近大的道理:当卫星转向内圈的时候,我们让球体逐渐变大;当卫星转向外圈的时候,我们让球体逐渐变小,这样就会产生一个远近景深的效果,也就产生了立体的感觉。
涉及的知识点:3D 元素距视图的距离(perspective),图形的角度处理三、画一个参照物
立体的旋转效果有了,但是我们的眼睛其实无法分辨哪个是内圈,哪个是外圈,我们需要在中间放一个参照物来告诉我们的眼睛,哪个在前,哪个在后。这样,一个完整的卫星围绕旋转效果就出来了。
涉及的知识点:让转换的子元素保留3D转换(transform-style: preserve-3d;)什么意思呢,就是让两个元素可以保持相对的立体空间效果。比如,土星图片和卫星轨道平面是垂直的,需要用这个属性来保持这个的空间效果。<body> <div class="star-animate"> <div class="out_circle"> <div class="nav_circle r1"> <img class="center-img1" src={require("Images/animateList/1/star.png")}/> <div class="img_top img"> <img src={require("Images/animateList/1/star1.png")}/> </div> <div class="img_bottom img"> <img src={require("Images/animateList/1/star2.png")}/> </div> <div class="img_bottom2 img"> <img src={require("Images/animateList/1/star3.png")}/> </div> </div> </div> </div> </body>
const outWidth = $(".out_circle").width() $(".out_circle").height(outWidth) // 获取半径 const rWidth = outWidth / 2 // 获得弧度 const radian = 2 * Math.PI / 360 * 60 // 长边 const langWidth = Math.sin(radian) * rWidth // icon的长度 const iconWidth = $(".img_top").width() $(".img_top").css({ top: 0 - iconWidth / 2, left: rWidth - iconWidth / 2 }) $(".img_bottom").css({ top: rWidth * 1.5 - iconWidth / 2, left: rWidth - langWidth - iconWidth / 2 }) $(".img_bottom2").css({ top: rWidth * 1.5 - iconWidth / 2, left: outWidth - (rWidth - langWidth) - iconWidth / 2 })
css(sass格式)内容:
.star-animate { width: 100%; height: 100%; background: url("~Images/animateList/1/bg.jpeg"); background-size: cover; .out_circle{ width: 400px; height: 400px; margin: auto; border-radius:50%; position: relative; transform-style: preserve-3d; -webkit-transform-style: preserve-3d; perspective: 30000; -webkit-perspective: 30000; transform: rotateX(76deg); -webkit-transform: rotateX(76deg); /* Safari and Chrome */ } .center-img1 { animation: rotate_change1 13s linear infinite; -webkit-animation:rotate_change1 13s linear infinite; -moz-animation:rotate_change1 13s linear infinite; -o-animation:rotate_change1 13s linear infinite; } .center-img1 { position: absolute; left: 6%; top: 25.5%; width: 88%; height: 49%; transform: rotateX(70deg); -webkit-transform: rotateX(70deg); /* Safari and Chrome */ } .test-div { position: absolute; width: 200px; height: 625px; background: red; left: 128px; top: -71px; } .nav_circle{ width:100%; height:100%; float:left; position:absolute; top:0; text-align:center; transform-style: preserve-3d; -webkit-transform-style: preserve-3d; } @keyframes rotate_change1{ 0%{ transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); } 100%{ transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); } } @keyframes rotate_change2{ 0%{ transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); opacity: 0; } 5%{ opacity: 1; } 17%{ opacity: 1; } 29%{ opacity: 1; } 34%{ opacity: 0; } 50%{ opacity: 0; } 67%{ opacity: 0; } 83%{ opacity: 0; } 100%{ opacity: 0; transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); } } @keyframes rotate_change3{ 0%{ transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); opacity: 0; } 17%{ opacity: 0; } 34%{ opacity: 0; } 50%{ opacity: 0; } 67%{ opacity: 0; } 72%{ opacity: 1; } 83%{ opacity: 1; } 95%{ opacity: 1; } 100%{ opacity: 0; transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); } } .img_top img, .img_bottom img, .img_bottom2 img { width: 100px; height: 100px; } .img_top,.img_bottom,.img_bottom2{ position: absolute; z-index:1; transform:rotateX(70deg); -ms-transform:rotateX(70deg); } .nav_circle .img a{ position: absolute; top:10px; left:94px; width: 52px; } .r1{ animation: rotate 13s linear infinite; -webkit-animation:rotate 13s linear infinite; -moz-animation:rotate 13s linear infinite; -o-animation:rotate 13s linear infinite; } .r1 .img_top{ animation:rotate_c1 13s linear infinite; -webkit-animation:rotate_c1 13s linear infinite; } .r1 .img_bottom{ animation:rotate_c2 13s linear infinite; -webkit-animation:rotate_c2 13s linear infinite; } .r1 .img_bottom2{ animation:rotate_c3 13s linear infinite; -webkit-animation:rotate_c3 13s linear infinite; } /* 外圈放大动画 */ @keyframes circle_rotate{ 0%{ width: 120px; height: 120px; margin-left: -10px; margin-top: -10px; } 100%{ width: 100px; height: 100px; margin-left: 0px; margin-top: 0px; } } @keyframes rotate{ 0%{ transform:rotate(0deg) skew(0deg) scale(1); -ms-transform:rotate(0deg) skew(0deg) scale(1); -moz-transform:rotate(0deg) skew(0deg) scale(1); -webkit-transform:rotate(0deg) skew(0deg) scale(1); -o-transform:rotate(0deg) skew(0deg) scale(1); } 100%{ transform:rotate(360deg) skew(0deg) scale(1); -ms-transform:rotate(360deg) skew(0deg) scale(1); -moz-transform:rotate(360deg) skew(0deg) scale(1); -webkit-transform:rotate(360deg) skew(0deg) scale(1); -o-transform:rotate(360deg) skew(0deg) scale(1); } } @keyframes rotate-center{ 0%{ transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(0deg) rotateX(-70deg) skew(0deg) scale(1); } 100%{ transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -ms-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -moz-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -webkit-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); -o-transform:rotate(-360deg) rotateX(-70deg) skew(0deg) scale(1); } } @keyframes rotate_c1{ 0%{ transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.01); -ms-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.01); -moz-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.01); -webkit-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.01); -o-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.01); } 50%{ transform:rotateX(-70deg) rotateY(180deg) skew(0deg) scale(1); -ms-transform:rotateX(-70deg) rotateY(180deg) skew(0deg) scale(1); -moz-transform:rotateX(-70deg) rotateY(180deg) skew(0deg) scale(1); -webkit-transform:rotateX(-70deg) rotateY(180deg) skew(0deg) scale(1); -o-transform:rotateX(-70deg) rotateY(180deg) skew(0deg) scale(1); } 100%{ transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.01); -ms-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.01); -moz-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.01); -webkit-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.01); -o-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.01); } } @keyframes rotate_c2{ 0%{ transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -ms-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -moz-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -webkit-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -o-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); } 34%{ transform:rotateX(-70deg) rotateY(120deg) skew(0deg) scale(0.01); -ms-transform:rotateX(-70deg) rotateY(120deg) skew(0deg) scale(0.01); -moz-transform:rotateX(-70deg) rotateY(120deg) skew(0deg) scale(0.01); -webkit-transform:rotateX(-70deg) rotateY(120deg) skew(0deg) scale(0.01); -o-transform:rotateX(-70deg) rotateY(120deg) skew(0deg) scale(0.01); } 83%{ transform:rotateX(-70deg) rotateY(300deg) skew(0deg) scale(1); -ms-transform:rotateX(-70deg) rotateY(300deg) skew(0deg) scale(1); -moz-transform:rotateX(-70deg) rotateY(300deg) skew(0deg) scale(1); -webkit-transform:rotateX(-70deg) rotateY(300deg) skew(0deg) scale(1); -o-transform:rotateX(-70deg) rotateY(300deg) skew(0deg) scale(1); } 100%{ transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -ms-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -moz-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -webkit-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -o-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); } } @keyframes rotate_c3{ 0%{ transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -ms-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -moz-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -webkit-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); -o-transform:rotateX(-70deg) rotateY(0deg) skew(0deg) scale(0.67); } 17%{ transform:rotateX(-70deg) rotateY(60deg) skew(0deg) scale(1); -ms-transform:rotateX(-70deg) rotateY(60deg) skew(0deg) scale(1); -moz-transform:rotateX(-70deg) rotateY(60deg) skew(0deg) scale(1); -webkit-transform:rotateX(-70deg) rotateY(60deg) skew(0deg) scale(1); -o-transform:rotateX(-70deg) rotateY(60deg) skew(0deg) scale(1); } 67%{ transform:rotateX(-70deg) rotateY(240deg) skew(0deg) scale(0.01); -ms-transform:rotateX(-70deg) rotateY(240deg) skew(0deg) scale(0.01); -moz-transform:rotateX(-70deg) rotateY(240deg) skew(0deg) scale(0.01); -webkit-transform:rotateX(-70deg) rotateY(240deg) skew(0deg) scale(0.01); -o-transform:rotateX(-70deg) rotateY(240deg) skew(0deg) scale(0.01); } 100%{ transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -ms-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -moz-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -webkit-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); -o-transform:rotateX(-70deg) rotateY(360deg) skew(0deg) scale(0.67); } } .line-box { position: absolute; width: 300px; height: 200px; top: 35%; right: 1%; } /* 标题动画 */ @keyframes des1_appear{ 0%{ opacity: 0; } 17%{ opacity: 0; } 34%{ opacity: 0; } 39%{ opacity: 1; } 50%{ opacity: 1; } 62%{ opacity: 1; } 67%{ opacity: 0; } 83%{ opacity: 0; } 100%{ opacity: 0; } } @keyframes des2_appear{ 0%{ opacity: 0; } 5%{ opacity: 1; } 17%{ opacity: 1; } 29%{ opacity: 1; } 34%{ opacity: 0; } 50%{ opacity: 0; } 67%{ opacity: 0; } 83%{ opacity: 0; } 100%{ opacity: 0; } } @keyframes des3_appear { 0%{ opacity: 0; } 17%{ opacity: 0; } 34%{ opacity: 0; } 50%{ opacity: 0; } 67%{ opacity: 0; } 72%{ opacity: 1; } 83%{ opacity: 1; } 95%{ opacity: 1; } 100%{ opacity: 0; } } @keyframes snap_line1_appear{ 0%{ width: 0px; } 17%{ width: 0px; } 34%{ width: 0px; } 39%{ width: 0px; } 50%{ width: 140px; } 62%{ width: 140px; } 67%{ width: 0px; } 83%{ width: 0px; } 100%{ width: 0px; } } @keyframes snap_line2_appear{ 0%{ width: 0px; } 5%{ width: 0px; } 17%{ width: 140px; } 29%{ width: 140px; } 34%{ width: 0px; } 50%{ width: 0px; } 67%{ width: 0px; } 83%{ width: 0px; } 100%{ width: 0px; } } @keyframes snap_line3_appear { 0%{ width: 0px; } 17%{ width: 0px; } 34%{ width: 0px; } 50%{ width: 0px; } 67%{ width: 0px; } 72%{ width: 0px; } 83%{ width: 140px; } 95%{ width: 140px; } 100%{ width: 0px; } } }