1. 程式人生 > >vue2 3d 切換器

vue2 3d 切換器

惡心 prev hid 點擊 auto 同時 target turn height

空閑時寫了一個3d切換器,靈感來自於轉行前畫3d工程圖,效果如圖:

  功能:按住鼠標中間,變為3d模式,點擊6個頁面中的某一個頁面,頁面旋轉放大,恢復到2d圖形,3d圖消失。再次點擊鼠標中間,恢復為3d(含動畫效果),按住中鍵不放,可以左右或者上下拖動,3d圖片做720°旋轉。

  效果可在:此處查看 請使用chrome打開

技術分享

  轉動原理:由於正方體只有6個面,所以ul+6個li標簽,先做出正方體布局。li標簽布局出正方向後,都是相對於ul標簽的位置,所以轉動ul標簽,正方形並不會散架。鼠標水平移動X為ul transform:rotateX(x),鼠標豎直移動Y為ul的transform:rotateY(-Y) 實現轉動。-Y是為了一開始豎直方向不要反方向轉動。

關於坐標軸正方向:x軸:從左到右,y軸:從上到下,z軸:從屏幕到眼睛。坐標系是會轉動的,這點非常惡心。

  轉動正方向:眼睛在坐標原點觀察,逆時針為正方向。比如rotateX(30deg),指繞x軸正方向轉30°。看到的那一面是下面往上跑的。

  動畫布局:ul li 為百分比布局,外層套一層div,實際切換動畫由放大縮小div的大小來實現。動畫時保存3d圖形位置,當然只需要保存ul的轉動數據,當按下中鍵後,恢復ul轉動數據,恢復div大小,就可以了。

  動畫層:1、div tansition all 1s 這個動畫是漸變放大與縮小,讓ul與li都同時放大縮小。 2、ul transition all 1s 這兒需要動態加入屬性,轉動時不需要,切換時才需要,效果為切換時轉動放大和縮小 3、transiton-group 包裹li標簽,這兒動畫是為了其中5個標簽漸變消失,只留一個標簽。

  有了上面的理論,基本可以寫出來了,這兒貼出代碼。

<template>
  <div class=‘r‘ @mousedown=‘start‘>
    <div  ref=‘odiv‘ :style=‘odiv‘ class=‘oDiv‘>
      <ul :class=‘ulClass‘ :style="ulSty" v-show=‘showUl‘ > 
        <transition-group name=‘tt‘ enter-active-class=‘animated fadeIn‘ leave-active-class=‘animated fadeOut‘> <!--淡入淡出效果-->
           <li v-for
=‘n in 6‘ class=‘li‘ v-show=‘showLi[n-1]‘ ref=‘n‘ :key=‘n‘ @mousedown=‘show(n,$event)‘> <component :is=‘msg[n-1]‘ class=‘com‘></component> </li> </transition-group> </ul> </div> </transition> </div> </template> <script> import pieChart from ‘./pieChart.vue‘ import barChart from ‘./barChart.vue‘ import info from ‘./info.vue‘ import table1 from ‘./table.vue‘ import baidu from ‘./baidu.vue‘ import reg from ‘./reg.vue‘ export default{ data(){ return{ msg:[‘info‘,‘barChart‘,‘reg‘,‘table1‘,‘baidu‘,‘pieChart‘], n:‘‘, m:true, showUl:true, ulClass:‘ul1‘, flag:true, odiv:{ width:‘300px‘, height:‘300px‘, margin:‘50px auto 100px‘, transition:‘all 1s‘ }, showLi:[true,true,true,true,true,true], ulSty:{ transform:‘‘ }, changeSty:[], drag:{lastX:0,lastY:0,X:0,Y:0}, } }, components:{ pieChart,barChart,info,table1,baidu,reg }, methods:{ show(n,e){//點擊鼠標左鍵,顯示該組件。 if(e.button!=0)return if(!this.flag)return this.flag=false//show某個組件的時候,不能再次show它。 this.n=nthis.odiv.width=‘100%‘ this.odiv.height=‘500px‘ let b= this.$refs.n[n-1].style let d=getComputedStyle(this.$refs.n[n-1],null)[‘background‘] b.overflow=‘visible‘ b.opacity=‘1‘ b.background=‘#fff‘ b.transition=‘all 1s‘ this.showLi=[false,false,false,false,false,false] this.showLi[n-1]=true this.ulClass=‘ul1 move‘ let c=getComputedStyle(this.$refs.n[n-1],null)[‘transform‘] this.changeSty=[this.ulSty.transform,c,d] this.ulSty.transform=‘rotateX(0deg) rotateY(0deg)‘ b.transform=‘rotateX(0deg) rotateY(0deg) translateZ(0px)‘ }, init(){//當點擊鼠標中鍵,恢復3d圖形之前的位置。初始化li,ul,div的屬性。 let b= this.$refs.n[this.n-1].style b.overflow=‘hidden‘ b.opacity=‘0.8‘ b.background=this.changeSty[2] b.transform=this.changeSty[1] this.odiv.width=‘300px‘ this.odiv.height=‘300px‘ this.showLi=[true,true,true,true,true,true] this.ulClass=‘ul1‘ this.ulSty.transform=this.changeSty[0] }, start(e){//轉動效果 if(e.button!=1)return if(this.n){ this.init() } e.preventDefault(); this.flag=true let x1=e.clientX, y1=e.clientY document.onmousemove=(evt)=>{ let dx=evt.clientX-x1 let dy=evt.clientY-y1 this.drag.X=(this.drag.lastX+dx)%360 this.drag.Y=(this.drag.lastY+dy)%360 this.ulSty.transform=‘rotateX(‘+ -this.drag.Y+‘deg) rotateY(‘+this.drag.X+‘deg)‘ } document.onmouseup=()=>{ this.drag.lastX=this.drag.X this.drag.lastY=this.drag.Y document.onmouseup=null document.onmousemove=null } } }, } </script> <style lang="stylus" scoped> .com position:absolute width:100% .r width:100% wh() width:100% height:100% .ul1 position relative wh() transform-style: preserve-3d; .move transition all 1s .li list-style:none wh() position:absolute font-size 40px background:#fff z-index:0 transform-origin:center center overflow:hidden transition:all 1s n(x,y,z) transform:rotateY(y) rotateX(x) translateZ(150px) background:rgba(z,0.8) .li:nth-child(1) n(0,90deg,burlywood) .li:nth-child(2) n(0,-90deg,beige) .li:nth-child(3) n(90deg,0,lightyellow) .li:nth-child(4) n(180deg,0,pink) .li:nth-child(5) n(270deg,0,#20A0FF) .li:nth-child(6) n(0,0,aquamarine) </style>

vue2 3d 切換器