threepipe
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

util-buttons.ts 5.7KB

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