vue2 3d 切换器

Posted 吃个石头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue2 3d 切换器相关的知识,希望对你有一定的参考价值。

空闲时写了一个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 切换器的主要内容,如果未能解决你的问题,请参考以下文章

将 Ortho 切换到 OpenGL HUD 的透视图

vue2.0实现点击后显示,再次点击隐藏

vue2.0的变化

Vue2基础——Tap栏切换案例

Android中切换标签片段之间的延迟

在Android Studio片段之间切换时地图片段不隐藏