Browse Source

added elevator

Bachir Soussi Chiadmi 3 years ago
parent
commit
82bde19d19
4 changed files with 125 additions and 10 deletions
  1. 20 0
      assets/css/app.scss
  2. 20 5
      src/App.vue
  3. 80 4
      src/components/objects/Project.vue
  4. 5 1
      src/store/modules/project.js

+ 20 - 0
assets/css/app.scss

@@ -99,3 +99,23 @@ section[role="main-content"]{
 
   }
 }
+
+
+.elevator{
+  position: absolute;
+  right:0;
+  top:43%;
+  ul{
+    padding:1em;
+    background-color: rgba(255, 255, 255, 0.6);
+    li{
+      padding:0.25em 0;
+      text-align: right;
+      min-width: 5em;
+      cursor: pointer;
+      &:hover, &.active{
+        font-weight: bold;
+      }
+    }
+  }
+}

+ 20 - 5
src/App.vue

@@ -41,6 +41,7 @@
                 v-for="(project) in projects"
                 :id="project.id"
                 :key="project.id"
+                @lift="onLift"
               />
             </template>
 
@@ -245,9 +246,9 @@ export default {
     this.updatedInteractiveObjects()
     // CONTROLS
     // https://blogs.perficient.com/2020/05/21/3d-camera-movement-in-three-js-i-learned-the-hard-way-so-you-dont-have-to/
-    document.addEventListener('mousedown', this.onDocMouseDown, false)
-    document.addEventListener('mousemove', this.onDocMouseMove, false)
-    document.addEventListener('mouseup', this.onDocMouseup, false)
+    document.addEventListener('mousedown', this.onDocMouseDown)
+    document.addEventListener('mousemove', this.onDocMouseMove)
+    document.addEventListener('mouseup', this.onDocMouseup)
   },
   updated () {
     this.updatedInteractiveObjects()
@@ -295,7 +296,8 @@ export default {
       this.controls.user_interact = false
 
       // check if event is not a classic html link
-      if (e.target.className === 'close-btn') {
+      // TODO: stopPropagation instead of that (but it does not work)
+      if (e.target.className === 'close-btn' || e.target.className === 'btn-level') {
         // console.log('close-btn: vnode', this.opened_vnode)
         // this.opened_vnode.isOpened = false
         return
@@ -315,7 +317,7 @@ export default {
         // if we clicked on 3Dobject
         if (intersects.length) {
           let cam = this.camera
-          console.log('onDocMouseUp intersects', intersects)
+          // console.log('onDocMouseUp intersects', intersects)
           let object = intersects[0].object
           console.log('object[0]', object)
           let vnode = object.userData.vnode
@@ -388,6 +390,19 @@ export default {
         }
       } // end if dragging
     },
+    onLift (toPos) {
+      console.log('onLift', toPos)
+      let cam = this.camera
+      let camPos = { ...cam.position }
+      new TWEEN.Tween(camPos)
+        .easing(TWEEN.Easing.Quadratic.InOut)
+        .to(toPos, 3000)
+        .onUpdate(function () {
+          // console.log('tween update', this._object)
+          cam.position.set(this._object.x, this._object.y, this._object.z)
+        })
+        .start()
+    },
     animate (tt) {
       // CONTROLS
       if (this.controls.user_interact) {

+ 80 - 4
src/components/objects/Project.vue

@@ -39,13 +39,49 @@
         :prtId="id"
         :data="item"
         />
+      <div class="elevator">
+        <ul>
+          <li :class="{ active: levelVisibles }">
+            <a
+              class="btn-level"
+              href="#visibles"
+              @click.stop="onClickLevel('visibles', $event)"
+              @keyup.enter="onClickLevel('visibles')"
+            >Visibles</a>
+          </li>
+          <li :class="{ active: levelContexts }">
+            <a
+              class="btn-level"
+              href="#contexts"
+              @click.stop="onClickLevel('contexts', $event)"
+              @keyup.enter="onClickLevel('contexts')"
+            >Contexts</a>
+          </li>
+          <li :class="{ active: levelProcesses }">
+            <a
+              class="btn-level"
+              href="#processes"
+              @click.stop="onClickLevel('processes', $event)"
+              @keyup.enter="onClickLevel('processes')"
+            >Processes</a>
+          </li>
+          <li :class="{ active: levelConcepts }">
+            <a
+              class="btn-level"
+              href="#concepts"
+              @click.stop="onClickLevel('concepts', $event)"
+              @keyup.enter="onClickLevel('concepts')"
+            >Concepts</a>
+          </li>
+        </ul>
+      </div>
     </div>
   </div>
 </template>
 
 <script>
 
-import { mapInstanceState, mapInstanceActions } from '@urbn/vuex-helpers'
+import { mapInstanceState, mapInstanceActions, mapInstanceMutations } from '@urbn/vuex-helpers'
 
 import * as THREE from 'three'
 // import { ThreeBSP } from 'three-js-csg-es6'
@@ -102,7 +138,8 @@ export default {
       floorPos: state => state.floorPos,
       levels3dObj: state => state.levels3dObj,
       levelsPos: state => state.levelsPos,
-      contents: state => state.contents
+      contents: state => state.contents,
+      activeLevel: state => state.activeLevel
     }),
     label_texture_opts () {
       return {
@@ -111,6 +148,18 @@ export default {
         wrapS: THREE.ClampToEdgeWrapping,
         wrapT: THREE.ClampToEdgeWrapping
       }
+    },
+    levelVisibles () {
+      return this.activeLevel === 'visibles'
+    },
+    levelContexts () {
+      return this.activeLevel === 'contexts'
+    },
+    levelProcesses () {
+      return this.activeLevel === 'processes'
+    },
+    levelConcepts () {
+      return this.activeLevel === 'concepts'
     }
   },
   created () {
@@ -132,9 +181,36 @@ export default {
     ...mapInstanceActions(getModuleName, {
       loadContents: 'loadContents'
     }),
+    ...mapInstanceMutations(getModuleName, {
+      setActiveLevel: 'setActiveLevel'
+    }),
     open () {
-      this.isOpened = true
-      this.loadContents()
+      if (!this.isOpened) {
+        this.isOpened = true
+        this.loadContents()
+      }
+    },
+    onClickLevel (level, e) {
+      // e.stopPropagation()
+      e.preventDefault()
+      console.log('onclickLevel', level)
+      this.setActiveLevel(level)
+      let toPos = { ...this.position }
+      switch (level) {
+        case 'visibles':
+          toPos.y = 2
+          break
+        case 'contexts':
+          toPos.y = -1 * this.size.y * 0.25 + 2
+          break
+        case 'processes':
+          toPos.y = -2 * this.size.y * 0.25 + 2
+          break
+        case 'concepts':
+          toPos.y = -3 * this.size.y * 0.25 + 2
+          break
+      }
+      this.$emit('lift', toPos)
     }
   }
 }

+ 5 - 1
src/store/modules/project.js

@@ -44,7 +44,8 @@ export default {
     contents_size_factor: 2, // factor to get the contents (grid) size proportional to windows
     contentTypes: ['visible', 'context', 'process', 'concept'],
     grid: { visible: [], context: [], process: [], concept: [] },
-    gridContentPlaced: {}
+    gridContentPlaced: {},
+    activeLevel: 'visibles'
   },
 
   // getters
@@ -94,6 +95,9 @@ export default {
         state.gridContentPlaced[c.type] = {}
       }
       state.gridContentPlaced[c.type][c.id] = p
+    },
+    setActiveLevel: (state, l) => {
+      state.activeLevel = l
     }
   },