Bläddra i källkod

contents are placed on inner faces of building, with visibles above surface and others below

Bachir Soussi Chiadmi 3 år sedan
förälder
incheckning
94b9a5452f
4 ändrade filer med 204 tillägg och 51 borttagningar
  1. 44 28
      src/App.vue
  2. 3 3
      src/components/mixins.js
  3. 131 17
      src/components/objects/ContentBlock.vue
  4. 26 3
      src/components/objects/Project.vue

+ 44 - 28
src/App.vue

@@ -184,7 +184,7 @@ export default {
       // cam_controls: null,
       init_cam_pos: { x: 0, y: 10, z: 100 },
       raycaster: new THREE.Raycaster(),
-      interactive_objects_names: ['Project', 'ContentBlock'],
+      interactive_objects_names: ['Project', 'Content'],
       interactive_objects: [],
       light_opts: {
         castShadow: true
@@ -286,34 +286,47 @@ export default {
         let cam = this.camera
         let camPos = { ...this.camera.position }
         if (intersects.length) {
-          console.log('onDocMouseUp intersects', intersects)
-          for (var i = 0; i < intersects.length; i++) {
-            object = intersects[i].object
-            vnode = object.userData.vnode
-            vnode.isOpened = true
-
+          // console.log('onDocMouseUp intersects', intersects)
+          // for (var i = 0; i < intersects.length; i++) {
+          object = intersects[0].object
+          vnode = object.userData.vnode
+          vnode.isOpened = true
+
+          toPos = { ...object.position }
+          if (object.name === 'Content') {
+            // toPos.z += 1
+            switch (vnode.face) {
+              case 'left':
+                toPos.x += 2
+                break
+              case 'back':
+                toPos.z += 2
+                break
+              case 'right':
+                toPos.x -= 2
+                break
+              case 'front':
+                toPos.z -= 2
+                break
+            }
+            // TODO: we need to update lon and lat accordingly when chaging camera orientation
             // new TWEEN.Tween(this.controls.cam_target)
-            //   .to(object.position, 400)
+            //   .to(object.position, 2000)
             //   .start()
-            //
-            toPos = { ...object.position }
-            if (object.name === 'ContentBlock') {
-              toPos.z += 1
-            }
-            // toPos.y = 5
-            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)
-                // camControls.update()
-              })
-              .start()
-
-            // console.log('tween', tween)
-            break
           }
+          // toPos.y = 5
+          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()
+
+          // console.log('tween', tween)
+          //   break
+          // }
         } else {
           // new TWEEN.Tween(this.camera.position)
           //   .to(this.init_cam_pos, 1000)
@@ -329,13 +342,16 @@ export default {
       // if (this.controls.user_interact === false) {
       //   this.controls.lon += 0.1
       // }
+      // if (this.controls.user_interact) {
       this.controls.cam_target.x = 500 * Math.sin(this.controls.phi) * Math.cos(this.controls.theta)
       this.controls.cam_target.y = 500 * Math.cos(this.controls.phi)
       this.controls.cam_target.z = 500 * Math.sin(this.controls.phi) * Math.sin(this.controls.theta)
-      // if (this.camera && this.controls.user_interact) {
-      this.camera.lookAt(this.controls.cam_target)
       // }
 
+      if (this.camera) {
+        this.camera.lookAt(this.controls.cam_target)
+      }
+
       // TWEENS
       TWEEN.update()
     }

+ 3 - 3
src/components/mixins.js

@@ -4,7 +4,7 @@ export default {
     deg2rad (deg) {
       return deg * (Math.PI / 180)
     },
-    createLabelCanvas (text, fontsize) {
+    createLabelCanvas (text, fontsize, sizefactore, txtcolor) {
       // console.log('createLabelCanvas', this.data.Titre)
       const size = fontsize
       const borderSize = 5
@@ -19,7 +19,7 @@ export default {
         width = Math.max(width, ctx.measureText(lines[i]).width + doubleBorderSize)
       }
       const height = size * lines.length + doubleBorderSize
-      this.label_size = { x: width / 21, y: height / 21 }
+      this.label_size = { x: width / sizefactore, y: height / sizefactore }
       ctx.canvas.width = width
       ctx.canvas.height = height
 
@@ -29,7 +29,7 @@ export default {
 
       // ctx.fillStyle = 'red'
       // ctx.fillRect(0, 0, width, height)
-      ctx.fillStyle = 'black'
+      ctx.fillStyle = txtcolor
       for (var j = 0; j < lines.length; j++) {
         ctx.fillText(lines[j], borderSize, borderSize + j * size)
       }

+ 131 - 17
src/components/objects/ContentBlock.vue

@@ -1,46 +1,160 @@
 <template>
-  <mesh ref="block3d" name="ContentBlock" :position="position">
-    <geometry type="Box" :args="[size.x, size.y, size.z]" />
-    <material type="MeshLambert" :color="color" :options="opts" />
-  </mesh>
+  <div>
+    <!-- <mesh ref="block3d" name="ContentBlock" :position="position">
+      <geometry type="Box" :args="[size.x, size.y, size.z]" />
+      <material type="MeshLambert" :color="color" :options="opts" />
+    </mesh> -->
+    <mesh
+      ref="label3d"
+      name="Content"
+      :position="position"
+      :rotation="{
+        x:deg2rad(rotation.x),
+        y:deg2rad(rotation.y),
+        z:deg2rad(rotation.z)
+      }"
+    >
+      <geometry type="Plane" :args="[size.x, size.y]" />
+      <material type="MeshLambert" :options="label_opts">
+        <texture :options="label_texture_opts" />
+      </material>
+    </mesh>
+  </div>
 </template>
 
 <script>
 import * as THREE from 'three'
+import mixins from 'components/mixins'
 
 export default {
   name: 'ContentBlock',
-  // mixins: [Object3D],
-  props: { prtPosition: Object, prtSize: Object },
+  mixins: [mixins],
+  props: { prtPosition: Object, prtSize: Object, type: String, data: Object },
   data: () => ({
-    block3d: null,
+    // block3d: null,
     size: { x: 2, y: 3, z: 0.1 },
     position: { x: 0, y: 0, z: 0 },
-    opts: {
-      side: THREE.DoubleSide
+    rotation: { x: 0, y: 0, z: 0 },
+    // opts: {
+    //   side: THREE.DoubleSide
+    //   // wireframe: false,
+    //   // transparent: false,
+    //   // opacity: 0.6
+    // },
+    isOpened: false,
+    label3d: null,
+    label_opts: {
+      side: THREE.DoubleSide,
       // wireframe: false,
-      // transparent: false,
+      transparent: true
       // opacity: 0.6
+      // renderOrder: 0
     },
-    isOpened: false
+    // label_position: { x: 5, y: 5, z: 6 },
+    label_canvas: null,
+    label_size: null,
+    face: null
   }),
   computed: {
     color () {
-      return this.opened ? 0xff0000 : 0x0000ff
+      let color = 0x000000
+      switch (this.type) {
+        case 'visible':
+          color = 0x0000ff
+          break
+        case 'context':
+          color = 0x00ffff
+          break
+        case 'process':
+          color = 0xff00ff
+          break
+        default:
+          color = 0xdddddd
+      }
+      return color
+    },
+    label_texture_opts () {
+      return {
+        canvas: this.label_canvas,
+        minFilter: THREE.LinearFilter,
+        wrapS: THREE.ClampToEdgeWrapping,
+        wrapT: THREE.ClampToEdgeWrapping
+      }
     }
   },
   created () {
     console.log('ContentBlock created', this.prtSize)
-    this.position.x = this.prtPosition.x - this.prtSize.x / 2 + Math.random() * this.prtSize.x
-    this.position.y = this.prtPosition.y - this.prtSize.y / 2 + Math.random() * this.prtSize.y
-    this.position.z = this.prtPosition.z - this.prtSize.z / 2 + Math.random() * this.prtSize.z
+    let txtcolor = '#000000'
+    switch (this.type) {
+      case 'visible':
+        txtcolor = '#0000ff'
+        break
+      case 'context':
+        txtcolor = '#ff0000'
+        break
+      case 'process':
+        txtcolor = '#00ff00'
+        break
+      default:
+    }
+
+    this.label_canvas = this.createLabelCanvas(this.data.Name.replace(/ /g, '\n').toUpperCase(), 60, 150, txtcolor)
+
+    this.size.x = this.label_size.x + 0.2
+    this.size.y = this.label_size.y + 0.2
+
+    let y = 0
+    switch (this.type) {
+      case 'visible':
+        y = (this.prtPosition.y + this.prtSize.y / 2) * Math.random()
+        break
+      case 'context':
+        y = (this.prtPosition.y - this.prtSize.y / 2) * Math.random()
+        break
+      case 'process':
+        y = (this.prtPosition.y - this.prtSize.y / 2) * Math.random()
+        break
+      default:
+    }
+    this.position.y = y
+
+    let face = Math.random()
+    if (face < 0.25) {
+      // gauche
+      this.face = 'left'
+      this.position.x = this.prtPosition.x - this.prtSize.x / 2 + 0.1
+      this.position.z = this.prtPosition.z - this.prtSize.z / 2 + this.size.x / 2 + Math.random() * (this.prtSize.z - this.size.x / 2)
+      this.rotation.y = 90
+    } else if (face >= 0.25 && face < 0.5) {
+      // fond
+      this.face = 'back'
+      this.position.z = this.prtPosition.z - this.prtSize.z / 2 + 0.1
+      this.position.x = this.prtPosition.x - this.prtSize.x / 2 + this.size.x / 2 + Math.random() * (this.prtSize.x - this.size.x / 2)
+    } else if (face >= 0.5 && face < 0.75) {
+      // droite
+      this.face = 'right'
+      this.position.x = this.prtPosition.x + this.prtSize.x / 2 - 0.1
+      this.position.z = this.prtPosition.z - this.prtSize.z / 2 + this.size.x / 2 + Math.random() * (this.prtSize.z - this.size.x / 2)
+      this.rotation.y = -90
+    } else {
+      // face
+      this.face = 'front'
+      this.position.z = this.prtPosition.z + this.prtSize.z / 2 - 0.1
+      this.position.x = this.prtPosition.x - this.prtSize.x / 2 + this.size.x / 2 + Math.random() * (this.prtSize.x - this.size.x / 2)
+      this.rotation.y = 180
+    }
+    // this.label_position.x = this.position.x - this.size.x / 2 + this.label_size.x / 2 + 0.1
+    // this.label_position.y = this.position.y + this.size.y / 2 - this.label_size.y / 2 - 0.1
+    // this.label_position.z = this.position.z + this.size.z / 2 + 0.01
   },
   mounted () {
-    this.block3d = this.$refs.block3d.curObj
+    // this.block3d = this.$refs.block3d.curObj
     // this.block3d.castShadow = true
     // this.block3d.receiveShadow = true
+
+    this.label3d = this.$refs.label3d.curObj
     // record self references
-    this.block3d.userData = {
+    this.label3d.userData = {
       vnode: this
     }
   }

+ 26 - 3
src/components/objects/Project.vue

@@ -13,7 +13,30 @@
       </material>
     </mesh>
     <div v-if="isOpened">
-      <ContentBlock v-for="n in 10" :key="n" :prtPosition="position" :prtSize="size" />
+      <ContentBlock
+        v-for="item in data.visibles"
+        :key="item.id"
+        :prtPosition="position"
+        :prtSize="size"
+        type="visible"
+        :data="item"
+        />
+      <ContentBlock
+        v-for="item in data.contexts"
+        :key="item.id"
+        :prtPosition="position"
+        :prtSize="size"
+        type="context"
+        :data="item"
+        />
+      <ContentBlock
+        v-for="item in data.processes"
+        :key="item.id"
+        :prtPosition="position"
+        :prtSize="size"
+        type="process"
+        :data="item"
+        />
     </div>
   </div>
 </template>
@@ -69,7 +92,7 @@ export default {
     }
   },
   created () {
-    // console.log('this.index', this.index)
+    console.log('Project created: data', this.data)
     // randomize size and positions
     this.size.y = 100 + Math.random() * 90
     this.size.z = 10 + Math.random() * 30
@@ -78,7 +101,7 @@ export default {
     this.position.y = -1 * this.size.y / 2 + 10 + Math.random() * 30// -10 + Math.random() * this.size.y / 2
     this.position.z = -10 + Math.random() * 10
 
-    this.label_canvas = this.createLabelCanvas(this.data.Titre.replace(/ /g, '\n').toUpperCase(), 48)
+    this.label_canvas = this.createLabelCanvas(this.data.Titre.replace(/ /g, '\n').toUpperCase(), 48, 21, '#000000')
     this.label_position.x = this.position.x - this.size.x / 2 + this.label_size.x / 2 + 1
     this.label_position.y = this.position.y + this.size.y / 2 - this.label_size.y / 2 - 1
     this.label_position.z = this.position.z + this.size.z / 2 + 0.1