Browse Source

looking arround is quite working

Bachir Soussi Chiadmi 3 years ago
parent
commit
e8e679a442

+ 1 - 1
index.html

@@ -2,7 +2,7 @@
 <html>
   <head>
     <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
     <title>Muntadas</title>
   </head>
   <body>

+ 5 - 0
package-lock.json

@@ -2943,6 +2943,11 @@
         "@types/yargs": "^13.0.0"
       }
     },
+    "@tweenjs/tween.js": {
+      "version": "18.6.0",
+      "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.0.tgz",
+      "integrity": "sha512-z45HU0G0e/SenbvGdAlTpUR5Hur5zwZXQcqfI+f7EnVHdeb2oMI2rQghEePu7uXuvBC0nuKWG5YtZ1nWbuvqzQ=="
+    },
     "@types/babel__core": {
       "version": "7.1.3",
       "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz",

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
   "author": "Daniel Cook",
   "license": "MIT",
   "dependencies": {
+    "@tweenjs/tween.js": "^18.6.0",
     "axios": "^0.18.1",
     "dat.gui": "^0.7.7",
     "oimo": "^1.0.9",

+ 144 - 26
src/App.vue

@@ -13,21 +13,25 @@
       <div class="wrapper">
         <renderer :obj="myRenderer" :size="size">
           <scene :obj="myScene" @update:obj="handleScene">
-            <orbit-controls :position="{x:0,y:150,z:0}" :rotation="{ x: -90, y: 0, z: 0 }">
+
+            <!-- <orbit-controls ref="cam_controls" :position="init_cam_pos" :rotation="{ x: 0, y: 0, z: 0 }">
               <camera />
-            </orbit-controls>
-            <!-- <camera :position="{x:0, y:300, z:0}" :rotation="{x:deg2rad(-90), y:0, z:0}"/> -->
-            <!-- <camera :position="{x:0,y:50,z:0}" :lookat="{x:0,y:0,z:0}" /> -->
+            </orbit-controls> -->
+            <camera ref="camera" :position="init_cam_pos" :rotation="{x:0, y:0, z:0}" />
+
             <light :hex="0xffffff" :intensity="5" :position="{x:-100,y:150,z:50}" />
-            <light :hex="0xffffff" :intensity="2" :position="{x:100,y:-150,z:-50}" />
-            <!-- <mesh :obj="mesh" :position="{ y: -200 }" /> -->
-            <!-- <animation :fn="animate" :speed="3" /> -->
-            <plan :size="{w:5000,h:5000}" :position="{x:0,y:0,z:0}" :color="0xffffff" :rotation="{x:90,y:0,z:0}" />
+            <light :hex="0xffffff" :intensity="2" :position="{x:100,y:-150,z:-50}" :options="light_opts" />
+
+            <animation :fn="animate" :speed="3" />
+
             <template v-if="debug">
               <cube :size="{x:30,y:1,z:1}" :position="{x:15,y:0,z:0}" :color="0x992222" />
               <cube :size="{x:1,y:30,z:1}" :position="{x:0,y:15,z:0}" :color="0x00BBFF" />
               <cube :size="{x:1,y:1,z:30}" :position="{x:0,y:0,z:15}" :color="0x17d100" />
             </template>
+
+            <plan :size="{w:5000,h:5000}" :position="{x:0,y:0,z:0}" :color="0x1a1a1a" :rotation="{x:90,y:0,z:0}" />
+
             <template v-if="projects.length">
               <project
                 v-for="(project, index) in projects"
@@ -37,7 +41,7 @@
                 :index="index"
               />
             </template>
-            <line />
+
           </scene>
         </renderer>
       </div>
@@ -50,11 +54,15 @@
 import { mapState, mapActions } from 'vuex'
 import mixins from 'components/mixins'
 import * as THREE from 'three'
+import TWEEN from '@tweenjs/tween.js'
 
 import Plan from './components/objects/Plan'
 import Cube from './components/objects/Cube'
 import Project from './components/objects/Project'
 
+// const TWEEN = require('@tweenjs/tween.js')
+const _debug = true
+
 export default {
   metaInfo: {
     // if no subcomponents specify a metaInfo.title, this title will be used
@@ -72,20 +80,44 @@ export default {
     // const envcolor = 0xffffff
     let renderer = new THREE.WebGLRenderer({ alpha: false, antialias: true })
     renderer.setClearColor(0x000000, 0)
+    renderer.shadowMap.enabled = true
 
     // scene obj is well overwrited but background color not visible
     let scene = new THREE.Scene()
     scene.background = new THREE.Color(0x1a1a1a)
     scene.fog = new THREE.Fog(scene.background, 50, 400)
-    console.log('myScene', scene)
+    // console.log('myScene', scene)
+
+    // let cameraHelper = new THREE.CameraHelper()
+    // scene.add(cameraHelper)
+
     return {
-      debug: false,
+      debug: _debug,
       myRenderer: renderer,
       myScene: scene,
-      mouse: new THREE.Vector2(),
+      // mouse_start: new THREE.Vector2(),
+      // mouse: new THREE.Vector2(),
       camera: null,
+      mouse: new THREE.Vector2(),
+      controls: {
+        user_interact: false,
+        mouse: new THREE.Vector2(),
+        mouse_start: new THREE.Vector2(),
+        lon: 0,
+        lat: 0,
+        lon_start: 0,
+        lat_start: 0,
+        phi: 0,
+        theta: 0,
+        cam_target: new THREE.Vector3(0, 0, 0)
+      },
+      // cam_controls: null,
+      init_cam_pos: { x: 0, y: 10, z: 150 },
       raycaster: new THREE.Raycaster(),
-      interactive_objects: []
+      interactive_objects: [],
+      light_opts: {
+        castShadow: true
+      }
     }
   },
   computed: {
@@ -106,10 +138,17 @@ export default {
   },
   mounted () {
     console.log('mounted', this)
-    this.camera = this.$children[0].global.camera
+    this.camera = this.$refs.camera.curObj
+    // this.cam_controls = this.$refs.cam_controls.controls
+    // console.log('cam_controls', this.cam_controls)
+
+    // this.cam_controls = new THREE.PointerLockControls(this.camera)
+    // console.log('this.cam_controls', this.cam_controls)
+
     this.updatedInteractiveObjects()
-    document.addEventListener('mousemove', this.onMouseMove, false)
-    document.addEventListener('click', this.onDocumentClick, false)
+    document.addEventListener('mousedown', this.onDocMouseDown, false)
+    document.addEventListener('mousemove', this.onDocMouseMove, false)
+    document.addEventListener('mouseup', this.onDocMouseup, false)
   },
   updated () {
     this.updatedInteractiveObjects()
@@ -121,11 +160,6 @@ export default {
     handleScene (scene) {
       console.log('handlescene', scene)
     },
-    onMouseMove (e) {
-      // update the mouse variable
-      this.mouse.x = (e.clientX / window.innerWidth) * 2 - 1
-      this.mouse.y = -(e.clientY / window.innerHeight) * 2 + 1
-    },
     updatedInteractiveObjects () {
       this.interactive_objects = []
       for (var i = 0; i < this.myScene.children.length; i++) {
@@ -133,19 +167,103 @@ export default {
           this.interactive_objects.push(this.myScene.children[i])
         }
       }
-      console.log('this.interactive_objects', this.interactive_objects)
+      // console.log('this.interactive_objects', this.interactive_objects)
+    },
+    onDocMouseDown (e) {
+      // controls
+      this.controls.mouse_start.x = e.clientX
+      this.controls.mouse_start.y = e.clientY
+      this.controls.lon_start = this.controls.lon
+      this.controls.lat_start = this.controls.lat
+      this.controls.user_interact = true
     },
-    onDocumentClick (e) {
-      console.log('onDocumentClick', e)
+    onDocMouseMove (e) {
+      // RAY CASTING : update the mouse variable
+      this.mouse.x = (e.clientX / window.innerWidth) * 2 - 1
+      this.mouse.y = -(e.clientY / window.innerHeight) * 2 + 1
 
+      // CONTROLS
+      if (this.controls.user_interact) {
+        // lon = ( onMouseDownMouseX - clientX ) * 0.1 + onMouseDownLon;
+        this.controls.lon = (this.controls.mouse_start.x - e.clientX) * 0.1 + this.controls.lon_start
+        // lat = ( clientY - onMouseDownMouseY ) * 0.1 + onMouseDownLat;
+        this.controls.lat = (e.clientY - this.controls.mouse_start.y) * 0.1 + this.controls.lat_start
+      }
+    },
+    onDocMouseup (e) {
+      // console.log('onDocumentMouseup', e)
+      // CONTROLS
+      this.controls.user_interact = false
+
+      // INTERACT
+      // TODO: check if draging
       // update the picking ray with the camera and mouse position
       this.raycaster.setFromCamera(this.mouse, this.camera)
       // calculate objects intersecting the picking ray
       var intersects = this.raycaster.intersectObjects(this.interactive_objects)
 
-      for (var i = 0; i < intersects.length; i++) {
-        intersects[i].object.material.color.set(0xff0000)
+      // console.log('intersects', intersects)
+      // console.log('camera', this.camera)
+      // console.log('TWEEN', TWEEN)
+      let object, vnode, topos
+      let cam = this.camera
+      // let camControls = this.cam_controls
+      let camPos = { ...this.camera.position }
+      // console.log('camPos', camPos)
+      if (intersects.length) {
+        for (var i = 0; i < intersects.length; i++) {
+          // intersects[i].object.material.color.set(0xff0000)
+          object = intersects[i].object
+          vnode = object.userData.vnode
+          vnode.isOpened = true
+          // this.cam_controls.target = object.position
+
+          new TWEEN.Tween(this.controls.cam_target)
+            .to(object.position, 400)
+            .start()
+
+          // cam.position.set({ x: camPos.x, y: camPos.y, z: camPos.z })
+          // camControls.update()
+          topos = { ...object.position }
+          topos.z += 20
+          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
+        }
+      } else {
+        // new TWEEN.Tween(this.camera.position)
+        //   .to(this.init_cam_pos, 1000)
+        //   .start()
+      }
+    },
+    animate (tt) {
+      this.controls.lat = Math.max(-85, Math.min(85, this.controls.lat))
+      this.controls.phi = this.deg2rad(90 - this.controls.lat)
+      this.controls.theta = this.deg2rad(this.controls.lon)
+
+      // if (this.controls.user_interact === false) {
+      //   this.controls.lon += 0.1
+      // }
+
+      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)
       }
+
+      TWEEN.update()
     }
   }
 }

+ 39 - 0
src/components/objects/ContentBlock.vue

@@ -0,0 +1,39 @@
+<template>
+  <mesh name="ContentBlock" :position="position">
+    <geometry type="Box" :args="[size.x, size.y, size.z]" />
+    <material type="MeshLambert" :color="color" :options="opts" />
+  </mesh>
+</template>
+
+<script>
+import * as THREE from 'three'
+
+export default {
+  name: 'ContentBlock',
+  // mixins: [Object3D],
+  props: { prtPosition: Object, prtSize: Object },
+  data: () => ({
+    color: 0xffffff,
+    size: { x: 2, y: 2, z: 2 },
+    position: { x: 0, y: 5, z: 2 },
+    opts: {
+      side: THREE.DoubleSide
+      // wireframe: false,
+      // transparent: false,
+      // opacity: 0.6
+    }
+  }),
+  created () {
+    console.log('ContentBlock created', this.prtSize)
+    this.position.x = this.prtPosition.x - this.prtSize.x / 2 + Math.random() * this.prtSize.x
+
+    // console.log('this.position.y', this.position.y)
+    if (Math.random() > 0.5) {
+      this.position.y = this.prtPosition.y + this.prtSize.y / 2 + Math.random() * 20
+    } else {
+      this.position.y = this.prtPosition.y - this.prtSize.y / 2 - Math.random() * 20
+    }
+    // this.position.z = this.prtPosition.Z
+  }
+}
+</script>

+ 7 - 3
src/components/objects/Plan.vue

@@ -7,9 +7,10 @@
       y:deg2rad(rotation.y),
       z:deg2rad(rotation.z)
     }"
+    :options="mesh_opts"
   >
     <geometry type="PlaneBuffer" :args="[size.w, size.h]" />
-    <material type="MeshBasic" :color="color" :options="opts" />
+    <material type="MeshLambert" :color="color" :options="opts" />
   </mesh>
 </template>
 
@@ -28,12 +29,15 @@ export default {
     rotation: Object
   },
   data: () => ({
+    mesh_opts: {
+      receiveShadow: true,
+      castShadow: true
+    },
     opts: {
       side: THREE.DoubleSide,
       wireframe: false,
       transparent: true,
-      opacity: 0.5,
-      renderOrder: 0
+      opacity: 0.4
     }
   })
 }

+ 45 - 14
src/components/objects/Project.vue

@@ -1,40 +1,58 @@
 <template>
   <div>
-    <mesh name="Project" :position="position">
+    <mesh ref="block3d" name="Project" :position="position">
       <geometry type="Box" :args="[size.x, size.y, size.z]" />
-      <material type="MeshLambert" :color="color" :options="block_opts" />
+      <material type="MeshLambert" :color="color" :options="block_opts">
+        <!-- <texture :options="label_texture_opts" /> -->
+      </material>
     </mesh>
-    <mesh name="Label" :position="label_position">
+    <mesh ref="label3d" name="Label" :position="label_position">
       <geometry type="Plane" :args="[label_size.x, label_size.y]" />
-      <material type="MeshBasic" :options="label_opts">
+      <material type="MeshLambert" :options="label_opts">
         <texture :options="label_texture_opts" />
       </material>
     </mesh>
+    <div v-if="isOpened">
+      <ContentBlock v-for="n in 10" :key="n" :prtPosition="position" :prtSize="size" />
+    </div>
   </div>
 </template>
 
 <script>
 import * as THREE from 'three'
-// import { Object3D } from '@'
+// import { Base } from 'vue-threejs'
+
+import ContentBlock from 'components/objects/ContentBlock'
 
 export default {
   name: 'Project',
-  // mixins: [Object3D],
+  components: {
+    ContentBlock
+  },
+  // mixins: [Base],
   // props: { size: Object, texture: String, position: Object, color: Number },
   props: { data: Object, len: Number, index: Number },
   data: () => ({
+    // mesh_opts: {
+    //   userData: {
+    //     test: 'Hello!'
+    //   },
+    //   receiveShadow: true,
+    //   castShadow: true
+    // },
+    block3d: null,
     block_opts: {
       side: THREE.DoubleSide,
       wireframe: false
       // transparent: true,
       // opacity: 0.6
       // renderOrder: 0
-
     },
+    label3d: null,
     label_opts: {
       side: THREE.DoubleSide,
       // wireframe: false,
-      transparent: true
+      transparent: false
       // opacity: 0.6
       // renderOrder: 0
     },
@@ -43,7 +61,8 @@ export default {
     label_position: { x: 5, y: 5, z: 6 },
     color: 0xffffff,
     label_canvas: null,
-    label_size: null
+    label_size: null,
+    isOpened: false
   }),
   computed: {
     label_texture_opts () {
@@ -57,19 +76,31 @@ export default {
   },
   created () {
     // console.log('this.index', this.index)
+    // this.position = { x: 5, y: 5, z: 0 }
     this.size.y = 30 + Math.random() * 90
     this.position.y = -10 + Math.random() * this.size.y / 2
     // this.label_position.y = this.position.y + this.size.y / 2 - 5
     this.label_position.y = 5
     this.position.x = this.label_position.x = (-this.len + 1) / 2 * (this.size.x + 5) + (this.size.x + 5) * this.index
+    this.label_position.z = this.size.z / 2 + 0.1
     this.label_canvas = this.createLabelCanvas()
-    console.log('this.label_canvas', this.label_canvas)
+    // console.log('this.label_canvas', this.label_canvas)
+  },
+  mounted () {
+    // console.log('project mounted', this)
+    this.block3d = this.$refs.block3d.curObj
+    this.block3d.castShadow = true
+    this.block3d.receiveShadow = true
+    this.block3d.userData = {
+      vnode: this
+    }
+    this.label3d = this.$refs.label3d.curObj
   },
   methods: {
     createLabelCanvas () {
-      console.log('createLabelCanvas', this.data.Titre)
+      // console.log('createLabelCanvas', this.data.Titre)
       const size = 48
-      const borderSize = 2
+      const borderSize = 5
       const ctx = document.createElement('canvas').getContext('2d')
       const font = `${size}px bold noto_sans`
       ctx.font = font
@@ -85,8 +116,8 @@ export default {
       ctx.font = font
       ctx.textBaseline = 'top'
 
-      // ctx.fillStyle = 'green'
-      // ctx.fillRect(0, 0, width, height)
+      ctx.fillStyle = 'white'
+      ctx.fillRect(0, 0, width, height)
       ctx.fillStyle = 'black'
       ctx.fillText(this.data.Titre, borderSize, borderSize)
       // console.log('createLabelCanvas', ctx)