今天在学习vue的时候发了一个简单的banner效果图:如下(来源 )
以傲慢与偏执
回敬傲慢与偏见
code by qingjin.me | picture from t.tt
感觉挺有意思,于是就给它实现一波。(html和css是扒的) 实现原理就是两张图片在3d中显示前后位置,通过透视图perspective属性实现(透视图和我们的眼睛看到的是一样的,越远的物体看上去越小。还有种正交视图,不会根据距离收缩。) 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 <style > * { padding: 0; margin: 0; box-sizing: border-box; } .banner { -webkit-perspective: 3000px; perspective: 3000px; position: relative; z-index: 19 } .bg { position: relative; width: 1220px; height: 500px; margin: 20px auto; background : url (banner-3d-item .png ) 50% no-repeat ; background-size: 100% 100%; border-radius: 10px; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-transform-origin: 50% 50%; -webkit-transform: rotateY(0deg) rotateX(0deg); } .img { display: block; position: absolute; width: 100%; height: 100%; bottom: 5px; left: 0; background : url ("banner-3d .png ") center no-repeat ; background-size: 95% 100%; } .text { position: absolute; top: 20%; right: 10%; font-size: 30px; color : #fff ; text-align: right; font-weight: lighter; } .copyright { position: absolute; bottom: 10%; right: 10%; font-size: 10px; color : #fff ; text-align: right; font-weight: lighter; } .a { -webkit-transform: translateZ(40px); } .b { -webkit-transform: translateZ(20px); } .c { -webkit-transform: translateZ(0px); } </style > <div class ="banner" > <div class ="bg" id ="bg" style ="transform: rotateY(0deg) rotateX(0deg);" > <span class ="img a" > </span > <span class ="text b" > 以傲慢与偏执<br > 回敬傲慢与偏见</span > <span class ="copyright c" > code by qingjin.me | picture from t.tt</span > </div > </div > <script > var bindEvent = function (dom, eventName, listener ) { if (dom.attachEvent) { dom.attachEvent('on' +eventName, listener); } else { dom.addEventListener(eventName, listener); } } var bg = document .getElementById('bg' ); bindEvent(bg, 'mousemove' , function (e ) { let x = e.offsetX - (bg.offsetWidth / 2 ) let y = bg.offsetHeight / 2 - e.offsetY bg.style['-webkit-transform' ] = `rotateY(${x / 100}deg) rotateX(${y / 100 } deg)` bg.style.transform = `rotateY(${x / 100}deg) rotateX(${y / 100 } deg)` }) bindEvent(bg, 'mouseout' , function (e ) { bg.style['-webkit-transform' ] = `rotateY(0deg) rotateX(0deg)` bg.style.transform = `rotateY(0deg) rotateX(0deg)` }) </script >
扒好后发现动画很卡,一开始我还以为是demo的服务器比较差带不动动画,可在本地运行也贼卡。
于是去找原因:最终发现问题出在transition: all .3s
这个css属性。 transition是过渡属性,这句话的含义是所有的变换(位子,宽高,透明度,旋转等等)在0.3秒内过渡完成。 可是我们js实现的时候是实时根据鼠标位置修改rotate的角度的,而且鼠标移动触发的频率贼高。每次都使用0.3秒过渡,就导致每次动画过渡还没执行结束又开始新的动画。所以导致卡顿。
解决方法就是把它改成0秒或直接删除这个属性就OK了
小技巧:添加CSS3样式-webkit-transform:transition3d(0,0,0)或-webkit-transform:translateZ(0);,这两个属性都会开启GPU硬件加速模式
希望这篇文章能给你带来知识和乐趣,喜欢博主的文章可以加博主好友哦
有好的文章也可以向博主投稿哦