Project.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <template>
  2. <div>
  3. <mesh ref="block3d" name="Project" :position="position">
  4. <geometry type="Box" :args="[size.x, size.y, size.z]" />
  5. <material type="MeshLambert" :color="color" :options="block_opts">
  6. <!-- <texture :options="label_texture_opts" /> -->
  7. </material>
  8. </mesh>
  9. <mesh ref="label3d" name="Label" :position="label_position">
  10. <geometry type="Plane" :args="[label_size.x, label_size.y]" />
  11. <material type="MeshLambert" :options="label_opts">
  12. <texture :options="label_texture_opts" />
  13. </material>
  14. </mesh>
  15. <div v-if="isOpened">
  16. <ContentBlock v-for="n in 10" :key="n" :prtPosition="position" :prtSize="size" />
  17. </div>
  18. </div>
  19. </template>
  20. <script>
  21. import * as THREE from 'three'
  22. // import { Base } from 'vue-threejs'
  23. import ContentBlock from 'components/objects/ContentBlock'
  24. export default {
  25. name: 'Project',
  26. components: {
  27. ContentBlock
  28. },
  29. // mixins: [Base],
  30. // props: { size: Object, texture: String, position: Object, color: Number },
  31. props: { data: Object, len: Number, index: Number },
  32. data: () => ({
  33. // mesh_opts: {
  34. // userData: {
  35. // test: 'Hello!'
  36. // },
  37. // receiveShadow: true,
  38. // castShadow: true
  39. // },
  40. block3d: null,
  41. block_opts: {
  42. side: THREE.DoubleSide,
  43. wireframe: false
  44. // transparent: true,
  45. // opacity: 0.6
  46. // renderOrder: 0
  47. },
  48. label3d: null,
  49. label_opts: {
  50. side: THREE.DoubleSide,
  51. // wireframe: false,
  52. transparent: false
  53. // opacity: 0.6
  54. // renderOrder: 0
  55. },
  56. size: { x: 35, y: 10, z: 10 },
  57. position: { x: 5, y: 5, z: 0 },
  58. label_position: { x: 5, y: 5, z: 6 },
  59. color: 0xffffff,
  60. label_canvas: null,
  61. label_size: null,
  62. isOpened: false
  63. }),
  64. computed: {
  65. label_texture_opts () {
  66. return {
  67. canvas: this.label_canvas,
  68. minFilter: THREE.LinearFilter,
  69. wrapS: THREE.ClampToEdgeWrapping,
  70. wrapT: THREE.ClampToEdgeWrapping
  71. }
  72. }
  73. },
  74. created () {
  75. // console.log('this.index', this.index)
  76. // this.position = { x: 5, y: 5, z: 0 }
  77. this.size.y = 30 + Math.random() * 90
  78. this.position.y = -10 + Math.random() * this.size.y / 2
  79. // this.label_position.y = this.position.y + this.size.y / 2 - 5
  80. this.label_position.y = 5
  81. this.position.x = this.label_position.x = (-this.len + 1) / 2 * (this.size.x + 5) + (this.size.x + 5) * this.index
  82. this.label_position.z = this.size.z / 2 + 0.1
  83. this.label_canvas = this.createLabelCanvas()
  84. // console.log('this.label_canvas', this.label_canvas)
  85. },
  86. mounted () {
  87. // console.log('project mounted', this)
  88. this.block3d = this.$refs.block3d.curObj
  89. this.block3d.castShadow = true
  90. this.block3d.receiveShadow = true
  91. this.block3d.userData = {
  92. vnode: this
  93. }
  94. this.label3d = this.$refs.label3d.curObj
  95. },
  96. methods: {
  97. createLabelCanvas () {
  98. // console.log('createLabelCanvas', this.data.Titre)
  99. const size = 48
  100. const borderSize = 5
  101. const ctx = document.createElement('canvas').getContext('2d')
  102. const font = `${size}px bold noto_sans`
  103. ctx.font = font
  104. // measure how long the name will be
  105. const doubleBorderSize = borderSize * 2
  106. const width = ctx.measureText(this.data.Titre).width + doubleBorderSize
  107. const height = size + doubleBorderSize
  108. this.label_size = { x: width / 21, y: height / 21 }
  109. ctx.canvas.width = width
  110. ctx.canvas.height = height
  111. // need to set font again after resizing canvas
  112. ctx.font = font
  113. ctx.textBaseline = 'top'
  114. ctx.fillStyle = 'white'
  115. ctx.fillRect(0, 0, width, height)
  116. ctx.fillStyle = 'black'
  117. ctx.fillText(this.data.Titre, borderSize, borderSize)
  118. // console.log('createLabelCanvas', ctx)
  119. return ctx.canvas
  120. }
  121. }
  122. }
  123. </script>