SceneGraphItem.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <script setup lang="ts">
  2. import { computed, ref } from 'vue'
  3. import { useDevtoolsHook } from '../composables/useDevtoolsHook'
  4. import type { SceneGraphObject } from '../types'
  5. const props = withDefaults(defineProps<{
  6. item: SceneGraphObject
  7. depth?: number
  8. }>(), {
  9. depth: 0,
  10. })
  11. const isExpanded = ref(false)
  12. const { highlightObject, unhighlightObject, selectObject } = useDevtoolsHook()
  13. function roundNumber(num: number) {
  14. return Math.round((num + Number.EPSILON) * 100) / 100
  15. }
  16. function handleClick() {
  17. isExpanded.value = !isExpanded.value
  18. isExpanded.value ? highlightObject(props.item) : unhighlightObject()
  19. selectObject(props.item)
  20. }
  21. </script>
  22. <template>
  23. <div
  24. :class="{ 'text-sm text-gray-400 font-mono': depth > 0 }"
  25. >
  26. <div
  27. class="flex gap-2 items-end cursor-pointer pt2 mb2"
  28. @click="handleClick"
  29. >
  30. <span
  31. v-if="depth > 0"
  32. class="h-1 border-b border-gray-300 w-4"
  33. />
  34. <div
  35. v-if="depth > 0"
  36. class="flex gap-2 items-center -mb2.5"
  37. >
  38. <Icon :name="item.icon" />
  39. <!-- <i :class="item.icon" /> -->{{ item.type }}
  40. <UBadge
  41. v-if="item.name "
  42. variant="soft"
  43. >
  44. {{ item.name }}
  45. </UBadge>
  46. <template v-if="item.type.includes('Light') && !isExpanded">
  47. <UBadge
  48. color="gray"
  49. variant="soft"
  50. >
  51. <span
  52. class="w4 h4 rounded-full mr-2 border border-gray-200"
  53. :style="{ backgroundColor: `#${item.color}` }"
  54. />
  55. #{{ item.color }}
  56. </UBadge>
  57. <UBadge
  58. color="green"
  59. variant="soft"
  60. >
  61. {{ item.intensity }}
  62. </UBadge>
  63. </template>
  64. <template v-if="item.type.includes('Camera') && !isExpanded">
  65. <UTooltip
  66. text="X"
  67. >
  68. <UBadge
  69. color="gray"
  70. variant="soft"
  71. >
  72. {{ roundNumber(item.position.x) }}
  73. </UBadge>
  74. </UTooltip>
  75. <UTooltip
  76. text="Y"
  77. >
  78. <UBadge
  79. color="gray"
  80. variant="soft"
  81. >
  82. {{ roundNumber(item.position.y) }}
  83. </UBadge>
  84. </UTooltip>
  85. <UTooltip
  86. text="Z"
  87. >
  88. <UBadge
  89. color="gray"
  90. variant="soft"
  91. >
  92. {{ roundNumber(item.position.z) }}
  93. </UBadge>
  94. </UTooltip>
  95. </template>
  96. </div>
  97. </div>
  98. <div
  99. v-if="isExpanded || depth === 0"
  100. :class="{ 'border-l border-gray-300': item.children.length > 0, 'ml2.5': depth === 0, 'ml6.5': depth > 0 }"
  101. >
  102. <template v-if="item.children.length > 0">
  103. <SceneGraphItem
  104. v-for="(child, index) in item.children"
  105. :key="index"
  106. :depth="depth + 1"
  107. :item="child"
  108. />
  109. </template>
  110. <template v-else>
  111. <div class="p4 text-gray-400 text-xs font-mono">
  112. <div
  113. v-if="item.geometry"
  114. class="mb-2 flex items-center gap-2"
  115. >
  116. <strong>Geometry</strong>
  117. <UBadge
  118. color="gray"
  119. variant="soft"
  120. >
  121. <i class="i-iconoir-box-3d-three-points mr2" />
  122. <a
  123. :href="`https://threejs.org/docs/#api/en/geometries/${item.geometry.type}`"
  124. target="_blank"
  125. >
  126. {{ item.geometry.type.replace('Geometry', '') }}
  127. </a>
  128. </UBadge>
  129. </div>
  130. <div
  131. v-if="item.material"
  132. class="mb-2 flex items-center gap-2"
  133. >
  134. <strong>Material</strong>
  135. <UBadge
  136. color="gray"
  137. variant="soft"
  138. >
  139. <i class="i-iconoir-select-face-3d mr2" />
  140. <a
  141. :href="`https://threejs.org/docs/#api/en/materials/${item.material.type}`"
  142. target="_blank"
  143. >
  144. {{ item.material?.type.replace('Material', '') }}
  145. </a>
  146. </UBadge>
  147. <UBadge
  148. v-if="item.material.color"
  149. color="gray"
  150. variant="soft"
  151. >
  152. <span
  153. class="w4 h4 rounded-full mr-2 border border-gray-200"
  154. :style="{ backgroundColor: `#${item.material.color.getHexString()}` }"
  155. />
  156. #{{ item.material.color.getHexString() }}
  157. </UBadge>
  158. </div>
  159. <div
  160. v-if="item.color"
  161. class="mb-2 flex items-center gap-2"
  162. >
  163. <strong>Color</strong>
  164. <UTooltip
  165. text="Color"
  166. >
  167. <UBadge
  168. color="gray"
  169. variant="soft"
  170. >
  171. <span
  172. class="w4 h4 rounded-full mr-2 border border-gray-200"
  173. :style="{ backgroundColor: `#${item.color}` }"
  174. />
  175. #{{ item.color }}
  176. </UBadge>
  177. </UTooltip>
  178. </div>
  179. <div
  180. v-if="item.color"
  181. class="mb-2 flex items-center gap-2"
  182. >
  183. <strong>Intensity</strong>
  184. <UTooltip
  185. text="Intensity"
  186. >
  187. <UBadge
  188. color="gray"
  189. variant="soft"
  190. >
  191. {{ item.intensity }}
  192. </UBadge>
  193. </UTooltip>
  194. </div>
  195. <div class="flex items-center mb2 gap-2">
  196. <UTooltip
  197. text="Position"
  198. >
  199. <i
  200. class="i-iconoir-axes mr1"
  201. />
  202. </UTooltip>
  203. <UTooltip
  204. text="X"
  205. >
  206. <UBadge
  207. color="gray"
  208. variant="soft"
  209. >
  210. {{ roundNumber(item.position.x) }}
  211. </UBadge>
  212. </UTooltip>
  213. <UTooltip
  214. text="Y"
  215. >
  216. <UBadge
  217. color="gray"
  218. variant="soft"
  219. >
  220. {{ roundNumber(item.position.y) }}
  221. </UBadge>
  222. </UTooltip>
  223. <UTooltip
  224. text="Z"
  225. >
  226. <UBadge
  227. color="gray"
  228. variant="soft"
  229. >
  230. {{ roundNumber(item.position.z) }}
  231. </UBadge>
  232. </UTooltip>
  233. </div>
  234. <div class="flex items-center mb2 gap-2">
  235. <UTooltip
  236. text="Rotation"
  237. >
  238. <i class="i-carbon-rotate-clockwise mr-1" />
  239. </UTooltip>
  240. <UTooltip
  241. text="X"
  242. >
  243. <UBadge
  244. color="gray"
  245. variant="soft"
  246. >
  247. {{ roundNumber(item.rotation.x) }}
  248. </UBadge>
  249. </UTooltip>
  250. <UTooltip
  251. text="Y"
  252. >
  253. <UBadge
  254. color="gray"
  255. variant="soft"
  256. >
  257. {{ roundNumber(item.rotation.y) }}
  258. </UBadge>
  259. </UTooltip>
  260. <UTooltip
  261. text="Z"
  262. >
  263. <UBadge
  264. color="gray"
  265. variant="soft"
  266. >
  267. {{ roundNumber(item.rotation.z) }}
  268. </UBadge>
  269. </UTooltip>
  270. </div>
  271. <div
  272. v-if="item.scale"
  273. class="flex items-center mb2 gap-2"
  274. >
  275. <UTooltip
  276. text="Scale"
  277. >
  278. <i class="i-iconoir-ellipse-3d-three-points mr-1" />
  279. </UTooltip>
  280. <UTooltip
  281. text="X"
  282. >
  283. <UBadge
  284. color="gray"
  285. variant="soft"
  286. >
  287. {{ roundNumber(item.scale?.x) }}
  288. </UBadge>
  289. </UTooltip>
  290. <UTooltip
  291. text="Y"
  292. >
  293. <UBadge
  294. color="gray"
  295. variant="soft"
  296. >
  297. {{ roundNumber(item.scale?.y) }}
  298. </UBadge>
  299. </UTooltip>
  300. <UTooltip
  301. text="Z"
  302. >
  303. <UBadge
  304. color="gray"
  305. variant="soft"
  306. >
  307. {{ roundNumber(item.scale?.z) }}
  308. </UBadge>
  309. </UTooltip>
  310. </div>
  311. </div>
  312. </template>
  313. </div>
  314. </div>
  315. </template>