threepipe
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import {AViewerPlugin, Class, createDiv, FullScreenPlugin, ThreeViewer} from 'threepipe'
  2. import {autoRotateCC, collapse, expand, resetSettings, trash} from './icons'
  3. import tippy, {createSingleton} from 'tippy.js'
  4. export function createUtilButtons(viewer: ThreeViewer, allPlugins: Class<AViewerPlugin>[]) {
  5. return [
  6. {
  7. id: 'reset-settings',
  8. icon: resetSettings,
  9. tooltip: 'Reset All Settings',
  10. onclick: async() => {
  11. if (!await viewer.dialog.confirm('Reset settings: Are you sure you want to reset all plugin settings?')) return
  12. const ps = allPlugins.map(p => viewer.getPlugin(p)!)
  13. for (const p of ps) {
  14. await (p as any)?.resetDefaults?.() // set in TweakpaneUiPlugin
  15. }
  16. },
  17. },
  18. {
  19. id: 'clear-scene',
  20. icon: trash,
  21. tooltip: 'Clear Scene',
  22. onclick: async() => {
  23. if (!await viewer.dialog.confirm('Clear scene: Are you sure you want to clear the scene?')) return
  24. viewer.scene.disposeSceneModels()
  25. },
  26. },
  27. // {
  28. // id: 'fit-scene',
  29. // icon: focus,
  30. // tooltip: 'Fit Object/Scene',
  31. // onclick: async() => {
  32. // await viewer.fitToView(viewer.getPlugin(PickingPlugin)?.getSelectedObject())
  33. // },
  34. // },
  35. // {
  36. // id: 'loop-cam-views',
  37. // icon: loopCamViews,
  38. // tooltip: 'Loop Camera Views',
  39. // toggle: true,
  40. // onclick: async() => {
  41. // if (!viewer.getPlugin(CameraViewPlugin)) return
  42. // viewer.getPlugin(CameraViewPlugin)!.viewLooping = !viewer.getPlugin(CameraViewPlugin)!.viewLooping
  43. // },
  44. // },
  45. // {
  46. // id: 'play-gltf',
  47. // icon: playIcon,
  48. // tooltip: 'GLTF Animations',
  49. // toggle: true,
  50. // onclick: async() => {
  51. // viewer.getPlugin(GLTFAnimationPlugin)?.playPauseAnimation()
  52. // },
  53. // },
  54. {
  55. id: 'auto-rotate-cc',
  56. icon: autoRotateCC,
  57. tooltip: 'Auto rotate',
  58. toggle: true,
  59. onclick: async() => {
  60. const controls = viewer.scene.mainCamera.controls
  61. if (controls?.autoRotate === undefined) return
  62. controls.autoRotate = !controls.autoRotate
  63. },
  64. },
  65. // {
  66. // id: 'snapshot',
  67. // icon: snapshot,
  68. // tooltip: 'Capture Snapshot',
  69. // onclick: async() => {
  70. // const s = viewer.getPlugin(CanvasSnipperPlugin)
  71. // if (!s) {
  72. // viewer.console.error('CanvasSnipperPlugin not added')
  73. // return
  74. // }
  75. // await s.downloadSnapshot()
  76. // },
  77. // },
  78. // {
  79. // id: 'glb-export',
  80. // icon: download,
  81. // tooltip: 'Export GLB',
  82. // onclick: async() => {
  83. // const exporter = viewer.getPlugin(AssetExporterPlugin)
  84. // if (!exporter) {
  85. // viewer.console.error('AssetExporterPlugin not added')
  86. // return
  87. // }
  88. // await exporter?.downloadSceneGlb()
  89. // },
  90. // },
  91. ]
  92. }
  93. export function setupFullscreenButton(viewer: ThreeViewer) {
  94. const fullScreenButton = createDiv({
  95. innerHTML: expand,
  96. id: 'fsToggle',
  97. classList: ['round-button'],
  98. addToBody: false,
  99. })
  100. fullScreenButton.dataset.tippyContent = 'Full-Screen'
  101. viewer.getPlugin(FullScreenPlugin)?.addEventListener('enter', () => {
  102. fullScreenButton.innerHTML = collapse
  103. fullScreenButton.dataset.tippyContent = 'Exit Full-Screen'
  104. })
  105. viewer.getPlugin(FullScreenPlugin)?.addEventListener('exit', () => {
  106. fullScreenButton.innerHTML = expand
  107. fullScreenButton.dataset.tippyContent = 'Full-Screen'
  108. })
  109. fullScreenButton.onclick = () => {
  110. viewer.getPlugin(FullScreenPlugin)?.toggle(viewer.container)
  111. }
  112. viewer.container.appendChild(fullScreenButton)
  113. tippy(fullScreenButton, {
  114. placement: 'left',
  115. })
  116. }
  117. export function setupUtilButtonsBar(viewer: ThreeViewer, allPlugins: Class<AViewerPlugin>[]) {
  118. const utilButtonsContainer = createDiv({
  119. classList: ['button-bar', 'util-buttons-container'],
  120. addToBody: false,
  121. })
  122. viewer.container.appendChild(utilButtonsContainer)
  123. const utilButtons = createUtilButtons(viewer, allPlugins)
  124. for (const utilButton of utilButtons) {
  125. const button = createDiv({
  126. innerHTML: utilButton.icon,
  127. id: utilButton.id,
  128. classList: ['button-bar-button', 'util-button'],
  129. addToBody: false,
  130. })
  131. button.dataset.tippyContent = utilButton.tooltip
  132. button.onclick = () => {
  133. if (utilButton.toggle) {
  134. button.classList.toggle('button-bar-selected-box')
  135. }
  136. utilButton.onclick()
  137. }
  138. utilButtonsContainer.appendChild(button)
  139. }
  140. createSingleton(tippy('.util-button'), {
  141. moveTransition: 'transform 0.2s ease-out',
  142. placement: 'top',
  143. })
  144. }