356 lines
12 KiB
Vue
356 lines
12 KiB
Vue
<template>
|
|
<div>
|
|
<!-- <object3d ref="block3d" name="Content" :position="position"> -->
|
|
<!-- <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> -->
|
|
<mesh
|
|
v-if="img_canvas"
|
|
ref="img3d"
|
|
name="Content"
|
|
:position="img_position"
|
|
:rotation="{
|
|
x:deg2rad(rotation.x),
|
|
y:deg2rad(rotation.y),
|
|
z:deg2rad(rotation.z)
|
|
}"
|
|
>
|
|
<geometry type="Plane" :args="[img_size.x, img_size.y]" />
|
|
<material type="MeshLambert" :options="img_opts">
|
|
<texture :options="img_texture_opts" />
|
|
</material>
|
|
</mesh>
|
|
<!-- </object3d> -->
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapInstanceState, mapInstanceMutations } from '@urbn/vuex-helpers'
|
|
// import { mapState, mapGetters } from 'vuex'
|
|
|
|
// import { VIMEO } from 'api/vimeo-axios'
|
|
// import qs from 'querystring'
|
|
|
|
import * as THREE from 'three'
|
|
import mixins from 'components/mixins'
|
|
|
|
// We'll determine our module based on the moduleName prop on this component
|
|
// https://www.npmjs.com/package/@urbn/vuex-helpers
|
|
const getModuleName = cmp => `project:${cmp.prtId}`
|
|
|
|
export default {
|
|
name: 'ContentBlock',
|
|
mixins: [mixins],
|
|
props: { prtId: Number, type: String, data: Object },
|
|
data: () => ({
|
|
// block3d: null,
|
|
project: null,
|
|
size: { x: 0, y: 0 },
|
|
position: { x: 0, y: 0, z: 0 },
|
|
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: true
|
|
// // opacity: 0.6
|
|
// // renderOrder: 0
|
|
// },
|
|
img_opts: {
|
|
// side: THREE.DoubleSide,
|
|
// wireframe: false,
|
|
// transparent: true
|
|
// opacity: 0.6
|
|
// renderOrder: 0
|
|
},
|
|
// label_position: { x: 5, y: 5, z: 6 },
|
|
// label_canvas: null,
|
|
// label_size: null,
|
|
preview_img_url: null,
|
|
img_canvas: null,
|
|
img_size: { x: 0, y: 0 },
|
|
img_position: { x: 0, y: 0, z: 0 },
|
|
img_padding: 0.25,
|
|
face: null
|
|
}),
|
|
computed: {
|
|
...mapInstanceState(getModuleName, {
|
|
projSize: state => state.size,
|
|
projPos: state => state.position,
|
|
projWall: state => state.wall,
|
|
gridsContentPlaced: state => state.gridsContentPlaced,
|
|
contents_size_factor: state => state.contents_size_factor
|
|
}),
|
|
color () {
|
|
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
|
|
// }
|
|
// },
|
|
img_texture_opts () {
|
|
return {
|
|
canvas: this.img_canvas,
|
|
minFilter: THREE.LinearFilter,
|
|
wrapS: THREE.ClampToEdgeWrapping,
|
|
wrapT: THREE.ClampToEdgeWrapping
|
|
}
|
|
},
|
|
id () {
|
|
return this.data.id
|
|
}
|
|
},
|
|
created () {
|
|
if (this.data.Vimeo) {
|
|
this.preview_img_url = this.data.Vimeo.thumbnail_url_with_play_button
|
|
} else if (this.data.Media && this.data.Media.length) {
|
|
this.preview_img_url = `https://api.anarchive-muntadas.figli.io${this.data.Media[0].url}`
|
|
}
|
|
|
|
if (this.preview_img_url) {
|
|
// this.size.x = this.projWall.winW * this.contents_size_factor
|
|
// this.size.y = this.projWall.winH * this.contents_size_factor
|
|
|
|
// get the right size depending on screen
|
|
let u
|
|
if (window.innerWidth > window.innerHeight) {
|
|
u = window.innerHeight / window.innerWidth
|
|
} else {
|
|
u = window.innerWidth / window.innerHeight
|
|
}
|
|
this.size.x = this.projWall.winW * this.contents_size_factor
|
|
this.size.y = this.projWall.winH * u * this.contents_size_factor
|
|
// console.log(`windowW :${window.innerWidth}, windowH :${window.innerHeight}, winW : ${this.projWall.winW}, winH : ${this.projWall.winH}, size.x :${this.size.x}, size.y :${this.size.y}`)
|
|
|
|
// 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
|
|
// let top = this.projPos.y + this.projSize.y / 2
|
|
// let floor = this.projPos.y - this.projSize.y / 2
|
|
// switch (this.type) {
|
|
// case 'visible':
|
|
// y = top * Math.random()
|
|
// break
|
|
// case 'context':
|
|
// y = floor / 3 * Math.random()
|
|
// break
|
|
// case 'process':
|
|
// y = floor / 3 + floor / 3 * Math.random()
|
|
// break
|
|
// case 'concept':
|
|
// y = (floor / 3) * 2 + floor / 3 * Math.random()
|
|
// break
|
|
// }
|
|
// this.position.y = y
|
|
|
|
let face = Math.random()
|
|
// // USES 4 FACES
|
|
// if (face < 0.25) {
|
|
// // gauche
|
|
// this.face = 'left'
|
|
// this.position.x = this.projPos.x - this.projSize.x / 2 + 0.1
|
|
// this.position.z = this.projPos.z - this.projSize.z / 2 + this.size.x / 2 + Math.random() * (this.projSize.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.projPos.z - this.projSize.z / 2 + 0.1
|
|
// this.position.x = this.projPos.x - this.projSize.x / 2 + this.size.x / 2 + Math.random() * (this.projSize.x - this.size.x / 2)
|
|
// } else if (face >= 0.5 && face < 0.75) {
|
|
// // droite
|
|
// this.face = 'right'
|
|
// this.position.x = this.projPos.x + this.projSize.x / 2 - 0.1
|
|
// this.position.z = this.projPos.z - this.projSize.z / 2 + this.size.x / 2 + Math.random() * (this.projSize.z - this.size.x / 2)
|
|
// this.rotation.y = -90
|
|
// } else {
|
|
// // face
|
|
// this.face = 'front'
|
|
// this.position.z = this.projPos.z + this.projSize.z / 2 - 0.1
|
|
// this.position.x = this.projPos.x - this.projSize.x / 2 + this.size.x / 2 + Math.random() * (this.projSize.x - this.size.x / 2)
|
|
// this.rotation.y = 180
|
|
// }
|
|
|
|
// RANDOMLY USE 2 FACES
|
|
if (face < 0.5) {
|
|
this.face = 'left'
|
|
} else {
|
|
this.face = 'right'
|
|
}
|
|
// define side
|
|
let side
|
|
switch (this.face) {
|
|
case 'back':
|
|
case 'front':
|
|
side = 'x'
|
|
break
|
|
case 'left':
|
|
case 'right':
|
|
side = 'z'
|
|
break
|
|
}
|
|
// Get GRID's CEL
|
|
if (typeof this.gridsContentPlaced[side] === 'undefined' ||
|
|
typeof this.gridsContentPlaced[side][this.face] === 'undefined' ||
|
|
typeof this.gridsContentPlaced[side][this.face][this.type] === 'undefined' ||
|
|
typeof this.gridsContentPlaced[side][this.face][this.type][this.id] === 'undefined') {
|
|
// First shift grid place (will transfer it from free places to occupied places)
|
|
this.shiftGrid({ face: this.face, type: this.type, id: this.id })
|
|
}
|
|
// rotation and position
|
|
let gridPos = this.gridsContentPlaced[side][this.face][this.type][this.id]
|
|
console.log('gridPos', gridPos)
|
|
switch (side) {
|
|
case 'x':
|
|
this.position.x = this.projPos.x - this.projSize.x / 2 + gridPos.x
|
|
this.position.y = this.projPos.y - this.projSize.y / 2 + gridPos.y
|
|
switch (this.face) {
|
|
case 'face':
|
|
this.position.z = this.projPos.z + this.projSize.z / 2 - 0.1
|
|
this.rotation.y = 180
|
|
break
|
|
case 'back':
|
|
this.position.z = this.projPos.z - this.projSize.z / 2 + 0.1
|
|
this.rotation.y = 0
|
|
break
|
|
}
|
|
break
|
|
case 'z':
|
|
this.position.z = this.projPos.z - this.projSize.z / 2 + gridPos.z
|
|
this.position.y = this.projPos.y - this.projSize.y / 2 + gridPos.y
|
|
switch (this.face) {
|
|
case 'left':
|
|
this.position.x = this.projPos.x - this.projSize.x / 2 + 0.1
|
|
this.rotation.y = 90
|
|
break
|
|
case 'right':
|
|
this.position.x = this.projPos.x + this.projSize.x / 2 - 0.1
|
|
this.rotation.y = -90
|
|
break
|
|
}
|
|
break
|
|
}
|
|
|
|
// console.log(this.data.Media[0].url)
|
|
// create image object with a promise (async img loading)
|
|
this.createImgCanvas(this.preview_img_url)
|
|
.then(({ img, canvas }) => {
|
|
// console.log('THEN img loaded ok', this, img, canvas)
|
|
// canvas is way bigger than displayable for good resolution
|
|
// reduce it keeping good resolution
|
|
// and fit the width and height to the screen
|
|
let f
|
|
if (canvas.width >= canvas.height) {
|
|
f = this.size.x / canvas.width
|
|
this.img_size.x = canvas.width * f - this.img_padding * 2
|
|
this.img_size.y = this.size.y = canvas.height * f - this.img_padding * 2
|
|
} else {
|
|
f = this.size.y / canvas.height
|
|
this.img_size.y = canvas.height * f - this.img_padding * 2
|
|
this.img_size.x = this.size.x = canvas.width * f - this.img_padding * 2
|
|
}
|
|
console.log(`size.x :${this.size.x}, size.y :${this.size.y}, canvas.width: ${canvas.width}, canvas.height: ${canvas.height}, f: ${f}, img_size.x: ${this.img_size.x}, img_size.y: ${this.img_size.y}`)
|
|
|
|
this.img_position.y = this.position.y - this.size.y / 2 - this.img_size.y / 2
|
|
switch (this.face) {
|
|
case 'left':
|
|
this.img_position.z = this.position.z + this.size.x / 2 - this.img_size.x / 2
|
|
this.img_position.x = this.position.x
|
|
break
|
|
case 'back':
|
|
this.img_position.x = this.position.x - this.size.x / 2 + this.img_size.x / 2
|
|
this.img_position.z = this.position.z
|
|
break
|
|
case 'right':
|
|
this.img_position.z = this.position.z - this.size.x / 2 + this.img_size.x / 2
|
|
this.img_position.x = this.position.x
|
|
break
|
|
case 'front':
|
|
this.img_position.x = this.position.x + this.size.x / 2 - this.img_size.x / 2
|
|
this.img_position.z = this.position.z
|
|
break
|
|
}
|
|
this.img_canvas = canvas
|
|
this.curObj.needsUpdate()
|
|
// this.imgObj = this.$refs.img3d.curObj
|
|
// // record self references
|
|
// this.imgObj.userData = {
|
|
// vnode: this
|
|
// }
|
|
})
|
|
.catch(function () {
|
|
console.warn('CATCH img load ERROR')
|
|
})
|
|
}
|
|
// this.img_position = { ...this.position }
|
|
// this.img_position.y -= this.size.y
|
|
},
|
|
mounted () {
|
|
// this.block3d = this.$refs.block3d.curObj
|
|
// this.block3d.castShadow = true
|
|
// this.block3d.receiveShadow = true
|
|
},
|
|
updated () {
|
|
if (!this.curObj && this.$refs.img3d) {
|
|
this.curObj = this.$refs.img3d.curObj
|
|
// record self references
|
|
this.curObj.userData = {
|
|
vnode: this
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
...mapInstanceMutations(getModuleName, {
|
|
shiftGrid: 'shiftGrid'
|
|
}),
|
|
open () {
|
|
this.isOpened = true
|
|
// this.loadContents()
|
|
}
|
|
}
|
|
}
|
|
</script>
|