@realsee/dnalogel 4.0.0-webgpu.7 → 4.0.0-webgpu.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/floorplan.js +1 -1
  3. package/dist/index.js +20 -20
  4. package/dist/internal/{BasePlugin-Br1gjzFy.js → BasePlugin-DykvYZVy.js} +2 -2
  5. package/dist/internal/{BasePlugin-Br1gjzFy.js.map → BasePlugin-DykvYZVy.js.map} +1 -1
  6. package/dist/internal/BasePluginWithData-6nBdzY9e.js +7 -0
  7. package/dist/internal/{BasePluginWithData-Cz_hCIai.js.map → BasePluginWithData-6nBdzY9e.js.map} +1 -1
  8. package/dist/internal/{CSS3DObject-C9ck81UX.js → CSS3DObject-Bra0eAMf.js} +3 -2
  9. package/dist/internal/CSS3DObject-Bra0eAMf.js.map +1 -0
  10. package/dist/internal/{CSS3DRender-BKWjq-Mo.js → CSS3DRender-Du8bC8b8.js} +2 -2
  11. package/dist/internal/{CSS3DRender-BKWjq-Mo.js.map → CSS3DRender-Du8bC8b8.js.map} +1 -1
  12. package/dist/internal/{CSS3DRenderPlugin-CEatgl0m.js → CSS3DRenderPlugin-BuQ7tgJe.js} +3 -3
  13. package/dist/internal/{CSS3DRenderPlugin-CEatgl0m.js.map → CSS3DRenderPlugin-BuQ7tgJe.js.map} +1 -1
  14. package/dist/internal/{Controller-CyIcxTxN.js → Controller-Er0BrDv0.js} +4 -4
  15. package/dist/internal/{Controller-CyIcxTxN.js.map → Controller-Er0BrDv0.js.map} +1 -1
  16. package/dist/internal/{PointHelper-DIhgdjY2.js → PointHelper-qhcK4big.js} +10 -9
  17. package/dist/internal/{PointHelper-DIhgdjY2.js.map → PointHelper-qhcK4big.js.map} +1 -1
  18. package/dist/internal/{Rectangle-DnriNoRJ.js → Rectangle-B31n7TDh.js} +3 -3
  19. package/dist/internal/{Rectangle-DnriNoRJ.js.map → Rectangle-B31n7TDh.js.map} +1 -1
  20. package/dist/internal/{Work-ltxGwn4w.js → Work-XztRkc9j.js} +4 -4
  21. package/dist/internal/{Work-ltxGwn4w.js.map → Work-XztRkc9j.js.map} +1 -1
  22. package/dist/internal/{area-maker-6kaWjqeL.js → area-maker-bVre0AJ9.js} +2 -2
  23. package/dist/internal/{area-maker-6kaWjqeL.js.map → area-maker-bVre0AJ9.js.map} +1 -1
  24. package/dist/internal/{controller-Do-09Spx.js → controller-B-zFQPgF.js} +5 -5
  25. package/dist/internal/{controller-Do-09Spx.js.map → controller-B-zFQPgF.js.map} +1 -1
  26. package/dist/internal/{cruise-Bc8Uyi_j.js → cruise-jHbIppkf.js} +2 -2
  27. package/dist/internal/{cruise-Bc8Uyi_j.js.map → cruise-jHbIppkf.js.map} +1 -1
  28. package/dist/internal/{current-pano-image-CXiCqVoV.js → current-pano-image-DNfrkHuB.js} +2 -2
  29. package/dist/internal/{current-pano-image-CXiCqVoV.js.map → current-pano-image-DNfrkHuB.js.map} +1 -1
  30. package/dist/internal/{floorplan-BVvZ49A3.js → floorplan-RJYWsiTc.js} +2 -2
  31. package/dist/internal/{floorplan-BVvZ49A3.js.map → floorplan-RJYWsiTc.js.map} +1 -1
  32. package/dist/internal/{measure-B4jFwdQ6.js → measure-D6kvLcMk.js} +2 -2
  33. package/dist/internal/{measure-B4jFwdQ6.js.map → measure-D6kvLcMk.js.map} +1 -1
  34. package/dist/internal/{model-chassis-compass-C6NTVMLo.js → model-chassis-compass-rfKL38y2.js} +2 -1
  35. package/dist/internal/model-chassis-compass-rfKL38y2.js.map +1 -0
  36. package/dist/internal/{model-maker-C6fhkpcB.js → model-maker-Cu0GXliA.js} +2 -2
  37. package/dist/internal/{model-maker-C6fhkpcB.js.map → model-maker-Cu0GXliA.js.map} +1 -1
  38. package/dist/internal/{model-tv-video-BP-7HoDC.js → model-tv-video-E71WR84A.js} +2 -2
  39. package/dist/internal/{model-tv-video-BP-7HoDC.js.map → model-tv-video-E71WR84A.js.map} +1 -1
  40. package/dist/internal/object3d-helper-oTuySso1.js +7 -0
  41. package/dist/internal/{object3d-helper-1-TEtUKM.js.map → object3d-helper-oTuySso1.js.map} +1 -1
  42. package/dist/internal/{pano-compass-Bt9eAQQS.js → pano-compass-DfAPVSZU.js} +3 -3
  43. package/dist/internal/{pano-compass-Bt9eAQQS.js.map → pano-compass-DfAPVSZU.js.map} +1 -1
  44. package/dist/internal/{pano-door-label-KjaGohvA.js → pano-door-label-D9vCDCxJ.js} +2 -2
  45. package/dist/internal/{pano-door-label-KjaGohvA.js.map → pano-door-label-D9vCDCxJ.js.map} +1 -1
  46. package/dist/internal/{pano-measure-Cfe9RfWP.js → pano-measure-s-QZthZi.js} +3 -3
  47. package/dist/internal/{pano-measure-Cfe9RfWP.js.map → pano-measure-s-QZthZi.js.map} +1 -1
  48. package/dist/internal/{pano-spatial-tag-B7Gxn3BS.js → pano-spatial-tag-gwN_WDLJ.js} +2 -2
  49. package/dist/internal/{pano-spatial-tag-B7Gxn3BS.js.map → pano-spatial-tag-gwN_WDLJ.js.map} +1 -1
  50. package/dist/internal/{pano-tag-DeWr38_M.js → pano-tag-mnA3Y7eC.js} +2 -2
  51. package/dist/internal/{pano-tag-DeWr38_M.js.map → pano-tag-mnA3Y7eC.js.map} +1 -1
  52. package/dist/internal/{pano-video-CTlwzLiU.js → pano-video-CSb6bzy-.js} +2 -2
  53. package/dist/internal/{pano-video-CTlwzLiU.js.map → pano-video-CSb6bzy-.js.map} +1 -1
  54. package/dist/internal/{pipeline-BqVMSO6-.js → pipeline-CdRT0_qH.js} +2 -2
  55. package/dist/internal/{pipeline-BqVMSO6-.js.map → pipeline-CdRT0_qH.js.map} +1 -1
  56. package/dist/internal/{sculpt-E8oyJAik.js → sculpt-BXBzzG_D.js} +3 -3
  57. package/dist/internal/{sculpt-E8oyJAik.js.map → sculpt-BXBzzG_D.js.map} +1 -1
  58. package/dist/plugins/area-maker.js +1 -1
  59. package/dist/plugins/cruise.js +2 -2
  60. package/dist/plugins/css3d-render.js +1 -1
  61. package/dist/plugins/current-pano-image.js +1 -1
  62. package/dist/plugins/guide-line.js +1 -1
  63. package/dist/plugins/measure.js +1 -1
  64. package/dist/plugins/model-chassis-compass.js +1 -1
  65. package/dist/plugins/model-maker.js +1 -1
  66. package/dist/plugins/model-tv-video.js +1 -1
  67. package/dist/plugins/object3d-helper.js +2 -2
  68. package/dist/plugins/pano-compass.js +1 -1
  69. package/dist/plugins/pano-door-label.js +1 -1
  70. package/dist/plugins/pano-measure.js +1 -1
  71. package/dist/plugins/pano-spatial-tag.js +1 -1
  72. package/dist/plugins/pano-tag.js +2 -2
  73. package/dist/plugins/pano-video.js +1 -1
  74. package/dist/plugins/pipeline.js +1 -1
  75. package/dist/plugins/sculpt.js +2 -2
  76. package/dist/types/shared-utils/CSS3DRender/CSS3DRenderer.d.ts +1 -2
  77. package/dist/types/shared-utils/CSS3DRender/index.d.ts +1 -2
  78. package/dist/types/shared-utils/three/CSS3DRenderer/index.d.ts +2 -3
  79. package/dist/types/shared-utils/three/PointSelector/utils/PointHelper2.d.ts +1 -0
  80. package/dist/utils.js +1 -1
  81. package/package.json +1 -1
  82. package/dist/internal/BasePluginWithData-Cz_hCIai.js +0 -7
  83. package/dist/internal/CSS3DObject-C9ck81UX.js.map +0 -1
  84. package/dist/internal/model-chassis-compass-C6NTVMLo.js.map +0 -1
  85. package/dist/internal/object3d-helper-1-TEtUKM.js +0 -7
@@ -1,5 +1,5 @@
1
1
  import { d as e } from "./defaultUrls-CfMtGzqM.js";
2
- import { t } from "./CSS3DRenderPlugin-CEatgl0m.js";
2
+ import { t } from "./CSS3DRenderPlugin-BuQ7tgJe.js";
3
3
  import { G as n, K as r, L as i, M as a, N as o, O as s, P as c, Q as l, T as u, V as d, X as f, Y as p, b as m, f as h, i as g, it as _, k as v, l as y, m as b, n as x, o as S, ot as C, p as w, q as T, rt as E, st as D, t as O, x as k, y as A, z as j } from "./component.svelte-D5LYqt50.js";
4
4
  import "./index-client-W3QT304M.js";
5
5
  import * as M from "three/webgpu";
@@ -389,4 +389,4 @@ var K = class {
389
389
  //#endregion
390
390
  export { X as t };
391
391
 
392
- //# sourceMappingURL=pano-spatial-tag-B7Gxn3BS.js.map
392
+ //# sourceMappingURL=pano-spatial-tag-gwN_WDLJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pano-spatial-tag-B7Gxn3BS.js","names":["root","$.from_html","$.prop","$.comment","$.first_child","$.index","$.set_class","$.get","$.set_style","$.untrack","$.from_html","$.prop","$.mutable_source","$.get","$.child","$.sibling","$.set","$.set_class","PANO_SPATIAL_TAG_BLUR_IMAGE","template_effect","child","event","append","comment","onDestroy","from_html","set","afterUpdate","untrack","mutable_source","sibling","each","set_attribute","writable","push","onMount","bind_this","set_class","prop","init","next","set_style","first_child","pop","reset","mountComponent","index","html","get","THREE","currentTarget","root$1","Origins","$$props","origins","handleClick","id","fragment","node","i","classes","styles","origin","$$anchor","root","Tag","upsideDown","content","contentZoom","lineWidthZoom","lineHeightZoom","destroying","folded","dispose","events","hooks","blurImageUrl","contentWidth","contentHeight","contentDom","show","timeoutId","handleClickContent","eventsName","classNames","key","unsubscribe","str","currentId","date","div","div_1","div_2","div_3","div_4","$$value","pluginStyle","REGEX_STRING","ENCODE_HTML_RULES","TEMPLATE_MODES","stripSemi","render","Template","template","data","text","src","escapeFn","markup","c","matches","closing","line","pat","result","arr","firstPos","MESH_SIZE","RAY_TOLERANT_DISTANCE","BLUR_IMAGE_URL","PanoSpatialTagPlugin","wrapper","params","centerY","wait","maxNumberOnScreen","minRad","nearTolerance","upsideHeight","minDistance","maxDistance","css3DRender","CSS3DRenderPlugin","five","container","Subscribe","blurImage","state","onCameraUpdate","updateOrigins","userAction","updateTags","onPanoArrived","onPanoWillArrive","rotateRad","pose","camera","frustum","projScreenMatrix","distance","tag","v","onModeChange","mode","Five","direction","mouse","front","newTags","getNewTags","frontTagLength","points","point","_mouse","clientWidth","clientHeight","newPoint","l","anotherPoint","raycaster","intersect","plane","normal","position","right","square","app","replacement","load","setIntersectObjects","objects","enable","disable","unfoldAll","foldAll","unfold","fold","onResize","onModelLoaded"],"sources":["../../src/PanoSpatialTagPlugin/store.ts","../../src/PanoSpatialTagPlugin/Components/origins.svelte","../../src/PanoSpatialTagPlugin/Components/tag.svelte","../../src/PanoSpatialTagPlugin/style.ts","../../src/shared-utils/tinyEJSrender.ts","../../src/PanoSpatialTagPlugin/Plugin.ts"],"sourcesContent":["import { writable } from 'svelte/store'\n\nexport const currentTarget = writable(null)","<script lang=\"ts\">\n import { currentTarget } from '../store'\n import type { PanoSpatialTagPluginOriginElement, PanoSpatialTagPluginId } from '../typings'\n export let origins: Array<PanoSpatialTagPluginOriginElement>\n\n const handleClick = (id: PanoSpatialTagPluginId): void => {\n currentTarget.update((): string => `${id}-PanoSpatialTagPlugin-${Date.now()}`)\n }\n</script>\n\n{#each origins as origin}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <i \n class:PanoSpatialTagPlugin__tag-origin={true}\n class:PanoSpatialTagPlugin__tag-origin-destroy={origin.destroying}\n style:top=\"{origin.top}%\"\n style:left=\"{origin.left}%\"\n style:visibility=\"{origin.front ? 'visible' : 'hidden'}\"\n on:click=\"{() => handleClick(origin.id)}\"\n />\n{/each}\n\n<style>\n .PanoSpatialTagPlugin__tag-origin {\n position: absolute;\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 0 .6rem #fff;\n transform: translate(-50%, -50%) scale(1);\n transform-origin: center center;\n animation: PanoSpatialTagPlugin__tag-origin 1.2s forwards;\n pointer-events: auto;\n }\n\n .PanoSpatialTagPlugin__tag-origin:after {\n content: '';\n position: absolute;\n top: 50%;\n height: 50%;\n width: 2rem;\n height: 2rem;\n transform: translate(-50%, -50%);\n }\n\n .PanoSpatialTagPlugin__tag-origin-destroy {\n transform: translate(-50%, -50%) scale(0.6);\n animation: PanoSpatialTagPlugin__tag-origin-destroy 1.2s forwards .7s;\n }\n\n @keyframes PanoSpatialTagPlugin__tag-origin {\n 0% { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n 100% { transform: translate(-50%, -50%) scale(0.6); opacity: 1 }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-origin-destroy {\n 0% { transform: translate(-50%, -50%) scale(0.6); opacity: 1; }\n 10% { transform: translate(-50%, -50%) scale(1); opacity: 0.9; }\n 100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n }\n</style>\n","<script lang=\"ts\">\n import type { PanoSpatialTagPluginContentEvent } from '../typings'\n import { onMount, onDestroy, afterUpdate } from 'svelte'\n import { currentTarget } from '../store'\n export let id: number | string\n export let upsideDown: boolean\n export let content: string\n export let contentZoom: number\n export let lineWidthZoom: number\n export let lineHeightZoom: number\n export let destroying = false\n export let folded: boolean\n export let dispose: () => void\n export let events: PanoSpatialTagPluginContentEvent\n export let hooks\n export let blurImageUrl: string\n\n let contentWidth = 0\n let contentHeight = 0\n let contentDom: HTMLElement\n let show: boolean\n let timeoutId = setTimeout(() => {\n if (!folded) show = true\n timeoutId = undefined\n }, 100)\n\n const handleClickContent = (event) => {\n const eventsName = Object.keys(events)\n let node = event.target\n while (node) {\n const classNames = node.getAttribute('class')\n if (!classNames) {\n node = node.parentNode\n continue\n }\n if (classNames.includes('PanoSpatialTagPlugin__tag-content')) {\n node = null\n break\n }\n eventsName.forEach((key) => {\n if (classNames.includes(key)) events[key](id)\n })\n node = node.parentNode\n }\n }\n\n onMount(() => {\n hooks.emit('initTag', { id })\n })\n\n const unsubscribe = currentTarget.subscribe((str: string) => {\n if (str === null) return\n const [currentId, date] = str.split('-PanoSpatialTagPlugin-')\n if (id === currentId) {\n hooks.emit('clickOrigin', { id, show })\n if (!timeoutId) {\n show = folded\n folded = !folded\n timeoutId = setTimeout(() => {\n timeoutId = undefined\n }, 1500)\n }\n }\n })\n\n afterUpdate(() => {\n contentWidth = contentDom.offsetWidth\n contentHeight = contentDom.offsetHeight\n if (timeoutId) return\n show = !folded\n })\n\n onDestroy(() => {\n hooks.emit('destroyTag', { id })\n unsubscribe()\n dispose()\n })\n</script>\n\n<div\n class:PanoSpatialTagPlugin__tag-x={true}\n class:PanoSpatialTagPlugin__tag-upside-down={upsideDown}\n class:PanoSpatialTagPlugin__tag-show={show}\n class:PanoSpatialTagPlugin__tag-hide={show === false || destroying}\n id={'PanoSpatialTagPlugin__' + id}\n style=\"height: {20 * lineHeightZoom}rem\"\n>\n <div\n class=\"PanoSpatialTagPlugin__tag-shadow\"\n style=\"transform: translate({(contentWidth / 2) * contentZoom * 3}px, {(contentHeight / 2) *\n (upsideDown ? -1 : 1) *\n contentZoom *\n 3}px) scale({1 / contentZoom}); background-image: url('{blurImageUrl}');\"\n />\n <div class=\"PanoSpatialTagPlugin__tag-line\">\n <i class=\"PanoSpatialTagPlugin__tag-flagpole\" style=\"width: {lineWidthZoom}rem;\" />\n <i class=\"PanoSpatialTagPlugin__tag-line1\" />\n <i class=\"PanoSpatialTagPlugin__tag-line2\" />\n </div>\n <div class=\"PanoSpatialTagPlugin__tag-animate\" style=\"transform: scale({contentZoom * 3})\">\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div class=\"PanoSpatialTagPlugin__tag-content\" on:click={handleClickContent} bind:this={contentDom}>\n {@html content}\n </div>\n </div>\n</div>\n\n<style>\n .PanoSpatialTagPlugin__tag-x {\n position: absolute;\n top: 0;\n left: 0;\n display: block;\n white-space: nowrap;\n box-sizing: border-box;\n width: 25rem;\n height: 14rem;\n color: #fff;\n transform: translate(0, -100%);\n transition: height 0.5s linear;\n }\n\n .PanoSpatialTagPlugin__tag-shadow {\n content: '';\n position: absolute;\n width: 30rem;\n height: 30rem;\n top: -15rem;\n left: -15rem;\n z-index: -1;\n opacity: 0;\n transition: opacity 0.8s 0.6s;\n background-size: 30rem 30rem;\n }\n\n .PanoSpatialTagPlugin__tag-line {\n position: absolute;\n left: -1rem;\n width: 2rem;\n height: 100%;\n overflow: hidden;\n }\n\n .PanoSpatialTagPlugin__tag-flagpole {\n position: absolute;\n top: 0;\n left: 1rem;\n height: calc(100% - 1.5rem);\n width: 0.15rem;\n background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.1));\n box-shadow: 0 0.1rem 0.5rem rgba(0, 0, 0, 0.2);\n opacity: 0;\n transform: translate(-50%, 60%) scaleY(0);\n transition: transform 0.4s cubic-bezier(0.44, 0.44, 0.74, 0.98), opacity 0.4s cubic-bezier(0.44, 0.44, 0.74, 0.98), width 0.5s linear,\n height 0.5s linear;\n transform-origin: center bottom;\n }\n\n .PanoSpatialTagPlugin__tag-line1 {\n position: absolute;\n top: 0;\n left: 0.3rem;\n height: 1.8rem;\n width: 0.1rem;\n background: #fff;\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n transform-origin: center top;\n }\n\n .PanoSpatialTagPlugin__tag-line2 {\n position: absolute;\n top: 0;\n left: 0.5rem;\n height: 1.8rem;\n width: 0.1rem;\n background: #fff;\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n transform-origin: center top;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-line1 {\n animation: PanoSpatialTagPlugin__tag-line1 linear 0.5s forwards 0.45s;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-line2 {\n animation: PanoSpatialTagPlugin__tag-line2 linear 0.5s forwards 0.65s;\n }\n\n .PanoSpatialTagPlugin__tag-x.PanoSpatialTagPlugin__tag-upside-down {\n transform: translate(0, 0);\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-line {\n transform: scaleY(-1);\n }\n\n .PanoSpatialTagPlugin__tag-animate {\n position: relative;\n height: 100%;\n overflow: hidden;\n transform-origin: left top;\n transition: transform 0.5s linear;\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-animate {\n transform-origin: left bottom;\n }\n\n .PanoSpatialTagPlugin__tag-content {\n position: absolute;\n display: inline-block;\n transform: translate(-100%, 0);\n transition: transform 0.9s cubic-bezier(0, 0.65, 0.16, 1.08) 0.6s;\n padding-left: 0.5rem;\n font-size: 1rem;\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-content {\n bottom: 0;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-flagpole {\n opacity: 1;\n transform: translate(-50%, 0) scaleY(1);\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-shadow {\n top: unset;\n bottom: -15rem;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-shadow {\n opacity: 0.32;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-content {\n transform: translate(0, 0);\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-flagpole {\n opacity: 0;\n transform: translate(-50%, 60%) scaleY(0);\n transition: transform 0.5s 0.55s, opacity 0.4s 0.55s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-shadow {\n opacity: 0;\n transition: opacity 0.8s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-content {\n transform: translate(-100%, 0);\n transition: transform 0.6s cubic-bezier(0.53, 0.06, 0.88, 0.59);\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-content * {\n pointer-events: none;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-line1 {\n opacity: 0.5;\n transform: translate(-50%, 10%) scaleY(0);\n animation: PanoSpatialTagPlugin__tag-line1-hide linear 0.28s forwards 0.3s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-line2 {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n animation: PanoSpatialTagPlugin__tag-line2-hide linear 0.28s forwards 0.45s;\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line1 {\n 0% {\n opacity: 0;\n transform: translate(-50%, 250%) scaleY(1);\n }\n 50% {\n opacity: 0.5;\n transform: translate(-50%, 135%) scaleY(1);\n }\n 100% {\n opacity: 0.5;\n transform: translate(-50%, 20%) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line2 {\n 0% {\n opacity: 0;\n transform: translate(-50%, 250%) scaleY(1);\n }\n 50% {\n opacity: 0.5;\n transform: translate(-50%, 125%) scaleY(1);\n }\n 100% {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line1-hide {\n 0% {\n opacity: 0.5;\n transform: translate(-50%, 10%) scaleY(0);\n }\n 50% {\n opacity: 0.2;\n transform: translate(-50%, 105%) scaleY(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line2-hide {\n 0% {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n }\n 50% {\n opacity: 0.2;\n transform: translate(-50%, 100%) scaleY(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n }\n }\n</style>\n","export const pluginStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n top: '0px',\n left: '0px',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n}","const DEFAULT_OPEN_DELIMITER = '<'\nconst DEFAULT_CLOSE_DELIMITER = '>'\nconst DEFAULT_DELIMITER = '%'\nconst DEFAULT_LOCALS_NAME = 'locals'\nconst REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'\nconst ENCODE_HTML_RULES = {\n '&': '&amp',\n '<': '&lt',\n '>': '&gt',\n '\"': '&#34',\n \"'\": '&#39'\n}\nconst TEMPLATE_MODES = {\n EVAL: 'eval',\n ESCAPED: 'escaped',\n RAW: 'raw',\n COMMENT: 'comment',\n LITERAL: 'literal',\n}\n\ninterface RenderData {\n\t[key: string]: string\n}\n\nfunction stripSemi (str: string): string {\n return str.replace(/;(\\s*$)/, '$1')\n}\n\nexport default function render (template: string, data: RenderData): string {\n\tconst templ = new Template(template)\n return templ.compileFunction()(data)\n}\n\nclass Template {\n\tprivate templateText: string\n\tprivate mode = null\n\tprivate truncate = false\n\tprivate currentLine = 1\n\tprivate source = ''\n\tprivate regex = new RegExp(REGEX_STRING)\n\n\tconstructor (text) {\n\t this.templateText = text\n\t}\n\n\tpublic compileFunction () {\n let src\n const prepended = \n \t' var __output = \"\";\\n' +\n ' function __append(s) { if (s !== undefined && s !== null) __output += s }\\n' +\n \t' with (' + DEFAULT_LOCALS_NAME + ' || {}) {' + '\\n'\n const appended = ' }' + '\\n return __output;' + '\\n'\n const escapeFn = function (markup) {\n\t\t return markup == undefined\n\t\t ? ''\n\t\t : String(markup)\n\t\t .replace(/[&<>'\"]/g, function (c) {\n\t\t\t return ENCODE_HTML_RULES[c] || c\n\t\t\t})\n\t\t}\n\n this._generateSource()\n this.source = prepended + this.source + appended\n\n src = this.source\n src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\\n' + src\n\n return new Function(DEFAULT_LOCALS_NAME + ', escapeFn', src)\n }\n\n private _generateSource () {\n this.templateText =\n this.templateText.replace(/[ \\t]*<%_/gm, '<%_').replace(/_%>[ \\t]*/gm, '_%>')\n\n const matches = this._parseTemplateText()\n const d = DEFAULT_DELIMITER\n const o = DEFAULT_OPEN_DELIMITER\n const c = DEFAULT_CLOSE_DELIMITER\n\n if (matches && matches.length) {\n matches.forEach((line, index) => {\n let closing\n if ( line.indexOf(o + d) === 0\n && line.indexOf(o + d + d) !== 0) {\n closing = matches[index + 2]\n if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {\n throw new Error('Could not find matching close tag for \"' + line + '\".')\n }\n }\n this._scanLine(line)\n })\n }\n }\n\n private _parseTemplateText () {\n let str = this.templateText\n const pat = this.regex\n let result = pat.exec(str)\n const arr = []\n let firstPos\n\n while (result) {\n firstPos = result.index\n\n if (firstPos !== 0) {\n arr.push(str.substring(0, firstPos))\n str = str.slice(firstPos)\n }\n\n arr.push(result[0])\n str = str.slice(result[0].length)\n result = pat.exec(str)\n }\n\n if (str) {\n arr.push(str)\n }\n\n return arr\n }\n\n private _addOutput (line) {\n if (this.truncate) {\n line = line.replace(/^(?:\\r\\n|\\r|\\n)/, '')\n this.truncate = false\n }\n if (!line) return line\n\n line = line.replace(/\\\\/g, '\\\\\\\\')\n line = line.replace(/\\n/g, '\\\\n')\n line = line.replace(/\\r/g, '\\\\r')\n line = line.replace(/\"/g, '\\\\\"')\n this.source += ' ; __append(\"' + line + '\")' + '\\n'\n }\n\n private _scanLine (line) {\n const d = DEFAULT_DELIMITER\n const o = DEFAULT_OPEN_DELIMITER\n const c = DEFAULT_CLOSE_DELIMITER\n const newLineCount = line.split('\\n').length - 1\n\n switch (line) {\n\t case o + d:\n\t case o + d + '_':\n\t this.mode = TEMPLATE_MODES.EVAL\n\t break\n\t case o + d + '=':\n\t this.mode = TEMPLATE_MODES.ESCAPED\n\t break\n\t case o + d + '-':\n\t this.mode = TEMPLATE_MODES.RAW\n\t break\n\t case o + d + '#':\n\t this.mode = TEMPLATE_MODES.COMMENT\n\t break\n\t case o + d + d:\n\t this.mode = TEMPLATE_MODES.LITERAL\n\t this.source += ' ; __append(\"' + line.replace(o + d + d, o + d) + '\")' + '\\n'\n\t break\n\t case d + d + c:\n\t this.mode = TEMPLATE_MODES.LITERAL\n\t this.source += ' ; __append(\"' + line.replace(d + d + c, d + c) + '\")' + '\\n'\n\t break\n\t case d + c:\n\t case '-' + d + c:\n\t case '_' + d + c:\n\t if (this.mode == TEMPLATE_MODES.LITERAL) {\n\t this._addOutput(line)\n\t }\n\n\t this.mode = null\n\t this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0\n\t break\n\t default:\n\t if (this.mode) {\n\t switch (this.mode) {\n\t case TEMPLATE_MODES.EVAL:\n\t case TEMPLATE_MODES.ESCAPED:\n\t case TEMPLATE_MODES.RAW:\n\t if (line.lastIndexOf('//') > line.lastIndexOf('\\n')) {\n\t line += '\\n'\n\t }\n\t }\n\t switch (this.mode) {\n\t case TEMPLATE_MODES.EVAL:\n\t this.source += ' ; ' + line + '\\n'\n\t break\n\t case TEMPLATE_MODES.ESCAPED:\n\t this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\\n'\n\t break\n\t case TEMPLATE_MODES.RAW:\n\t this.source += ' ; __append(' + stripSemi(line) + ')' + '\\n'\n\t break\n\t case TEMPLATE_MODES.COMMENT:\n\t break\n\t case TEMPLATE_MODES.LITERAL:\n\t this._addOutput(line)\n\t break\n\t }\n\t }\n\t else {\n\t this._addOutput(line)\n\t }\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { FivePlugin } from '@realsee/five-webgpu'\nimport { Five, Subscribe } from '@realsee/five-webgpu'\nimport CSS3DRenderPlugin from '../CSS3DRenderPlugin'\nimport Origins from './Components/origins.svelte'\nimport Tag from './Components/tag.svelte'\nimport { pluginStyle } from './style'\nimport render from '../shared-utils/tinyEJSrender'\nimport { PANO_SPATIAL_TAG_BLUR_IMAGE } from '../shared-utils'\n\nimport { mountComponent, type MountedComponent } from '../shared-utils/svelte/component.svelte'\nimport type {\n PanoSpatialTagPluginId,\n PanoSpatialTagPluginDataElement,\n PanoSpatialTagPluginTagElement,\n PanoSpatialTagPluginOriginElement,\n PanoSpatialTagPluginPointElement,\n PanoSpatialTagPluginContentReplacement,\n PanoSpatialTagPluginContentEvent,\n} from './typings'\n\nexport interface PanoSpatialTagPluginData {\n // 插件load数据\n folded?: boolean // 标签初始是否收起\n enabled?: boolean // 插件初始是否启用\n points: Array<PanoSpatialTagPluginDataElement>\n template: string // dom模板\n events?: PanoSpatialTagPluginContentEvent\n render?: (template: string, replacement: PanoSpatialTagPluginContentReplacement) => string // 模板数据映射函数\n}\n\nexport interface PanoSpatialTagPluginParameterType {\n container?: Element // 标签容器\n wait?: number // debounce延迟\n maxNumberOnScreen?: number // 屏幕内标签最大展示数量\n minRad?: number // 视角和标签平面最小夹角\n nearTolerance?: number // 标签映射到屏幕之间最小间距\n upsideHeight?: number // 标签反向高度\n minDistance?: number // 标签最小距离,单位米\n maxDistance?: number // 标签最小距离,单位米\n // foldPercent?: number // 标签折叠屏幕百分比\n}\n\nexport interface PanoSpatialTagPluginExportType {\n load: (data: PanoSpatialTagPluginData) => void\n unfoldAll: () => void\n foldAll: () => void\n unfold: (id: PanoSpatialTagPluginId) => void\n fold: (id: PanoSpatialTagPluginId) => void\n enable: () => void\n disable: () => void\n dispose: () => void\n}\n\ninterface PanoSpatialTagPluginState {\n timeoutId?: NodeJS.Timeout\n points: Array<PanoSpatialTagPluginPointElement>\n origins: Array<PanoSpatialTagPluginOriginElement>\n tags: Array<PanoSpatialTagPluginTagElement>\n render: (template: string, replacement: PanoSpatialTagPluginContentReplacement) => string\n events: PanoSpatialTagPluginContentEvent\n intersectObjects?: Array<any> // 碰撞检测objects\n template: string\n folded: boolean // 标签初始收起展开状态\n enabled: boolean // 用户控制启用禁止状态\n forbidden: boolean // 插件控制启用禁止状态\n}\n\nconst MESH_SIZE = 0.001\nconst RAY_TOLERANT_DISTANCE = 0.01\nconst BLUR_IMAGE_URL = PANO_SPATIAL_TAG_BLUR_IMAGE\n\n/**\n * 空间游走标签插件\n */\nexport const PanoSpatialTagPlugin: FivePlugin<PanoSpatialTagPluginParameterType, PanoSpatialTagPluginExportType> = (five: Five, params) => {\n let wrapper = params?.container\n let centerY = 1.4\n const wait = params?.wait ?? 200\n const maxNumberOnScreen = params?.maxNumberOnScreen ?? 3\n const minRad = params?.minRad ?? Math.PI / 4\n const nearTolerance = params?.nearTolerance ?? 100\n const upsideHeight = params?.upsideHeight ?? 1.6\n const minDistance = params?.minDistance ?? 1.2\n const maxDistance = params?.maxDistance ?? 3.5\n // const foldPercent = params?.foldPercent ?? 20\n\n const css3DRender = CSS3DRenderPlugin(five)\n const container = document.createElement('div')\n container.classList.add('PanoSpatialTagPlugin')\n Object.assign(container.style, pluginStyle)\n\n const hooks = new Subscribe()\n\n let blurImage = new Image()\n blurImage.src = BLUR_IMAGE_URL\n\n const state: PanoSpatialTagPluginState = {\n points: [],\n origins: [],\n tags: [],\n template: '',\n events: {},\n render,\n folded: false,\n enabled: true,\n forbidden: true,\n }\n\n const origins = mountComponent(Origins, container, { origins: state.origins })\n\n const onCameraUpdate = (pose, userAction): void => {\n updateOrigins()\n if (userAction) {\n updateTags()\n // state.tags.forEach(tag => {\n // const mouse = tag.position.clone().project(five.camera)\n // const top = ( - mouse.y + 1 ) / 2 * 100\n // })\n }\n }\n\n const onPanoArrived = () => {\n if (state.forbidden) {\n state.forbidden = false\n updateTags()\n }\n }\n\n const onPanoWillArrive = (pano, pose): void => {\n if (state.tags.length === 0) return\n const rotateRad = pose.longitude - five.state.longitude\n const camera = five.camera.clone()\n camera.position.copy(pose.offset)\n camera.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), rotateRad)\n camera.updateProjectionMatrix()\n camera.updateMatrixWorld(true)\n const frustum = new THREE.Frustum()\n const projScreenMatrix = new THREE.Matrix4()\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n frustum.setFromProjectionMatrix(projScreenMatrix, camera.coordinateSystem)\n\n state.tags.forEach((tag) => {\n const distance = camera.position.clone().setY(centerY).distanceTo(tag.position)\n if (distance < minDistance || distance > maxDistance) return (tag.destroying = true)\n if (!frustum.containsPoint(tag.position)) return (tag.destroying = true)\n const v = tag.position.clone().sub(camera.position).setY(0)\n if (v.angleTo(tag.normal) > Math.PI / 2 - minRad && v.angleTo(tag.normal) < Math.PI / 2 + minRad) return (tag.destroying = true)\n })\n state.tags.forEach((tag) => {\n if (tag.destroying) {\n tag.app.update({\n contentZoom: 0.1 + camera.position.distanceTo(tag.position) / maxDistance,\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(tag.position) / maxDistance),\n destroying: tag.destroying,\n })\n } else {\n tag.app.update({\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(tag.position) / maxDistance),\n lineHeightZoom: 0.4 + ((camera.position.distanceTo(tag.position) - minDistance) / maxDistance) * 0.6,\n contentZoom: 0.1 + camera.position.distanceTo(tag.position) / maxDistance,\n })\n }\n })\n setTimeout(() => {\n state.tags.forEach((tag) => {\n if (tag.destroying) {\n tag.app.destroy()\n tag = null\n }\n })\n state.tags = state.tags.filter((tag) => !tag.destroying)\n updateOrigins()\n }, 1900)\n }\n\n const onModeChange = (mode): void => {\n if (mode !== Five.Mode.Panorama && !state.forbidden) {\n origins.update({ origins: [] })\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n state.forbidden = true\n }\n }\n\n const updateOrigins = (): void => {\n if (state.forbidden || !state.enabled) return\n const camera = five.camera\n const direction = camera.getWorldDirection(new THREE.Vector3())\n state.origins = state.tags.map((tag) => {\n const mouse = tag.position.clone().project(camera)\n const front = tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) < Math.PI / 2\n return {\n id: tag.id,\n front,\n left: ((mouse.x + 1) / 2) * 100,\n top: ((-mouse.y + 1) / 2) * 100,\n destroying: tag.destroying,\n }\n })\n origins.update({ origins: state.origins })\n }\n\n const updateTags = (): void => {\n if (state.forbidden || !state.enabled) return\n if (state.timeoutId) clearTimeout(state.timeoutId)\n state.timeoutId = setTimeout(() => {\n state.timeoutId = undefined\n const newTags = getNewTags()\n if (newTags.length) {\n state.tags = state.tags.concat(newTags)\n updateOrigins()\n }\n }, wait)\n }\n\n const getNewTags = (): Array<PanoSpatialTagPluginTagElement> => {\n const { clientWidth, clientHeight } = five.getElement()\n const newTags = []\n const camera = five.camera\n const frustum = new THREE.Frustum()\n const projScreenMatrix = new THREE.Matrix4()\n const direction = camera.getWorldDirection(new THREE.Vector3())\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n frustum.setFromProjectionMatrix(projScreenMatrix, camera.coordinateSystem)\n const frontTagLength = state.tags.filter((tag) => frustum.containsPoint(tag.position) && !tag.destroying).length\n\n const points: Array<PanoSpatialTagPluginPointElement> = state.points.reduce((result, point) => {\n if (state.tags.find((tag) => point.id === tag.id && !tag.destroying)) return result\n const distance = camera.position.clone().setY(centerY).distanceTo(point.position)\n if (distance < minDistance || distance > maxDistance) return result\n if (!frustum.containsPoint(point.position)) return result\n\n const v = point.position.clone().sub(camera.position).setY(0)\n\n if (v.angleTo(point.normal) > Math.PI / 2 - minRad && v.angleTo(point.normal) < Math.PI / 2 + minRad) return result\n\n const mouse = point.position.clone().project(camera)\n if (\n !state.tags.every((tag) => {\n if (tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) > Math.PI / 2) return true\n const _mouse = tag.position.clone().project(camera)\n return (\n Math.sqrt(Math.pow(((mouse.x - _mouse.x) / 2) * clientWidth, 2) + Math.pow(((mouse.y - _mouse.y) / 2) * clientHeight, 2)) >\n nearTolerance\n )\n })\n )\n return result\n\n const newPoint: PanoSpatialTagPluginPointElement = {\n id: point.id,\n position: point.position,\n normal: point.normal,\n replacement: point.replacement,\n weight: point.weight,\n distance,\n }\n\n let index: number\n for (let i = 0, l = result.length; i < l; i++) {\n const anotherPoint = result[i]\n if (newPoint.weight > anotherPoint.weight) {\n index = i\n break\n }\n if (newPoint.distance < anotherPoint.distance) {\n index = i\n break\n }\n }\n if (index !== undefined) result.splice(index, 0, newPoint)\n else result.push(newPoint)\n\n return result\n }, [])\n\n for (let i = 0, l = points.length; i < l; i++) {\n if (frontTagLength + newTags.length >= maxNumberOnScreen) break\n const point = points[i]\n if (newTags.find((tag) => point.id === tag.id)) continue\n\n const mouse = point.position.clone().project(camera)\n if (\n !state.tags.concat(newTags).every((tag) => {\n if (tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) > Math.PI / 2) return true\n const _mouse = tag.position.clone().project(camera)\n return (\n Math.sqrt(Math.pow(((mouse.x - _mouse.x) / 2) * clientWidth, 2) + Math.pow(((mouse.y - _mouse.y) / 2) * clientHeight, 2)) >\n nearTolerance\n )\n })\n )\n continue\n\n const raycaster = new THREE.Raycaster(\n camera.position.clone().setY(centerY),\n point.position.clone().sub(camera.position.clone().setY(centerY)).normalize(),\n 0,\n point.distance + RAY_TOLERANT_DISTANCE,\n )\n const [intersect] = state.intersectObjects\n ? raycaster.intersectObjects(state.intersectObjects, true)\n : five.model.loaded\n ? five.model.intersectRaycaster(raycaster)\n : raycaster.intersectObjects(five.model.children, true)\n if (!intersect) continue\n if (point.distance - intersect.distance < RAY_TOLERANT_DISTANCE) {\n const { position, normal, id, replacement } = point\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, position)\n const right = position.clone().sub(camera.position).cross(new THREE.Vector3(0, 1, 0)).setLength(MESH_SIZE)\n const square = [\n position.clone(),\n position.clone().add(right),\n position.clone().add(new THREE.Vector3(0, MESH_SIZE, 0)).add(right),\n position.clone().add(new THREE.Vector3(0, MESH_SIZE, 0)),\n ].map((v) => plane.projectPoint(v, new THREE.Vector3()))\n\n const { container, dispose } = css3DRender.create3DDomContainer(square) || {}\n const app = mountComponent(Tag, container, {\n id,\n content: state.render(state.template, replacement),\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(position) / maxDistance),\n lineHeightZoom: 0.4 + ((camera.position.distanceTo(position) - minDistance) / maxDistance) * 0.6,\n contentZoom: 0.1 + camera.position.distanceTo(position) / maxDistance,\n upsideDown: position.y > upsideHeight,\n folded: state.folded,\n events: state.events,\n hooks,\n dispose,\n blurImageUrl: BLUR_IMAGE_URL,\n })\n newTags.push({\n position,\n normal,\n id,\n app,\n })\n }\n }\n\n return newTags\n }\n\n /** 标签数据加载\n * @param data.points {Array} 标签数据\n * @param data.enabled {Boolean} 插件是否启用\n * @param data.folded {Boolean} 标签是否默认展开\n */\n const load = (data: PanoSpatialTagPluginData): void => {\n state.points = data.points.map((point) => {\n return {\n id: point.id,\n position: new THREE.Vector3().fromArray(point.position),\n normal: new THREE.Vector3().fromArray(point.normal),\n replacement: point.replacement ?? {},\n weight: point.weight ?? -1,\n }\n })\n if (data.render) state.render = data.render\n if (data.template) state.template = data.template\n if (data.events) state.events = data.events\n if (data.enabled === false) state.enabled = data.enabled\n if (data.folded === true) state.folded = data.folded\n }\n\n /** 设置射线碰撞检测objects\n *\n */\n const setIntersectObjects = (objects: Array<any>): void => {\n state.intersectObjects = objects\n updateTags()\n }\n\n /** 标签启用\n * 启用插件并重新计算展示标签\n */\n const enable = (): void => {\n state.enabled = true\n updateTags()\n }\n\n /** 插件禁用\n * 1. 禁用同时会清除已展示的标签\n * 2. 再次启用时会重新计算展示标签\n */\n const disable = (): void => {\n state.enabled = false\n origins.update({ origins: [] })\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n }\n\n /** 展开所有标签\n * 1. 展开所有收起的标签\n * 2. 新标签会默认展开\n */\n const unfoldAll = (): void => {\n state.folded = false\n state.tags.forEach((tag) => {\n tag.app.update({ folded: state.folded })\n })\n }\n\n /** 收起所有标签\n * 1. 收起所有展开的标签\n * 2. 新标签会默认收起\n */\n const foldAll = (): void => {\n state.folded = true\n state.tags.forEach((tag) => {\n tag.app.update({ folded: state.folded })\n })\n }\n\n /** 展开单个标签\n * @param id {Number | String} 标签ID\n */\n const unfold = (id: PanoSpatialTagPluginId): void => {\n state.tags.forEach((tag) => {\n if (tag.id === id) tag.app.update({ folded: false })\n })\n }\n\n /** 收起单个标签\n * @param id {Number | String} 标签ID\n */\n const fold = (id: PanoSpatialTagPluginId): void => {\n state.tags.forEach((tag) => {\n if (tag.id === id) tag.app.update({ folded: true })\n })\n }\n\n const onResize = (): void => {\n five.once('renderFrame', updateOrigins)\n }\n\n const onModelLoaded = (): void => {\n if (!wrapper) wrapper = five.getElement().parentElement\n if (wrapper) wrapper.appendChild(container)\n state.forbidden = false\n centerY = five.model.bounding.getCenter(new THREE.Vector3()).y\n updateTags()\n five.on('panoWillArrive', onPanoWillArrive)\n five.on('panoArrived', onPanoArrived)\n five.on('modeChange', onModeChange)\n five.on('cameraUpdate', onCameraUpdate)\n }\n\n const dispose = (): void => {\n blurImage = null\n css3DRender.dispose()\n\n origins.destroy()\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n\n five.off('modelLoaded', onModelLoaded)\n five.off('renderFrame', updateOrigins)\n five.off('panoWillArrive', onPanoWillArrive)\n five.off('panoArrived', onPanoArrived)\n five.off('modeChange', onModeChange)\n five.off('cameraUpdate', onCameraUpdate)\n five.off('dispose', dispose)\n window.removeEventListener('resize', onResize, false)\n }\n\n window.addEventListener('resize', onResize, false)\n\n if (five?.model?.loaded) onModelLoaded()\n else five.once('modelLoaded', onModelLoaded)\n\n five.on('dispose', dispose)\n\n return {\n load,\n setIntersectObjects,\n unfoldAll,\n foldAll,\n unfold,\n fold,\n enable,\n disable,\n hooks,\n dispose,\n }\n}\n\nexport default PanoSpatialTagPlugin\n"],"mappings":"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"}
1
+ {"version":3,"file":"pano-spatial-tag-gwN_WDLJ.js","names":["root","$.from_html","$.prop","$.comment","$.first_child","$.index","$.set_class","$.get","$.set_style","$.untrack","$.from_html","$.prop","$.mutable_source","$.get","$.child","$.sibling","$.set","$.set_class","PANO_SPATIAL_TAG_BLUR_IMAGE","template_effect","child","event","append","comment","onDestroy","from_html","set","afterUpdate","untrack","mutable_source","sibling","each","set_attribute","writable","push","onMount","bind_this","set_class","prop","init","next","set_style","first_child","pop","reset","mountComponent","index","html","get","THREE","currentTarget","root$1","Origins","$$props","origins","handleClick","id","fragment","node","i","classes","styles","origin","$$anchor","root","Tag","upsideDown","content","contentZoom","lineWidthZoom","lineHeightZoom","destroying","folded","dispose","events","hooks","blurImageUrl","contentWidth","contentHeight","contentDom","show","timeoutId","handleClickContent","eventsName","classNames","key","unsubscribe","str","currentId","date","div","div_1","div_2","div_3","div_4","$$value","pluginStyle","REGEX_STRING","ENCODE_HTML_RULES","TEMPLATE_MODES","stripSemi","render","Template","template","data","text","src","escapeFn","markup","c","matches","closing","line","pat","result","arr","firstPos","MESH_SIZE","RAY_TOLERANT_DISTANCE","BLUR_IMAGE_URL","PanoSpatialTagPlugin","wrapper","params","centerY","wait","maxNumberOnScreen","minRad","nearTolerance","upsideHeight","minDistance","maxDistance","css3DRender","CSS3DRenderPlugin","five","container","Subscribe","blurImage","state","onCameraUpdate","updateOrigins","userAction","updateTags","onPanoArrived","onPanoWillArrive","rotateRad","pose","camera","frustum","projScreenMatrix","distance","tag","v","onModeChange","mode","Five","direction","mouse","front","newTags","getNewTags","frontTagLength","points","point","_mouse","clientWidth","clientHeight","newPoint","l","anotherPoint","raycaster","intersect","plane","normal","position","right","square","app","replacement","load","setIntersectObjects","objects","enable","disable","unfoldAll","foldAll","unfold","fold","onResize","onModelLoaded"],"sources":["../../src/PanoSpatialTagPlugin/store.ts","../../src/PanoSpatialTagPlugin/Components/origins.svelte","../../src/PanoSpatialTagPlugin/Components/tag.svelte","../../src/PanoSpatialTagPlugin/style.ts","../../src/shared-utils/tinyEJSrender.ts","../../src/PanoSpatialTagPlugin/Plugin.ts"],"sourcesContent":["import { writable } from 'svelte/store'\n\nexport const currentTarget = writable(null)","<script lang=\"ts\">\n import { currentTarget } from '../store'\n import type { PanoSpatialTagPluginOriginElement, PanoSpatialTagPluginId } from '../typings'\n export let origins: Array<PanoSpatialTagPluginOriginElement>\n\n const handleClick = (id: PanoSpatialTagPluginId): void => {\n currentTarget.update((): string => `${id}-PanoSpatialTagPlugin-${Date.now()}`)\n }\n</script>\n\n{#each origins as origin}\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <i \n class:PanoSpatialTagPlugin__tag-origin={true}\n class:PanoSpatialTagPlugin__tag-origin-destroy={origin.destroying}\n style:top=\"{origin.top}%\"\n style:left=\"{origin.left}%\"\n style:visibility=\"{origin.front ? 'visible' : 'hidden'}\"\n on:click=\"{() => handleClick(origin.id)}\"\n />\n{/each}\n\n<style>\n .PanoSpatialTagPlugin__tag-origin {\n position: absolute;\n width: 0.5rem;\n height: 0.5rem;\n border-radius: 50%;\n background: #fff;\n box-shadow: 0 0 .6rem #fff;\n transform: translate(-50%, -50%) scale(1);\n transform-origin: center center;\n animation: PanoSpatialTagPlugin__tag-origin 1.2s forwards;\n pointer-events: auto;\n }\n\n .PanoSpatialTagPlugin__tag-origin:after {\n content: '';\n position: absolute;\n top: 50%;\n height: 50%;\n width: 2rem;\n height: 2rem;\n transform: translate(-50%, -50%);\n }\n\n .PanoSpatialTagPlugin__tag-origin-destroy {\n transform: translate(-50%, -50%) scale(0.6);\n animation: PanoSpatialTagPlugin__tag-origin-destroy 1.2s forwards .7s;\n }\n\n @keyframes PanoSpatialTagPlugin__tag-origin {\n 0% { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n 100% { transform: translate(-50%, -50%) scale(0.6); opacity: 1 }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-origin-destroy {\n 0% { transform: translate(-50%, -50%) scale(0.6); opacity: 1; }\n 10% { transform: translate(-50%, -50%) scale(1); opacity: 0.9; }\n 100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }\n }\n</style>\n","<script lang=\"ts\">\n import type { PanoSpatialTagPluginContentEvent } from '../typings'\n import { onMount, onDestroy, afterUpdate } from 'svelte'\n import { currentTarget } from '../store'\n export let id: number | string\n export let upsideDown: boolean\n export let content: string\n export let contentZoom: number\n export let lineWidthZoom: number\n export let lineHeightZoom: number\n export let destroying = false\n export let folded: boolean\n export let dispose: () => void\n export let events: PanoSpatialTagPluginContentEvent\n export let hooks\n export let blurImageUrl: string\n\n let contentWidth = 0\n let contentHeight = 0\n let contentDom: HTMLElement\n let show: boolean\n let timeoutId = setTimeout(() => {\n if (!folded) show = true\n timeoutId = undefined\n }, 100)\n\n const handleClickContent = (event) => {\n const eventsName = Object.keys(events)\n let node = event.target\n while (node) {\n const classNames = node.getAttribute('class')\n if (!classNames) {\n node = node.parentNode\n continue\n }\n if (classNames.includes('PanoSpatialTagPlugin__tag-content')) {\n node = null\n break\n }\n eventsName.forEach((key) => {\n if (classNames.includes(key)) events[key](id)\n })\n node = node.parentNode\n }\n }\n\n onMount(() => {\n hooks.emit('initTag', { id })\n })\n\n const unsubscribe = currentTarget.subscribe((str: string) => {\n if (str === null) return\n const [currentId, date] = str.split('-PanoSpatialTagPlugin-')\n if (id === currentId) {\n hooks.emit('clickOrigin', { id, show })\n if (!timeoutId) {\n show = folded\n folded = !folded\n timeoutId = setTimeout(() => {\n timeoutId = undefined\n }, 1500)\n }\n }\n })\n\n afterUpdate(() => {\n contentWidth = contentDom.offsetWidth\n contentHeight = contentDom.offsetHeight\n if (timeoutId) return\n show = !folded\n })\n\n onDestroy(() => {\n hooks.emit('destroyTag', { id })\n unsubscribe()\n dispose()\n })\n</script>\n\n<div\n class:PanoSpatialTagPlugin__tag-x={true}\n class:PanoSpatialTagPlugin__tag-upside-down={upsideDown}\n class:PanoSpatialTagPlugin__tag-show={show}\n class:PanoSpatialTagPlugin__tag-hide={show === false || destroying}\n id={'PanoSpatialTagPlugin__' + id}\n style=\"height: {20 * lineHeightZoom}rem\"\n>\n <div\n class=\"PanoSpatialTagPlugin__tag-shadow\"\n style=\"transform: translate({(contentWidth / 2) * contentZoom * 3}px, {(contentHeight / 2) *\n (upsideDown ? -1 : 1) *\n contentZoom *\n 3}px) scale({1 / contentZoom}); background-image: url('{blurImageUrl}');\"\n />\n <div class=\"PanoSpatialTagPlugin__tag-line\">\n <i class=\"PanoSpatialTagPlugin__tag-flagpole\" style=\"width: {lineWidthZoom}rem;\" />\n <i class=\"PanoSpatialTagPlugin__tag-line1\" />\n <i class=\"PanoSpatialTagPlugin__tag-line2\" />\n </div>\n <div class=\"PanoSpatialTagPlugin__tag-animate\" style=\"transform: scale({contentZoom * 3})\">\n <!-- svelte-ignore a11y-click-events-have-key-events -->\n <div class=\"PanoSpatialTagPlugin__tag-content\" on:click={handleClickContent} bind:this={contentDom}>\n {@html content}\n </div>\n </div>\n</div>\n\n<style>\n .PanoSpatialTagPlugin__tag-x {\n position: absolute;\n top: 0;\n left: 0;\n display: block;\n white-space: nowrap;\n box-sizing: border-box;\n width: 25rem;\n height: 14rem;\n color: #fff;\n transform: translate(0, -100%);\n transition: height 0.5s linear;\n }\n\n .PanoSpatialTagPlugin__tag-shadow {\n content: '';\n position: absolute;\n width: 30rem;\n height: 30rem;\n top: -15rem;\n left: -15rem;\n z-index: -1;\n opacity: 0;\n transition: opacity 0.8s 0.6s;\n background-size: 30rem 30rem;\n }\n\n .PanoSpatialTagPlugin__tag-line {\n position: absolute;\n left: -1rem;\n width: 2rem;\n height: 100%;\n overflow: hidden;\n }\n\n .PanoSpatialTagPlugin__tag-flagpole {\n position: absolute;\n top: 0;\n left: 1rem;\n height: calc(100% - 1.5rem);\n width: 0.15rem;\n background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.1));\n box-shadow: 0 0.1rem 0.5rem rgba(0, 0, 0, 0.2);\n opacity: 0;\n transform: translate(-50%, 60%) scaleY(0);\n transition: transform 0.4s cubic-bezier(0.44, 0.44, 0.74, 0.98), opacity 0.4s cubic-bezier(0.44, 0.44, 0.74, 0.98), width 0.5s linear,\n height 0.5s linear;\n transform-origin: center bottom;\n }\n\n .PanoSpatialTagPlugin__tag-line1 {\n position: absolute;\n top: 0;\n left: 0.3rem;\n height: 1.8rem;\n width: 0.1rem;\n background: #fff;\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n transform-origin: center top;\n }\n\n .PanoSpatialTagPlugin__tag-line2 {\n position: absolute;\n top: 0;\n left: 0.5rem;\n height: 1.8rem;\n width: 0.1rem;\n background: #fff;\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n transform-origin: center top;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-line1 {\n animation: PanoSpatialTagPlugin__tag-line1 linear 0.5s forwards 0.45s;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-line2 {\n animation: PanoSpatialTagPlugin__tag-line2 linear 0.5s forwards 0.65s;\n }\n\n .PanoSpatialTagPlugin__tag-x.PanoSpatialTagPlugin__tag-upside-down {\n transform: translate(0, 0);\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-line {\n transform: scaleY(-1);\n }\n\n .PanoSpatialTagPlugin__tag-animate {\n position: relative;\n height: 100%;\n overflow: hidden;\n transform-origin: left top;\n transition: transform 0.5s linear;\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-animate {\n transform-origin: left bottom;\n }\n\n .PanoSpatialTagPlugin__tag-content {\n position: absolute;\n display: inline-block;\n transform: translate(-100%, 0);\n transition: transform 0.9s cubic-bezier(0, 0.65, 0.16, 1.08) 0.6s;\n padding-left: 0.5rem;\n font-size: 1rem;\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-content {\n bottom: 0;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-flagpole {\n opacity: 1;\n transform: translate(-50%, 0) scaleY(1);\n }\n\n .PanoSpatialTagPlugin__tag-upside-down .PanoSpatialTagPlugin__tag-shadow {\n top: unset;\n bottom: -15rem;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-shadow {\n opacity: 0.32;\n }\n\n .PanoSpatialTagPlugin__tag-show .PanoSpatialTagPlugin__tag-content {\n transform: translate(0, 0);\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-flagpole {\n opacity: 0;\n transform: translate(-50%, 60%) scaleY(0);\n transition: transform 0.5s 0.55s, opacity 0.4s 0.55s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-shadow {\n opacity: 0;\n transition: opacity 0.8s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-content {\n transform: translate(-100%, 0);\n transition: transform 0.6s cubic-bezier(0.53, 0.06, 0.88, 0.59);\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-content * {\n pointer-events: none;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-line1 {\n opacity: 0.5;\n transform: translate(-50%, 10%) scaleY(0);\n animation: PanoSpatialTagPlugin__tag-line1-hide linear 0.28s forwards 0.3s;\n }\n\n .PanoSpatialTagPlugin__tag-hide .PanoSpatialTagPlugin__tag-line2 {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n animation: PanoSpatialTagPlugin__tag-line2-hide linear 0.28s forwards 0.45s;\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line1 {\n 0% {\n opacity: 0;\n transform: translate(-50%, 250%) scaleY(1);\n }\n 50% {\n opacity: 0.5;\n transform: translate(-50%, 135%) scaleY(1);\n }\n 100% {\n opacity: 0.5;\n transform: translate(-50%, 20%) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line2 {\n 0% {\n opacity: 0;\n transform: translate(-50%, 250%) scaleY(1);\n }\n 50% {\n opacity: 0.5;\n transform: translate(-50%, 125%) scaleY(1);\n }\n 100% {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line1-hide {\n 0% {\n opacity: 0.5;\n transform: translate(-50%, 10%) scaleY(0);\n }\n 50% {\n opacity: 0.2;\n transform: translate(-50%, 105%) scaleY(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n }\n }\n\n @keyframes PanoSpatialTagPlugin__tag-line2-hide {\n 0% {\n opacity: 0.5;\n transform: translate(-50%, 0) scaleY(0);\n }\n 50% {\n opacity: 0.2;\n transform: translate(-50%, 100%) scaleY(1);\n }\n 100% {\n opacity: 0;\n transform: translate(-50%, 200%) scaleY(0);\n }\n }\n</style>\n","export const pluginStyle: Partial<CSSStyleDeclaration> = {\n position: 'absolute',\n top: '0px',\n left: '0px',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n}","const DEFAULT_OPEN_DELIMITER = '<'\nconst DEFAULT_CLOSE_DELIMITER = '>'\nconst DEFAULT_DELIMITER = '%'\nconst DEFAULT_LOCALS_NAME = 'locals'\nconst REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'\nconst ENCODE_HTML_RULES = {\n '&': '&amp',\n '<': '&lt',\n '>': '&gt',\n '\"': '&#34',\n \"'\": '&#39'\n}\nconst TEMPLATE_MODES = {\n EVAL: 'eval',\n ESCAPED: 'escaped',\n RAW: 'raw',\n COMMENT: 'comment',\n LITERAL: 'literal',\n}\n\ninterface RenderData {\n\t[key: string]: string\n}\n\nfunction stripSemi (str: string): string {\n return str.replace(/;(\\s*$)/, '$1')\n}\n\nexport default function render (template: string, data: RenderData): string {\n\tconst templ = new Template(template)\n return templ.compileFunction()(data)\n}\n\nclass Template {\n\tprivate templateText: string\n\tprivate mode = null\n\tprivate truncate = false\n\tprivate currentLine = 1\n\tprivate source = ''\n\tprivate regex = new RegExp(REGEX_STRING)\n\n\tconstructor (text) {\n\t this.templateText = text\n\t}\n\n\tpublic compileFunction () {\n let src\n const prepended = \n \t' var __output = \"\";\\n' +\n ' function __append(s) { if (s !== undefined && s !== null) __output += s }\\n' +\n \t' with (' + DEFAULT_LOCALS_NAME + ' || {}) {' + '\\n'\n const appended = ' }' + '\\n return __output;' + '\\n'\n const escapeFn = function (markup) {\n\t\t return markup == undefined\n\t\t ? ''\n\t\t : String(markup)\n\t\t .replace(/[&<>'\"]/g, function (c) {\n\t\t\t return ENCODE_HTML_RULES[c] || c\n\t\t\t})\n\t\t}\n\n this._generateSource()\n this.source = prepended + this.source + appended\n\n src = this.source\n src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\\n' + src\n\n return new Function(DEFAULT_LOCALS_NAME + ', escapeFn', src)\n }\n\n private _generateSource () {\n this.templateText =\n this.templateText.replace(/[ \\t]*<%_/gm, '<%_').replace(/_%>[ \\t]*/gm, '_%>')\n\n const matches = this._parseTemplateText()\n const d = DEFAULT_DELIMITER\n const o = DEFAULT_OPEN_DELIMITER\n const c = DEFAULT_CLOSE_DELIMITER\n\n if (matches && matches.length) {\n matches.forEach((line, index) => {\n let closing\n if ( line.indexOf(o + d) === 0\n && line.indexOf(o + d + d) !== 0) {\n closing = matches[index + 2]\n if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {\n throw new Error('Could not find matching close tag for \"' + line + '\".')\n }\n }\n this._scanLine(line)\n })\n }\n }\n\n private _parseTemplateText () {\n let str = this.templateText\n const pat = this.regex\n let result = pat.exec(str)\n const arr = []\n let firstPos\n\n while (result) {\n firstPos = result.index\n\n if (firstPos !== 0) {\n arr.push(str.substring(0, firstPos))\n str = str.slice(firstPos)\n }\n\n arr.push(result[0])\n str = str.slice(result[0].length)\n result = pat.exec(str)\n }\n\n if (str) {\n arr.push(str)\n }\n\n return arr\n }\n\n private _addOutput (line) {\n if (this.truncate) {\n line = line.replace(/^(?:\\r\\n|\\r|\\n)/, '')\n this.truncate = false\n }\n if (!line) return line\n\n line = line.replace(/\\\\/g, '\\\\\\\\')\n line = line.replace(/\\n/g, '\\\\n')\n line = line.replace(/\\r/g, '\\\\r')\n line = line.replace(/\"/g, '\\\\\"')\n this.source += ' ; __append(\"' + line + '\")' + '\\n'\n }\n\n private _scanLine (line) {\n const d = DEFAULT_DELIMITER\n const o = DEFAULT_OPEN_DELIMITER\n const c = DEFAULT_CLOSE_DELIMITER\n const newLineCount = line.split('\\n').length - 1\n\n switch (line) {\n\t case o + d:\n\t case o + d + '_':\n\t this.mode = TEMPLATE_MODES.EVAL\n\t break\n\t case o + d + '=':\n\t this.mode = TEMPLATE_MODES.ESCAPED\n\t break\n\t case o + d + '-':\n\t this.mode = TEMPLATE_MODES.RAW\n\t break\n\t case o + d + '#':\n\t this.mode = TEMPLATE_MODES.COMMENT\n\t break\n\t case o + d + d:\n\t this.mode = TEMPLATE_MODES.LITERAL\n\t this.source += ' ; __append(\"' + line.replace(o + d + d, o + d) + '\")' + '\\n'\n\t break\n\t case d + d + c:\n\t this.mode = TEMPLATE_MODES.LITERAL\n\t this.source += ' ; __append(\"' + line.replace(d + d + c, d + c) + '\")' + '\\n'\n\t break\n\t case d + c:\n\t case '-' + d + c:\n\t case '_' + d + c:\n\t if (this.mode == TEMPLATE_MODES.LITERAL) {\n\t this._addOutput(line)\n\t }\n\n\t this.mode = null\n\t this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0\n\t break\n\t default:\n\t if (this.mode) {\n\t switch (this.mode) {\n\t case TEMPLATE_MODES.EVAL:\n\t case TEMPLATE_MODES.ESCAPED:\n\t case TEMPLATE_MODES.RAW:\n\t if (line.lastIndexOf('//') > line.lastIndexOf('\\n')) {\n\t line += '\\n'\n\t }\n\t }\n\t switch (this.mode) {\n\t case TEMPLATE_MODES.EVAL:\n\t this.source += ' ; ' + line + '\\n'\n\t break\n\t case TEMPLATE_MODES.ESCAPED:\n\t this.source += ' ; __append(escapeFn(' + stripSemi(line) + '))' + '\\n'\n\t break\n\t case TEMPLATE_MODES.RAW:\n\t this.source += ' ; __append(' + stripSemi(line) + ')' + '\\n'\n\t break\n\t case TEMPLATE_MODES.COMMENT:\n\t break\n\t case TEMPLATE_MODES.LITERAL:\n\t this._addOutput(line)\n\t break\n\t }\n\t }\n\t else {\n\t this._addOutput(line)\n\t }\n }\n }\n}\n","import * as THREE from 'three/webgpu'\nimport type { FivePlugin } from '@realsee/five-webgpu'\nimport { Five, Subscribe } from '@realsee/five-webgpu'\nimport CSS3DRenderPlugin from '../CSS3DRenderPlugin'\nimport Origins from './Components/origins.svelte'\nimport Tag from './Components/tag.svelte'\nimport { pluginStyle } from './style'\nimport render from '../shared-utils/tinyEJSrender'\nimport { PANO_SPATIAL_TAG_BLUR_IMAGE } from '../shared-utils'\n\nimport { mountComponent, type MountedComponent } from '../shared-utils/svelte/component.svelte'\nimport type {\n PanoSpatialTagPluginId,\n PanoSpatialTagPluginDataElement,\n PanoSpatialTagPluginTagElement,\n PanoSpatialTagPluginOriginElement,\n PanoSpatialTagPluginPointElement,\n PanoSpatialTagPluginContentReplacement,\n PanoSpatialTagPluginContentEvent,\n} from './typings'\n\nexport interface PanoSpatialTagPluginData {\n // 插件load数据\n folded?: boolean // 标签初始是否收起\n enabled?: boolean // 插件初始是否启用\n points: Array<PanoSpatialTagPluginDataElement>\n template: string // dom模板\n events?: PanoSpatialTagPluginContentEvent\n render?: (template: string, replacement: PanoSpatialTagPluginContentReplacement) => string // 模板数据映射函数\n}\n\nexport interface PanoSpatialTagPluginParameterType {\n container?: Element // 标签容器\n wait?: number // debounce延迟\n maxNumberOnScreen?: number // 屏幕内标签最大展示数量\n minRad?: number // 视角和标签平面最小夹角\n nearTolerance?: number // 标签映射到屏幕之间最小间距\n upsideHeight?: number // 标签反向高度\n minDistance?: number // 标签最小距离,单位米\n maxDistance?: number // 标签最小距离,单位米\n // foldPercent?: number // 标签折叠屏幕百分比\n}\n\nexport interface PanoSpatialTagPluginExportType {\n load: (data: PanoSpatialTagPluginData) => void\n unfoldAll: () => void\n foldAll: () => void\n unfold: (id: PanoSpatialTagPluginId) => void\n fold: (id: PanoSpatialTagPluginId) => void\n enable: () => void\n disable: () => void\n dispose: () => void\n}\n\ninterface PanoSpatialTagPluginState {\n timeoutId?: NodeJS.Timeout\n points: Array<PanoSpatialTagPluginPointElement>\n origins: Array<PanoSpatialTagPluginOriginElement>\n tags: Array<PanoSpatialTagPluginTagElement>\n render: (template: string, replacement: PanoSpatialTagPluginContentReplacement) => string\n events: PanoSpatialTagPluginContentEvent\n intersectObjects?: Array<any> // 碰撞检测objects\n template: string\n folded: boolean // 标签初始收起展开状态\n enabled: boolean // 用户控制启用禁止状态\n forbidden: boolean // 插件控制启用禁止状态\n}\n\nconst MESH_SIZE = 0.001\nconst RAY_TOLERANT_DISTANCE = 0.01\nconst BLUR_IMAGE_URL = PANO_SPATIAL_TAG_BLUR_IMAGE\n\n/**\n * 空间游走标签插件\n */\nexport const PanoSpatialTagPlugin: FivePlugin<PanoSpatialTagPluginParameterType, PanoSpatialTagPluginExportType> = (five: Five, params) => {\n let wrapper = params?.container\n let centerY = 1.4\n const wait = params?.wait ?? 200\n const maxNumberOnScreen = params?.maxNumberOnScreen ?? 3\n const minRad = params?.minRad ?? Math.PI / 4\n const nearTolerance = params?.nearTolerance ?? 100\n const upsideHeight = params?.upsideHeight ?? 1.6\n const minDistance = params?.minDistance ?? 1.2\n const maxDistance = params?.maxDistance ?? 3.5\n // const foldPercent = params?.foldPercent ?? 20\n\n const css3DRender = CSS3DRenderPlugin(five)\n const container = document.createElement('div')\n container.classList.add('PanoSpatialTagPlugin')\n Object.assign(container.style, pluginStyle)\n\n const hooks = new Subscribe()\n\n let blurImage = new Image()\n blurImage.src = BLUR_IMAGE_URL\n\n const state: PanoSpatialTagPluginState = {\n points: [],\n origins: [],\n tags: [],\n template: '',\n events: {},\n render,\n folded: false,\n enabled: true,\n forbidden: true,\n }\n\n const origins = mountComponent(Origins, container, { origins: state.origins })\n\n const onCameraUpdate = (pose, userAction): void => {\n updateOrigins()\n if (userAction) {\n updateTags()\n // state.tags.forEach(tag => {\n // const mouse = tag.position.clone().project(five.camera)\n // const top = ( - mouse.y + 1 ) / 2 * 100\n // })\n }\n }\n\n const onPanoArrived = () => {\n if (state.forbidden) {\n state.forbidden = false\n updateTags()\n }\n }\n\n const onPanoWillArrive = (pano, pose): void => {\n if (state.tags.length === 0) return\n const rotateRad = pose.longitude - five.state.longitude\n const camera = five.camera.clone()\n camera.position.copy(pose.offset)\n camera.rotateOnWorldAxis(new THREE.Vector3(0, 1, 0), rotateRad)\n camera.updateProjectionMatrix()\n camera.updateMatrixWorld(true)\n const frustum = new THREE.Frustum()\n const projScreenMatrix = new THREE.Matrix4()\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n frustum.setFromProjectionMatrix(projScreenMatrix, camera.coordinateSystem)\n\n state.tags.forEach((tag) => {\n const distance = camera.position.clone().setY(centerY).distanceTo(tag.position)\n if (distance < minDistance || distance > maxDistance) return (tag.destroying = true)\n if (!frustum.containsPoint(tag.position)) return (tag.destroying = true)\n const v = tag.position.clone().sub(camera.position).setY(0)\n if (v.angleTo(tag.normal) > Math.PI / 2 - minRad && v.angleTo(tag.normal) < Math.PI / 2 + minRad) return (tag.destroying = true)\n })\n state.tags.forEach((tag) => {\n if (tag.destroying) {\n tag.app.update({\n contentZoom: 0.1 + camera.position.distanceTo(tag.position) / maxDistance,\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(tag.position) / maxDistance),\n destroying: tag.destroying,\n })\n } else {\n tag.app.update({\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(tag.position) / maxDistance),\n lineHeightZoom: 0.4 + ((camera.position.distanceTo(tag.position) - minDistance) / maxDistance) * 0.6,\n contentZoom: 0.1 + camera.position.distanceTo(tag.position) / maxDistance,\n })\n }\n })\n setTimeout(() => {\n state.tags.forEach((tag) => {\n if (tag.destroying) {\n tag.app.destroy()\n tag = null\n }\n })\n state.tags = state.tags.filter((tag) => !tag.destroying)\n updateOrigins()\n }, 1900)\n }\n\n const onModeChange = (mode): void => {\n if (mode !== Five.Mode.Panorama && !state.forbidden) {\n origins.update({ origins: [] })\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n state.forbidden = true\n }\n }\n\n const updateOrigins = (): void => {\n if (state.forbidden || !state.enabled) return\n const camera = five.camera\n const direction = camera.getWorldDirection(new THREE.Vector3())\n state.origins = state.tags.map((tag) => {\n const mouse = tag.position.clone().project(camera)\n const front = tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) < Math.PI / 2\n return {\n id: tag.id,\n front,\n left: ((mouse.x + 1) / 2) * 100,\n top: ((-mouse.y + 1) / 2) * 100,\n destroying: tag.destroying,\n }\n })\n origins.update({ origins: state.origins })\n }\n\n const updateTags = (): void => {\n if (state.forbidden || !state.enabled) return\n if (state.timeoutId) clearTimeout(state.timeoutId)\n state.timeoutId = setTimeout(() => {\n state.timeoutId = undefined\n const newTags = getNewTags()\n if (newTags.length) {\n state.tags = state.tags.concat(newTags)\n updateOrigins()\n }\n }, wait)\n }\n\n const getNewTags = (): Array<PanoSpatialTagPluginTagElement> => {\n const { clientWidth, clientHeight } = five.getElement()\n const newTags = []\n const camera = five.camera\n const frustum = new THREE.Frustum()\n const projScreenMatrix = new THREE.Matrix4()\n const direction = camera.getWorldDirection(new THREE.Vector3())\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)\n frustum.setFromProjectionMatrix(projScreenMatrix, camera.coordinateSystem)\n const frontTagLength = state.tags.filter((tag) => frustum.containsPoint(tag.position) && !tag.destroying).length\n\n const points: Array<PanoSpatialTagPluginPointElement> = state.points.reduce((result, point) => {\n if (state.tags.find((tag) => point.id === tag.id && !tag.destroying)) return result\n const distance = camera.position.clone().setY(centerY).distanceTo(point.position)\n if (distance < minDistance || distance > maxDistance) return result\n if (!frustum.containsPoint(point.position)) return result\n\n const v = point.position.clone().sub(camera.position).setY(0)\n\n if (v.angleTo(point.normal) > Math.PI / 2 - minRad && v.angleTo(point.normal) < Math.PI / 2 + minRad) return result\n\n const mouse = point.position.clone().project(camera)\n if (\n !state.tags.every((tag) => {\n if (tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) > Math.PI / 2) return true\n const _mouse = tag.position.clone().project(camera)\n return (\n Math.sqrt(Math.pow(((mouse.x - _mouse.x) / 2) * clientWidth, 2) + Math.pow(((mouse.y - _mouse.y) / 2) * clientHeight, 2)) >\n nearTolerance\n )\n })\n )\n return result\n\n const newPoint: PanoSpatialTagPluginPointElement = {\n id: point.id,\n position: point.position,\n normal: point.normal,\n replacement: point.replacement,\n weight: point.weight,\n distance,\n }\n\n let index: number\n for (let i = 0, l = result.length; i < l; i++) {\n const anotherPoint = result[i]\n if (newPoint.weight > anotherPoint.weight) {\n index = i\n break\n }\n if (newPoint.distance < anotherPoint.distance) {\n index = i\n break\n }\n }\n if (index !== undefined) result.splice(index, 0, newPoint)\n else result.push(newPoint)\n\n return result\n }, [])\n\n for (let i = 0, l = points.length; i < l; i++) {\n if (frontTagLength + newTags.length >= maxNumberOnScreen) break\n const point = points[i]\n if (newTags.find((tag) => point.id === tag.id)) continue\n\n const mouse = point.position.clone().project(camera)\n if (\n !state.tags.concat(newTags).every((tag) => {\n if (tag.position.clone().sub(camera.position).setY(0).angleTo(direction.setY(0)) > Math.PI / 2) return true\n const _mouse = tag.position.clone().project(camera)\n return (\n Math.sqrt(Math.pow(((mouse.x - _mouse.x) / 2) * clientWidth, 2) + Math.pow(((mouse.y - _mouse.y) / 2) * clientHeight, 2)) >\n nearTolerance\n )\n })\n )\n continue\n\n const raycaster = new THREE.Raycaster(\n camera.position.clone().setY(centerY),\n point.position.clone().sub(camera.position.clone().setY(centerY)).normalize(),\n 0,\n point.distance + RAY_TOLERANT_DISTANCE,\n )\n const [intersect] = state.intersectObjects\n ? raycaster.intersectObjects(state.intersectObjects, true)\n : five.model.loaded\n ? five.model.intersectRaycaster(raycaster)\n : raycaster.intersectObjects(five.model.children, true)\n if (!intersect) continue\n if (point.distance - intersect.distance < RAY_TOLERANT_DISTANCE) {\n const { position, normal, id, replacement } = point\n const plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, position)\n const right = position.clone().sub(camera.position).cross(new THREE.Vector3(0, 1, 0)).setLength(MESH_SIZE)\n const square = [\n position.clone(),\n position.clone().add(right),\n position.clone().add(new THREE.Vector3(0, MESH_SIZE, 0)).add(right),\n position.clone().add(new THREE.Vector3(0, MESH_SIZE, 0)),\n ].map((v) => plane.projectPoint(v, new THREE.Vector3()))\n\n const { container, dispose } = css3DRender.create3DDomContainer(square) || {}\n const app = mountComponent(Tag, container, {\n id,\n content: state.render(state.template, replacement),\n lineWidthZoom: 0.38 * (0.01 + camera.position.distanceTo(position) / maxDistance),\n lineHeightZoom: 0.4 + ((camera.position.distanceTo(position) - minDistance) / maxDistance) * 0.6,\n contentZoom: 0.1 + camera.position.distanceTo(position) / maxDistance,\n upsideDown: position.y > upsideHeight,\n folded: state.folded,\n events: state.events,\n hooks,\n dispose,\n blurImageUrl: BLUR_IMAGE_URL,\n })\n newTags.push({\n position,\n normal,\n id,\n app,\n })\n }\n }\n\n return newTags\n }\n\n /** 标签数据加载\n * @param data.points {Array} 标签数据\n * @param data.enabled {Boolean} 插件是否启用\n * @param data.folded {Boolean} 标签是否默认展开\n */\n const load = (data: PanoSpatialTagPluginData): void => {\n state.points = data.points.map((point) => {\n return {\n id: point.id,\n position: new THREE.Vector3().fromArray(point.position),\n normal: new THREE.Vector3().fromArray(point.normal),\n replacement: point.replacement ?? {},\n weight: point.weight ?? -1,\n }\n })\n if (data.render) state.render = data.render\n if (data.template) state.template = data.template\n if (data.events) state.events = data.events\n if (data.enabled === false) state.enabled = data.enabled\n if (data.folded === true) state.folded = data.folded\n }\n\n /** 设置射线碰撞检测objects\n *\n */\n const setIntersectObjects = (objects: Array<any>): void => {\n state.intersectObjects = objects\n updateTags()\n }\n\n /** 标签启用\n * 启用插件并重新计算展示标签\n */\n const enable = (): void => {\n state.enabled = true\n updateTags()\n }\n\n /** 插件禁用\n * 1. 禁用同时会清除已展示的标签\n * 2. 再次启用时会重新计算展示标签\n */\n const disable = (): void => {\n state.enabled = false\n origins.update({ origins: [] })\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n }\n\n /** 展开所有标签\n * 1. 展开所有收起的标签\n * 2. 新标签会默认展开\n */\n const unfoldAll = (): void => {\n state.folded = false\n state.tags.forEach((tag) => {\n tag.app.update({ folded: state.folded })\n })\n }\n\n /** 收起所有标签\n * 1. 收起所有展开的标签\n * 2. 新标签会默认收起\n */\n const foldAll = (): void => {\n state.folded = true\n state.tags.forEach((tag) => {\n tag.app.update({ folded: state.folded })\n })\n }\n\n /** 展开单个标签\n * @param id {Number | String} 标签ID\n */\n const unfold = (id: PanoSpatialTagPluginId): void => {\n state.tags.forEach((tag) => {\n if (tag.id === id) tag.app.update({ folded: false })\n })\n }\n\n /** 收起单个标签\n * @param id {Number | String} 标签ID\n */\n const fold = (id: PanoSpatialTagPluginId): void => {\n state.tags.forEach((tag) => {\n if (tag.id === id) tag.app.update({ folded: true })\n })\n }\n\n const onResize = (): void => {\n five.once('renderFrame', updateOrigins)\n }\n\n const onModelLoaded = (): void => {\n if (!wrapper) wrapper = five.getElement().parentElement\n if (wrapper) wrapper.appendChild(container)\n state.forbidden = false\n centerY = five.model.bounding.getCenter(new THREE.Vector3()).y\n updateTags()\n five.on('panoWillArrive', onPanoWillArrive)\n five.on('panoArrived', onPanoArrived)\n five.on('modeChange', onModeChange)\n five.on('cameraUpdate', onCameraUpdate)\n }\n\n const dispose = (): void => {\n blurImage = null\n css3DRender.dispose()\n\n origins.destroy()\n state.tags.forEach((tag) => {\n tag.app.destroy()\n tag = null\n })\n state.origins = []\n state.tags = []\n\n five.off('modelLoaded', onModelLoaded)\n five.off('renderFrame', updateOrigins)\n five.off('panoWillArrive', onPanoWillArrive)\n five.off('panoArrived', onPanoArrived)\n five.off('modeChange', onModeChange)\n five.off('cameraUpdate', onCameraUpdate)\n five.off('dispose', dispose)\n window.removeEventListener('resize', onResize, false)\n }\n\n window.addEventListener('resize', onResize, false)\n\n if (five?.model?.loaded) onModelLoaded()\n else five.once('modelLoaded', onModelLoaded)\n\n five.on('dispose', dispose)\n\n return {\n load,\n setIntersectObjects,\n unfoldAll,\n foldAll,\n unfold,\n fold,\n enable,\n disable,\n hooks,\n dispose,\n }\n}\n\nexport default PanoSpatialTagPlugin\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { t as e } from "./controller-Do-09Spx.js";
1
+ import { t as e } from "./controller-B-zFQPgF.js";
2
2
  //#region src/PanoTagPlugin/index.ts
3
3
  var t = (t, n) => new e(t, n);
4
4
  //#endregion
5
5
  export { t };
6
6
 
7
- //# sourceMappingURL=pano-tag-DeWr38_M.js.map
7
+ //# sourceMappingURL=pano-tag-mnA3Y7eC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pano-tag-DeWr38_M.js","names":["PanoTagPluginController","PanoTagPlugin","five","params"],"sources":["../../src/PanoTagPlugin/index.ts"],"sourcesContent":["import type { Five } from '@realsee/five-webgpu'\nimport PanoTagPluginController from './controller'\nexport { pluginFlag, PanoTagPluginController } from './controller'\nexport { defaultGlobalConfig } from './typings'\nexport type { ContentTypeMap, TagContentType, TagHooks, State, TemporaryState, TagClickParams, PluginEventMap, TagEvents, TagCacheInterface, MediaStore, PointTagInstance, Tags, Tag, TagId, ArrayPosition, Position, PanoIndex, WorkCode, ModelId, MinMax, StickType, BoxPosition, BoxTag, PolygonPosition, PolygonTag, MaskPosition, MaskTag, TagIconAnimationConfig, TagIconUrl, TagStyle, TagGLTFObject, ElementRenderer, TagRendererMap, TagContentTypeMapping, TagObjectGroup, TagGLTFObjectGroup, ImagePlaneGroup, AudioAppearance, ContentTypeConfigKeySplit, ContentTypeConfigKey, PickTagContentTypeInContentTypeConfigKey, TagConfigByKey, Point2DTag, Point3DTag, PlaneTag, TagState, MediaData, ObjectFit, ContentTypeMapInterface, TagPlacement, TagConfig, TagInstance } from './typings'\n\nexport type PanoTagPluginExportInterface = InstanceType<typeof PanoTagPluginController>\nexport type PanoTagPluginParamsInterface = ConstructorParameters<typeof PanoTagPluginController>[1]\n\nexport const PanoTagPlugin = (five: Five, params?: PanoTagPluginParamsInterface) => new PanoTagPluginController(five, params)\n\nexport default PanoTagPlugin\n"],"mappings":";;AASA,IAAaC,KAAiB,GAAY,MAA0C,IAAID,EAAwBE,GAAMC,CAAM"}
1
+ {"version":3,"file":"pano-tag-mnA3Y7eC.js","names":["PanoTagPluginController","PanoTagPlugin","five","params"],"sources":["../../src/PanoTagPlugin/index.ts"],"sourcesContent":["import type { Five } from '@realsee/five-webgpu'\nimport PanoTagPluginController from './controller'\nexport { pluginFlag, PanoTagPluginController } from './controller'\nexport { defaultGlobalConfig } from './typings'\nexport type { ContentTypeMap, TagContentType, TagHooks, State, TemporaryState, TagClickParams, PluginEventMap, TagEvents, TagCacheInterface, MediaStore, PointTagInstance, Tags, Tag, TagId, ArrayPosition, Position, PanoIndex, WorkCode, ModelId, MinMax, StickType, BoxPosition, BoxTag, PolygonPosition, PolygonTag, MaskPosition, MaskTag, TagIconAnimationConfig, TagIconUrl, TagStyle, TagGLTFObject, ElementRenderer, TagRendererMap, TagContentTypeMapping, TagObjectGroup, TagGLTFObjectGroup, ImagePlaneGroup, AudioAppearance, ContentTypeConfigKeySplit, ContentTypeConfigKey, PickTagContentTypeInContentTypeConfigKey, TagConfigByKey, Point2DTag, Point3DTag, PlaneTag, TagState, MediaData, ObjectFit, ContentTypeMapInterface, TagPlacement, TagConfig, TagInstance } from './typings'\n\nexport type PanoTagPluginExportInterface = InstanceType<typeof PanoTagPluginController>\nexport type PanoTagPluginParamsInterface = ConstructorParameters<typeof PanoTagPluginController>[1]\n\nexport const PanoTagPlugin = (five: Five, params?: PanoTagPluginParamsInterface) => new PanoTagPluginController(five, params)\n\nexport default PanoTagPlugin\n"],"mappings":";;AASA,IAAaC,KAAiB,GAAY,MAA0C,IAAID,EAAwBE,GAAMC,CAAM"}
@@ -1,7 +1,7 @@
1
1
  import { n as e } from "./rolldown-runtime-B0aSnxlc.js";
2
2
  import { i as t } from "./animationFrame-CacKXN8l.js";
3
3
  import { t as n } from "./animation-D9rPUNWJ.js";
4
- import { t as r } from "./BasePlugin-Br1gjzFy.js";
4
+ import { t as r } from "./BasePlugin-DykvYZVy.js";
5
5
  import { t as i } from "./loadVideoTexture-CWoiMWRg.js";
6
6
  import * as a from "three/webgpu";
7
7
  import { Mesh as o, MeshBasicNodeMaterial as s, Quaternion as c, SphereGeometry as l, Vector3 as u } from "three/webgpu";
@@ -375,4 +375,4 @@ var f = class {
375
375
  //#endregion
376
376
  export { m as n, h as t };
377
377
 
378
- //# sourceMappingURL=pano-video-CTlwzLiU.js.map
378
+ //# sourceMappingURL=pano-video-CSb6bzy-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pano-video-CTlwzLiU.js","names":["BasePlugin.Controller","__exportAll","requestAnimationFrameInterval","animate","Controller","createVideoTexture","THREE","directionToLongitudeAndLatitude","PI_2","longitude","direction","latitude","VideoMeshController","five","params","video","videoTexture","size","sourceUv","wrapWidth","wrappedU","videoUv","fadeX","fadeY","insideX","insideY","material","MeshBasicNodeMaterial","geometry","SphereGeometry","videoMesh","Mesh","userAction","session","operations","muted","generation","error","uvCenter","position","Vector3","PI","_2PI","u","_u","v","_v","originPosition","observer","transition","quaternion","finalPosition","currentFiveState","Quaternion","x","y","z","w","panoIndex","mode","intersection","raycaster","event","lastVersion","opacity","meg","target","minU","_minV","width","height","bounding","minV","maxU","maxV","PanoVideoPluginController","options","data","panoVideoItem","renderID","videoItem","controller","id","controllers","errors","typings_exports","PanoVideoPlugin"],"sources":["../../src/PanoVideoPlugin/utils/index.ts","../../src/PanoVideoPlugin/VideoMeshController.ts","../../src/PanoVideoPlugin/Controller.ts","../../src/PanoVideoPlugin/typings.ts","../../src/PanoVideoPlugin/index.ts"],"sourcesContent":["import type { Vector3 } from 'three/webgpu'\n\nexport default function directionToLongitudeAndLatitude(\n direction:\n | Vector3\n | {\n x: number\n y: number\n z: number\n },\n) {\n const PI_2 = Math.PI * 2\n let longitude = -Math.atan2(direction.x, -direction.z)\n longitude = ((longitude % PI_2) + PI_2) % PI_2\n const latitude = -Math.asin(direction.y / 1)\n return { longitude, latitude }\n}\n","import { createVideoTexture } from '../shared-utils/three/loadVideoTexture'\nimport type { PlaybackManager, PlaybackController, PlaybackSession } from '../shared-utils/playback'\nimport type { Five, Mode, WorkObserver, WorkResolvedObserver } from '@realsee/five-webgpu'\nimport type { VideoMeshParams } from './typings'\nimport { requestAnimationFrameInterval } from '../shared-utils'\nimport type { Raycaster } from 'three/webgpu'\nimport * as THREE from 'three/webgpu'\nimport {\n type Intersection,\n LinearFilter,\n Mesh,\n Quaternion,\n MeshBasicNodeMaterial,\n SphereGeometry,\n Vector3,\n type VideoTexture,\n} from 'three/webgpu'\nimport directionToLongitudeAndLatitude from './utils'\nimport { animate } from 'animejs'\nimport type { Subscribe } from '../shared-utils/Subscribe'\nimport type { PluginEventMap } from './typings'\nimport type { Simplify } from 'type-fest'\nimport type { FiveUtil } from '../shared-utils/Utils/FiveUtil'\n\n/** 点位视频控制器\n * @description 控制器存在副作用,包括:\n * - 对 Five 事件的监听。\n * - 对 DOM 原生事件的监听。\n * - 用于播放视频的模型。\n * - 视频实例。\n * @description 清除副作用的力度从弱到强:\n * - 隐藏:hide,用于隐藏 UI 元素;不销毁多媒体资源。用于临时隐藏。\n * - 取消挂载:unmount,销毁视频资源;移除模型。用于不符合自身展示条件时执行。\n * - 禁用:disable,销毁视频资源;移除模型;取消监听。用于外部条件变换导致的功能禁用。\n * - 销毁:dispose,用于彻底销毁实例,dispose 之后将不响应任何事件。\n */\nexport class VideoMeshController {\n /** 传入的 ID,不可更改 */\n public get renderID() {\n return this._id\n }\n /** 是否已经销毁 */\n public get disposed() {\n return this._disposed\n }\n /** 是否已经启用 */\n public get enabled() {\n return this._enabled\n }\n public video: HTMLVideoElement\n\n private fiveUtil?: FiveUtil\n\n private _id: string\n /** 视频资源地址 */\n private readonly url: string\n /** Five Instance */\n private five: Five\n /** 视频对应的点位 */\n private panoIndex: number\n /** 视频对应的 Work Observer */\n private observer?: WorkResolvedObserver\n /** 视频在球面的 uv:[left, top, width, height] */\n private origin: number[]\n /** Video DOM */\n /** Video Mesh */\n private videoMesh: Mesh<SphereGeometry, MeshBasicNodeMaterial>\n private readonly videoTexture: VideoTexture\n private _enabled = true\n private _disposed = false\n /** 视频资源是否满足播放条件 */\n private videoDataLoaded = false\n /** 视频是否曾经播放过 */\n private hasVideoEverPlayed = false\n /** 自动 render five 的销毁函数\n * @remark 由于 render video 依赖 Five render,因此需要自动 render five。\n */\n private renderFiveDisposer?: () => void\n private fadeAnimation?: ReturnType<typeof animate>\n private playbackController?: PlaybackController\n private session?: PlaybackSession\n private playbackGeneration = 0\n private readonly videoOpacity = THREE.TSL.uniform(0)\n private hooks: Subscribe<Simplify<PluginEventMap>>\n\n /** 初始化视频、模型以及相关事件监听。 */\n public constructor(five: Five, params: VideoMeshParams & { mediaManager?: PlaybackManager; fiveUtil?: FiveUtil } & { hooks: Subscribe<Simplify<PluginEventMap>> }) {\n this.five = five\n this.panoIndex = params.panoIndex\n this.fiveUtil = params.fiveUtil\n this._id = params.renderID\n this.url = params.url\n this.origin = params.origin.slice() as number[]\n this.hooks = params.hooks\n this._enabled = params.initialState?.enabled ?? true\n // ========== 初始化 Video Instance ==========\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.autoplay = false\n video.muted = true\n video.loop = true\n video.playsInline = true\n this.video = video\n this.playbackController = params.mediaManager?.createController({ label: 'pano-video', onCancel: () => { this.playbackGeneration++; this.session = undefined } })\n // ========== 初始化模型 ==========\n // 视频贴图\n const videoTexture = this.videoTexture = createVideoTexture(this.video)\n // 模型材质:在球面原始 UV 中裁剪视频区域,并在边缘做 10% 羽化。\n const size = THREE.TSL.uniform(new THREE.Vector4(this.origin[0], 1 - this.origin[1] - this.origin[3], this.origin[2], this.origin[3]))\n const sourceUv = THREE.TSL.uv()\n const wrapWidth = THREE.TSL.max(size.x.add(size.z).sub(1), 0)\n const wrappedU = THREE.TSL.select(sourceUv.x.lessThanEqual(wrapWidth), sourceUv.x.add(1), sourceUv.x)\n const videoUv = THREE.TSL.vec2(wrappedU.sub(size.x).div(size.z), sourceUv.y.sub(size.y).div(size.w))\n const fadeX = THREE.TSL.select(\n videoUv.x.lessThan(0.1),\n videoUv.x.div(0.1),\n THREE.TSL.select(videoUv.x.greaterThan(0.9), THREE.TSL.float(1).sub(videoUv.x).div(0.1), 1),\n )\n const fadeY = THREE.TSL.select(\n videoUv.y.lessThan(0.1),\n videoUv.y.div(0.1),\n THREE.TSL.select(videoUv.y.greaterThan(0.9), THREE.TSL.float(1).sub(videoUv.y).div(0.1), 1),\n )\n const insideX = THREE.TSL.float(1).sub(THREE.TSL.step(0.5, THREE.TSL.abs(videoUv.x.sub(0.5))))\n const insideY = THREE.TSL.float(1).sub(THREE.TSL.step(0.5, THREE.TSL.abs(videoUv.y.sub(0.5))))\n const material = new MeshBasicNodeMaterial({ depthTest: true, transparent: true })\n material.colorNode = THREE.TSL.texture(videoTexture, videoUv).rgb\n material.opacityNode = insideX.mul(insideY).mul(THREE.TSL.min(fadeX, fadeY)).mul(this.videoOpacity)\n // 模型几何体\n const geometry = new SphereGeometry(1, 64, 64)\n // 因为是从内向外看,需要翻转 X 轴。\n geometry.scale(-1, 1, 1)\n // 点位视频模型\n const videoMesh = new Mesh(geometry, material)\n videoMesh.name = 'pano-video-plugin'\n this.videoMesh = videoMesh\n // five work 存在,说明已经加载过数据。\n if (this.fiveUtil.workUtil.work) this.onFiveDataLoaded()\n // 插件初始化时如果是开启状态,添加事件监听。\n if (this.enabled) this.addEventListeners()\n // 如果初始化时满足挂载条件,需要挂载副作用。\n this.mountIfNeeded()\n }\n\n /**\n * 取消静音\n *\n * @warning 需要注意:由于大部分浏览器的限制,视频的声音必须在用户有交互事件后才能开启,否则会被浏览器禁用视频播放。\n */\n public unmute = async (userAction = false) => {\n if (this.disposed) return\n if (!this.video.paused) return this.play(userAction, false)\n const session = this.playbackController?.begin({ userAction, audible: true })\n if (this.playbackController && !session) return\n this.session = session\n const operations = session?.bind(this.video) ?? this.video\n operations.muted = false\n }\n\n public async play(userAction = false, muted = false) {\n if (this.disposed) return\n const session = this.playbackController?.begin({ userAction, audible: !muted })\n if (this.playbackController && !session) return\n this.session = session\n const generation = ++this.playbackGeneration\n const operations = session?.bind(this.video) ?? this.video\n operations.muted = muted\n try { await operations.play() } catch (error) {\n if (session?.signal.aborted || generation !== this.playbackGeneration) return\n if ((error as Error).name === 'AbortError') { this.pause(); return }\n this.pause()\n throw error\n }\n }\n\n public pause() {\n // disable removes the native pause listener before unmounting the video.\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n this.fadeAnimation?.cancel()\n this.fadeAnimation = undefined\n if (this.videoOpacity.value > 0) this.videoOpacity.value = 1\n this.video.removeEventListener('timeupdate', this.onVideoTimeUpdate)\n this.playbackController?.cancel()\n this.playbackGeneration++\n this.session = undefined\n this.video.muted = true\n this.video.pause()\n }\n\n public mute() {\n const operations = this.session?.bind(this.video) ?? this.video\n operations.muted = true\n }\n\n /** 彻底销毁,不响应之后的任何事件 */\n public dispose() {\n if (this.disposed) return\n this.disable()\n this.playbackController?.dispose()\n this._disposed = true\n this.videoTexture.dispose()\n this.videoMesh.geometry.dispose()\n this.videoMesh.material.dispose()\n }\n\n public enable() {\n if (this.disposed) return\n if (this.enabled) return\n this._enabled = true\n if (!this.observer && this.five.work) this.onFiveDataLoaded()\n this.addEventListeners()\n this.mountIfNeeded()\n }\n\n /** 禁用插件 */\n public disable() {\n if (this.disposed) return\n if (!this.enabled) return\n this._enabled = false\n this.removeEventListeners()\n this.unmount()\n }\n\n /** 切换到全景模式并看向视频\n * @remark 如果遇到不能自动播放的问题,需要放到用户交互事件中调用。\n */\n public lookAtVideo() {\n if (!this.observer) return\n const uvCenter = this.getUVCenter()\n if (!uvCenter) return\n const position = this.uv2Position(uvCenter[0], uvCenter[1])\n if (!position) return\n const direction = new Vector3().subVectors(position, this.observer.position).normalize()\n const { longitude, latitude } = directionToLongitudeAndLatitude(direction)\n this.five.setState({ mode: 'Panorama', panoIndex: this.panoIndex, longitude, latitude })\n // setState 不会触发 wantsMoveToPano 事件,因此需要手动触发。\n this.onFiveWantsMoveToPano(this.panoIndex)\n }\n\n /** 把 uv 值转换成位置 */\n private uv2Position = (_u: number, _v: number) => {\n const r = 1\n // π: 180°\n const PI = Math.PI\n // 2π: 360°\n const _2PI = Math.PI * 2\n const u = _u\n const v = 1 - _v\n // 构造原始球面坐标\n // 球面原始朝向是 Z 轴正方向。\n // v = 0.5,即 X、Z 取到最大值。\n // x、z 的变化相当于 -X 轴绕 +Y 轴逆时针旋转 360° 回到 -X 轴。\n // 此时 x = -r * cos(2π * u)、z = r * sin(2π * u)\n // v 的变换相当于 -Y 轴绕 +Z 轴逆时针旋转 180°。\n // 此时 x = -r * cos(2π * u) * sin(π * v)、y = r * cos(π * v)、z = r * sin(2π * u) * sin(π * v)\n const originPosition = new Vector3(\n -r * Math.cos(_2PI * u) * Math.sin(PI * v),\n r * Math.cos(PI * v),\n r * Math.sin(_2PI * u) * Math.sin(PI * v),\n )\n // 由于从内向外看,需要翻转 X 轴坐标。\n originPosition.setX(-originPosition.x)\n\n const observer = this.fiveUtil.workUtil.getResolvedObserver(this.panoIndex)\n if (!observer) return this.logWarning(`点位 ${this.panoIndex} 不存在,请检查 Five 数据是否正常。`)\n const transition = observer.position.clone()\n const quaternion = observer.quaternion.clone()\n\n const finalPosition = originPosition.clone()\n // 原因同模型旋转。\n finalPosition.applyAxisAngle(new Vector3(0, 1, 0), Math.PI / 2)\n finalPosition.applyQuaternion(quaternion)\n finalPosition.add(transition)\n\n return finalPosition\n }\n\n /** 获取视频中心点的 uv */\n private getUVCenter() {\n if (!this.origin) return\n const u = this.origin[0] + this.origin[2] / 2\n const v = this.origin[1] + this.origin[3] / 2\n return [u, v] as const\n }\n\n /** 添加时间监听 */\n private addEventListeners() {\n this.five.on('loaded', this.onFiveDataLoaded)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('panoArrived', this.onFivePanoArrived)\n this.five.on('panoWillArrive', this.onFivePanoWillArrive)\n this.five.on('wantsMoveToPano', this.onFiveWantsMoveToPano)\n this.five.on('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.on('initAnimationEnded', this.onFiveInitAnimationEnded)\n this.video.addEventListener('loadeddata', this.onVideoDataLoaded)\n this.video.addEventListener('canplay', this.onVideoDataLoaded)\n this.video.addEventListener('canplaythrough', this.onVideoDataLoaded)\n this.video.addEventListener('emptied', this.onVideoEmptied)\n this.video.addEventListener('seeked', this.onVideoSeeked)\n this.video.addEventListener('playing', this.onVideoPlaying)\n this.video.addEventListener('pause', this.onVideoPaused)\n }\n\n /** 移除事件监听 */\n private removeEventListeners() {\n this.five.off('loaded', this.onFiveDataLoaded)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('panoArrived', this.onFivePanoArrived)\n this.five.off('panoWillArrive', this.onFivePanoWillArrive)\n this.five.off('wantsMoveToPano', this.onFiveWantsMoveToPano)\n this.five.off('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.off('initAnimationEnded', this.onFiveInitAnimationEnded)\n this.video.removeEventListener('loadeddata', this.onVideoDataLoaded)\n this.video.removeEventListener('canplay', this.onVideoDataLoaded)\n this.video.removeEventListener('canplaythrough', this.onVideoDataLoaded)\n this.video.removeEventListener('emptied', this.onVideoEmptied)\n this.video.removeEventListener('seeked', this.onVideoSeeked)\n this.video.removeEventListener('playing', this.onVideoPlaying)\n this.video.removeEventListener('pause', this.onVideoPaused)\n }\n\n /** 如果满足 mount 条件,mount */\n private mountIfNeeded() {\n const currentFiveState = this.five.getCurrentState()\n if (currentFiveState.mode === 'Panorama' && currentFiveState.panoIndex === this.panoIndex && this.enabled) {\n this.mount()\n }\n }\n\n /** 挂载:加载视频资源;添加模型。 */\n private mount() {\n if (this.disposed) return this.logWarning('插件已经销毁,无法挂载。')\n if (this.url === '') return this.logWarning('视频资源不存在。')\n // if (this.panoIndex )\n if (this.video.src !== this.url) {\n this.videoDataLoaded = false\n this.video.src = this.url\n }\n // 如果视频正在播放,不做任何操作。\n if (!this.video.paused) return\n this.play(false, this.video.muted).catch((error) => {\n this.logWarning(error instanceof Error ? error.message : '视频播放失败。')\n })\n }\n\n /** 卸载:销毁视频资源;移除模型。 */\n private unmount() {\n this.pause()\n this.video.pause()\n // 去除模型后下次播放时,需要渐变显示,这里透明度重置为0。\n this.videoOpacity.value = 0\n this.videoDataLoaded = false\n this.video.removeAttribute('src')\n this.video.load()\n this.five.scene.remove(this.videoMesh)\n }\n\n /** 暂停视频,去除模型。 */\n private hide() {\n this.pause()\n this.video.pause()\n // 去除模型后下次播放时,需要渐变显示,这里透明度重置为0。\n this.videoOpacity.value = 0\n this.five.scene.remove(this.videoMesh)\n }\n\n /** Five 数据加载后需要根据点位位姿调整点位模型位置 */\n private onFiveDataLoaded = () => {\n const observer = this.fiveUtil.workUtil.getResolvedObserver(this.panoIndex)\n if (!observer) return this.logWarning(`点位 ${this.panoIndex} 不存在,请检查 Five 数据是否正常。`)\n // 初始化依赖 work 的数据\n this.observer = observer\n // 初始化模型位姿\n const { x, y, z, w } = observer.quaternion\n const quaternion = new Quaternion(x, y, z, w)\n const position = observer.position\n this.videoMesh.position.fromArray([position.x, position.y, position.z])\n // 重置模型旋转\n this.videoMesh.quaternion.set(0, 0, 0, 1)\n // 绕 Y 轴逆时针旋转 90 度\n // 这里是因为历史问题,算法模块里面转了 90 度,所以前端也要转 90 度。\n // 后面可以联系 @饶童 一起改掉。\n this.videoMesh.rotateOnAxis(new Vector3(0, 1, 0), Math.PI / 2)\n // 应用点位旋转\n this.videoMesh.applyQuaternion(quaternion)\n }\n\n /** 兼容视频播放 */\n private onFiveWantsMoveToPano = (panoIndex: number) => {\n // 点位不匹配,不做任何操作。\n if (panoIndex !== this.panoIndex) return\n // 如果视频之前播放过,不用再做兼容\n if (this.hasVideoEverPlayed) return\n this.play(false, true).catch(() => {\n // 视频播放失败时,不做任何操作。\n })\n }\n\n /** 走到某个点位上时,挂载/卸载视频 */\n private onFivePanoArrived = (panoIndex: number) => {\n if (this.disposed) return this.logWarning('实例已被销毁')\n if (!this.enabled) return\n // 如果点位条件满足,挂载。\n if (this.panoIndex === panoIndex) this.mount()\n }\n\n private onFivePanoWillArrive = (panoIndex: number) => {\n // wantsMoveToPano 和 panoArrived 可能不是同一个点位,如果不一致,销毁副作用。\n if (panoIndex !== this.panoIndex) return this.unmount()\n if (this.panoIndex !== panoIndex) this.unmount()\n }\n\n /** Five 模型变化 */\n private onFiveModeChange = (mode: Mode) => {\n if (mode !== 'Panorama') this.hide()\n // Panorama 的判断在 onFiveInitAnimationEnded\n }\n\n /** Five mode change 动画结束 */\n private onFiveInitAnimationEnded = () => {\n const currentFiveState = this.five.getCurrentState()\n if (currentFiveState.mode === 'Panorama' && currentFiveState.panoIndex === this.panoIndex) this.mount()\n }\n\n /** Five Canvas 点击 */\n private onFiveWantsTapGesture = (raycaster: Raycaster) => {\n if (!this.five.scene.children.includes(this.videoMesh)) return\n if (this.disposed) return this.logWarning('实例已被销毁')\n if (!this.enabled) return this.logWarning('实例已被禁用')\n const [intersection] = raycaster.intersectObject(this.videoMesh)\n if (!intersection) return\n const isIntersectInVideo = this.checkIntersectionInBounding(this.origin, intersection)\n if (isIntersectInVideo) {\n const event = {\n target: this,\n _preventDefaultReturn: false,\n preventDefault: () => {\n event._preventDefaultReturn = true\n },\n }\n this.hooks.emit('click', event)\n if (event._preventDefaultReturn === false) {\n if (this.video.muted) this.unmute(true)\n else { this.mute() }\n }\n return false as const\n }\n }\n\n /** video canplaythrough 事件触发 */\n private onVideoDataLoaded = () => {\n this.videoDataLoaded = this.hasCurrentFrame()\n if (this.video.paused === false && this.video.src !== '') this.onVideoPlayingAndLoaded()\n }\n\n /** video playing 事件触发\n * @remarks\n * 事件触发时机:\n * - video is ready to start after having been paused.\n * - video is ready to play after delayed due to lack of data.\n * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video\n */\n private onVideoPlaying = () => {\n this.hasVideoEverPlayed = true\n // 空视频不能挂载。\n if (!this.enabled) return\n // A cached video can already have a frame without another canplaythrough.\n this.videoDataLoaded = this.hasCurrentFrame()\n if (this.videoDataLoaded) this.onVideoPlayingAndLoaded()\n }\n\n /** 触发 playing 和 canplaythrough */\n private onVideoPlayingAndLoaded = () => {\n if (!this.videoDataLoaded || !this.hasCurrentFrame() || this.video.paused) return\n this.video.removeEventListener('timeupdate', this.onVideoTimeUpdate)\n // Do not wait for Safari's throttled timeupdate after a decoded frame is ready.\n this.onVideoTimeUpdate()\n }\n\n private hasCurrentFrame() {\n return this.video.readyState >= 2 && this.video.videoWidth > 0 && this.video.videoHeight > 0\n }\n\n private onVideoTimeUpdate = () => {\n if (this.disposed || !this.enabled || this.video.paused || !this.hasCurrentFrame()) return\n if (this.panoIndex !== this.five.getCurrentState().panoIndex || this.five.getCurrentState().mode !== 'Panorama') return\n if (!this.renderFiveDisposer) {\n let lastVersion = this.videoTexture.version\n this.renderFiveDisposer = requestAnimationFrameInterval(() => {\n if (this.video.paused || !this.hasCurrentFrame()) return\n // Retry when Safari's frame callback has not advanced the texture.\n // Keep normal rVFC-driven uploads without adding another upload per tick.\n if (this.videoTexture.version === lastVersion) this.videoTexture.needsUpdate = true\n lastVersion = this.videoTexture.version\n this.five.needsRender = true\n }, 30)\n }\n this.videoTexture.needsUpdate = true\n this.five.needsRender = true\n this.five.scene.add(this.videoMesh)\n if (this.videoOpacity.value === 0) {\n this.fadeAnimation?.cancel()\n const opacity = { value: 0 }\n this.fadeAnimation = animate(opacity, {\n value: 1, duration: 300, ease: 'linear',\n onUpdate: () => { this.videoOpacity.value = opacity.value },\n onComplete: () => { this.videoOpacity.value = 1; this.fadeAnimation = undefined },\n })\n }\n }\n\n /** video pause 事件触发 */\n private onVideoPaused = () => {\n // The browser may queue pause before a newer play request has started.\n if (!this.video.paused) return\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n }\n\n private onVideoEmptied = () => {\n // A queued unload event may arrive after the replacement frame is ready.\n if (this.hasCurrentFrame()) return\n this.videoDataLoaded = false\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n this.fadeAnimation?.cancel()\n this.fadeAnimation = undefined\n this.videoOpacity.value = 0\n this.five.scene.remove(this.videoMesh)\n this.five.needsRender = true\n }\n\n private onVideoSeeked = () => {\n if (this.disposed || !this.enabled || !this.hasCurrentFrame()) return\n this.videoTexture.needsUpdate = true\n this.five.needsRender = true\n }\n\n /** 控制台打印警告 */\n private logWarning(meg: string) {\n console.warn(`⛔ ==> [VideoMeshController]:`, meg)\n }\n\n /** 检测射线与模型的交点是不是在视频的范围内 */\n private checkIntersectionInBounding(bounding: number[], target: Intersection) {\n if (!target.uv) return false\n const [u, v] = target.uv.toArray()\n const [minU, _minV, width, height] = bounding\n const minV = 1 - _minV - height\n const maxU = minU + width\n const maxV = minV + height\n return u >= minU && u <= maxU && v >= minV && v <= maxV\n }\n}\n","import type { PlaybackManager } from '../shared-utils/playback'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { LoadParams, PluginEventMap, PluginState, PluginData, VideoItem } from './typings'\nimport { VideoMeshController } from './VideoMeshController'\nimport * as BasePlugin from '../base/BasePlugin'\n\nexport class PanoVideoPluginController extends BasePlugin.Controller<PluginState, PluginEventMap> {\n /** 插件 State */\n public get state() {\n return {\n enabled: this.enabled,\n }\n }\n\n /** 插件是否已被销毁 */\n public get disposed() {\n return this._disposed\n }\n\n public controllerMap: Map<string, VideoMeshController> = new Map()\n\n public data?: PluginData\n\n private enabled = true\n private _disposed = false\n private readonly removeFiveDisposeListener: () => void\n\n public constructor(five: Five, private options?: { mediaManager?: PlaybackManager }) {\n super(five)\n // Five emits dispose synchronously, before it releases the renderer.\n this.removeFiveDisposeListener = five.on('dispose', () => {\n try { this.dispose() } catch (error) {\n // Five must finish disposing its other resources and the renderer.\n console.error('[PanoVideoPluginController]: dispose failed', error)\n }\n })\n }\n\n /** 加载点位视频数据,加载数据并不代表会加载点位视频。 */\n public load(data: PluginData, params?: LoadParams) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (typeof params?.initialState?.enabled !== 'undefined' && params.initialState.enabled !== this.enabled) {\n params.initialState.enabled ? this.enable() : this.disable()\n }\n this.clear()\n // 初始化 controller 实例\n data.list.forEach((panoVideoItem) => {\n const panoIndex = panoVideoItem.pano_index\n const renderID = panoVideoItem.render_id\n panoVideoItem.video_list.forEach((videoItem) => {\n this.controllerMap.set(\n videoItem.render_id,\n new VideoMeshController(this.five, {\n mediaManager: this.options?.mediaManager,\n ...videoItem,\n fiveUtil: this.fiveUtil,\n panoIndex,\n renderID,\n hooks: this.hooks,\n initialState: { enabled: this.enabled },\n }),\n )\n })\n })\n\n this.data = data\n\n this.hooks.emit('dataLoaded', data)\n }\n\n /** 开启插件功能。 */\n public enable(options?: BasePlugin.BaseOptions) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (this.enabled) return\n this.enabled = true\n Array.from(this.controllerMap.values()).forEach((controller) => controller.enable())\n const userAction = options?.userAction ?? true\n this.hooks.emit('enable', { userAction })\n }\n\n /** 禁用插件功能。 */\n public disable(options?: BasePlugin.BaseOptions) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (!this.enabled) return\n this.enabled = false\n Array.from(this.controllerMap.values()).forEach((controller) => controller.disable())\n const userAction = options?.userAction ?? true\n this.hooks.emit('disable', { userAction })\n }\n\n /** 看向某个视频。\n * - 会自动切换到全景模式。\n * - 如果遇到不能自动播放的问题,需要放到用户交互事件中调用。\n */\n public lookAtVideoItemByRenderID(id: string) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.lookAtVideo()\n }\n\n /**\n * 取消静音。\n *\n * 大部分浏览器需要用户交互后才能开启视频声音。\n *\n * 如果需要取消静音,建议在用户交互事件中调用本方法。\n *\n * 例如:\n *\n * ```jsx\n * onClick={() => {\n * panoVideoPluginController.lookAtVideoItemByRenderID('xxx')\n * panoVideoPluginController.unmuteByRenderID('xxx')\n * }}\n * ```\n */\n public unmuteByRenderID(id: string, userAction = false) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.unmute(userAction)\n }\n\n /** 为一个点位添加视频(可以是多条)。 */\n public add(panoIndex: number, videoItems: VideoItem[]) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n videoItems.forEach((videoItem) => {\n if (this.controllerMap.get(videoItem.render_id)) return this.logWarning(`ID 为 ${videoItem.render_id} 的点位视频已存在`)\n const renderID = videoItem.render_id\n this.controllerMap.set(\n videoItem.render_id,\n new VideoMeshController(this.five, {\n mediaManager: this.options?.mediaManager,\n ...videoItem,\n fiveUtil: this.fiveUtil,\n panoIndex,\n renderID,\n hooks: this.hooks,\n initialState: { enabled: this.enabled },\n }),\n )\n })\n }\n\n /** 根据 VideoItem render_id 删除某个视频。 */\n public removeByRenderID(id: string) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.dispose()\n this.controllerMap.delete(id)\n }\n\n /** 清空现有数据 */\n public clear() {\n if (this.disposed) return this.logWarning('插件已被销毁')\n this.releaseControllers()\n }\n\n /** 销毁插件 */\n public dispose() {\n if (this.disposed) return\n this._disposed = true\n this.removeFiveDisposeListener()\n this.releaseControllers()\n }\n\n private releaseControllers() {\n const controllers = Array.from(this.controllerMap.values())\n this.controllerMap.clear()\n // Retire every video even if a material disposal listener throws.\n const errors: unknown[] = []\n for (const controller of controllers) {\n try { controller.dispose() } catch (error) { errors.push(error) }\n }\n if (errors.length) throw errors[0]\n }\n\n /** 控制台打印警告 */\n // TODO: 全局函数 curry 化\n private logWarning(meg: string) {\n console.warn(`⛔ ==> [PanoVideoPluginController]:`, meg)\n }\n}\n","import type * as BasePlugin from '../base/BasePluginWithData'\nimport type { VideoMeshController } from './VideoMeshController'\n\n/** 单个视频元素 */\nexport interface VideoItem {\n /** client render ID\n * @remarks 为什么不用 id 作为唯一标识?\n * - id 是后端生成的,而 render_id 是前端生成的,在编辑时为了保证在请求后端数据之前也能进行渲染,使用额外的 id 进行渲染。\n * - 为了保证两端的数据一致性,插件里使用 render_id 作为唯一 ID。\n */\n render_id: string\n /** 文件地址 */\n url: string\n /** 算法处理的视频 uv 信息\n * @description [left, top, width, height]\n */\n origin: number[]\n}\n\n/** 点位视频元素 */\nexport interface PanoVideoItem {\n /** client render ID */\n render_id: string\n /** 视频播放点位 */\n pano_index: number\n /** 视频列表 */\n video_list: VideoItem[]\n}\n\n/** 点位视频模型参数 */\nexport interface VideoMeshParams {\n /** client render ID */\n renderID: string\n /** video 文件地址 */\n url: string\n /** 算法处理的视频 uv 信息\n * @description [left, top, width, height]\n */\n origin: number[]\n /** 视频播放点位 */\n panoIndex: number\n /** 初始状态 */\n initialState?: {\n enabled?: boolean\n }\n}\n\n/** 加载数据时的额外参数 */\nexport interface LoadParams {\n initialState?: {\n enabled?: boolean\n }\n}\n\nexport interface PluginState {\n enabled: boolean\n}\n\nexport interface PluginData {\n list: PanoVideoItem[]\n}\n\nexport interface PluginEventMap extends BasePlugin.EventMap<PluginState, PluginData> {\n /** 点位视频模型开启 */\n enable: (params: { userAction: boolean }) => void\n /** 点位视频模型关闭 */\n disable: (params: { userAction: boolean }) => void\n /** 点位视频被点击 */\n click: (event: { target: VideoMeshController; preventDefault: () => void }) => void\n}\n","import type { PlaybackManager } from '../shared-utils/playback'\nimport type { FivePlugin } from '@realsee/five-webgpu'\nimport { PanoVideoPluginController } from './Controller'\nimport * as _PanoVideoPluginType from './typings'\n\n/** 点位视频播放插件\n * - 支持一次性加载多组数据。\n * - 走到点位上时播放视频(可能是多个)。\n * - 走出点位时销毁视频。\n * - 允许动态开启和禁用功能。\n * - 视频只能在全景模式且点位一致时才会播放。不满足条件会自动销毁。\n * - 不做多媒体缓存,缓解内存占用。\n */\nexport const PanoVideoPlugin: FivePlugin<{ mediaManager?: PlaybackManager } | undefined, PanoVideoPluginController> = (five, options) => {\n return new PanoVideoPluginController(five, options)\n}\n\nexport { _PanoVideoPluginType as PanoVideoPluginType }\nexport type PanoVideoPluginParameterType = { mediaManager?: PlaybackManager } | undefined\nexport type PanoVideoPluginReturnType = InstanceType<typeof PanoVideoPluginController>\nexport default PanoVideoPlugin\n"],"mappings":"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"}
1
+ {"version":3,"file":"pano-video-CSb6bzy-.js","names":["BasePlugin.Controller","__exportAll","requestAnimationFrameInterval","animate","Controller","createVideoTexture","THREE","directionToLongitudeAndLatitude","PI_2","longitude","direction","latitude","VideoMeshController","five","params","video","videoTexture","size","sourceUv","wrapWidth","wrappedU","videoUv","fadeX","fadeY","insideX","insideY","material","MeshBasicNodeMaterial","geometry","SphereGeometry","videoMesh","Mesh","userAction","session","operations","muted","generation","error","uvCenter","position","Vector3","PI","_2PI","u","_u","v","_v","originPosition","observer","transition","quaternion","finalPosition","currentFiveState","Quaternion","x","y","z","w","panoIndex","mode","intersection","raycaster","event","lastVersion","opacity","meg","target","minU","_minV","width","height","bounding","minV","maxU","maxV","PanoVideoPluginController","options","data","panoVideoItem","renderID","videoItem","controller","id","controllers","errors","typings_exports","PanoVideoPlugin"],"sources":["../../src/PanoVideoPlugin/utils/index.ts","../../src/PanoVideoPlugin/VideoMeshController.ts","../../src/PanoVideoPlugin/Controller.ts","../../src/PanoVideoPlugin/typings.ts","../../src/PanoVideoPlugin/index.ts"],"sourcesContent":["import type { Vector3 } from 'three/webgpu'\n\nexport default function directionToLongitudeAndLatitude(\n direction:\n | Vector3\n | {\n x: number\n y: number\n z: number\n },\n) {\n const PI_2 = Math.PI * 2\n let longitude = -Math.atan2(direction.x, -direction.z)\n longitude = ((longitude % PI_2) + PI_2) % PI_2\n const latitude = -Math.asin(direction.y / 1)\n return { longitude, latitude }\n}\n","import { createVideoTexture } from '../shared-utils/three/loadVideoTexture'\nimport type { PlaybackManager, PlaybackController, PlaybackSession } from '../shared-utils/playback'\nimport type { Five, Mode, WorkObserver, WorkResolvedObserver } from '@realsee/five-webgpu'\nimport type { VideoMeshParams } from './typings'\nimport { requestAnimationFrameInterval } from '../shared-utils'\nimport type { Raycaster } from 'three/webgpu'\nimport * as THREE from 'three/webgpu'\nimport {\n type Intersection,\n LinearFilter,\n Mesh,\n Quaternion,\n MeshBasicNodeMaterial,\n SphereGeometry,\n Vector3,\n type VideoTexture,\n} from 'three/webgpu'\nimport directionToLongitudeAndLatitude from './utils'\nimport { animate } from 'animejs'\nimport type { Subscribe } from '../shared-utils/Subscribe'\nimport type { PluginEventMap } from './typings'\nimport type { Simplify } from 'type-fest'\nimport type { FiveUtil } from '../shared-utils/Utils/FiveUtil'\n\n/** 点位视频控制器\n * @description 控制器存在副作用,包括:\n * - 对 Five 事件的监听。\n * - 对 DOM 原生事件的监听。\n * - 用于播放视频的模型。\n * - 视频实例。\n * @description 清除副作用的力度从弱到强:\n * - 隐藏:hide,用于隐藏 UI 元素;不销毁多媒体资源。用于临时隐藏。\n * - 取消挂载:unmount,销毁视频资源;移除模型。用于不符合自身展示条件时执行。\n * - 禁用:disable,销毁视频资源;移除模型;取消监听。用于外部条件变换导致的功能禁用。\n * - 销毁:dispose,用于彻底销毁实例,dispose 之后将不响应任何事件。\n */\nexport class VideoMeshController {\n /** 传入的 ID,不可更改 */\n public get renderID() {\n return this._id\n }\n /** 是否已经销毁 */\n public get disposed() {\n return this._disposed\n }\n /** 是否已经启用 */\n public get enabled() {\n return this._enabled\n }\n public video: HTMLVideoElement\n\n private fiveUtil?: FiveUtil\n\n private _id: string\n /** 视频资源地址 */\n private readonly url: string\n /** Five Instance */\n private five: Five\n /** 视频对应的点位 */\n private panoIndex: number\n /** 视频对应的 Work Observer */\n private observer?: WorkResolvedObserver\n /** 视频在球面的 uv:[left, top, width, height] */\n private origin: number[]\n /** Video DOM */\n /** Video Mesh */\n private videoMesh: Mesh<SphereGeometry, MeshBasicNodeMaterial>\n private readonly videoTexture: VideoTexture\n private _enabled = true\n private _disposed = false\n /** 视频资源是否满足播放条件 */\n private videoDataLoaded = false\n /** 视频是否曾经播放过 */\n private hasVideoEverPlayed = false\n /** 自动 render five 的销毁函数\n * @remark 由于 render video 依赖 Five render,因此需要自动 render five。\n */\n private renderFiveDisposer?: () => void\n private fadeAnimation?: ReturnType<typeof animate>\n private playbackController?: PlaybackController\n private session?: PlaybackSession\n private playbackGeneration = 0\n private readonly videoOpacity = THREE.TSL.uniform(0)\n private hooks: Subscribe<Simplify<PluginEventMap>>\n\n /** 初始化视频、模型以及相关事件监听。 */\n public constructor(five: Five, params: VideoMeshParams & { mediaManager?: PlaybackManager; fiveUtil?: FiveUtil } & { hooks: Subscribe<Simplify<PluginEventMap>> }) {\n this.five = five\n this.panoIndex = params.panoIndex\n this.fiveUtil = params.fiveUtil\n this._id = params.renderID\n this.url = params.url\n this.origin = params.origin.slice() as number[]\n this.hooks = params.hooks\n this._enabled = params.initialState?.enabled ?? true\n // ========== 初始化 Video Instance ==========\n const video = document.createElement('video')\n video.crossOrigin = 'anonymous'\n video.autoplay = false\n video.muted = true\n video.loop = true\n video.playsInline = true\n this.video = video\n this.playbackController = params.mediaManager?.createController({ label: 'pano-video', onCancel: () => { this.playbackGeneration++; this.session = undefined } })\n // ========== 初始化模型 ==========\n // 视频贴图\n const videoTexture = this.videoTexture = createVideoTexture(this.video)\n // 模型材质:在球面原始 UV 中裁剪视频区域,并在边缘做 10% 羽化。\n const size = THREE.TSL.uniform(new THREE.Vector4(this.origin[0], 1 - this.origin[1] - this.origin[3], this.origin[2], this.origin[3]))\n const sourceUv = THREE.TSL.uv()\n const wrapWidth = THREE.TSL.max(size.x.add(size.z).sub(1), 0)\n const wrappedU = THREE.TSL.select(sourceUv.x.lessThanEqual(wrapWidth), sourceUv.x.add(1), sourceUv.x)\n const videoUv = THREE.TSL.vec2(wrappedU.sub(size.x).div(size.z), sourceUv.y.sub(size.y).div(size.w))\n const fadeX = THREE.TSL.select(\n videoUv.x.lessThan(0.1),\n videoUv.x.div(0.1),\n THREE.TSL.select(videoUv.x.greaterThan(0.9), THREE.TSL.float(1).sub(videoUv.x).div(0.1), 1),\n )\n const fadeY = THREE.TSL.select(\n videoUv.y.lessThan(0.1),\n videoUv.y.div(0.1),\n THREE.TSL.select(videoUv.y.greaterThan(0.9), THREE.TSL.float(1).sub(videoUv.y).div(0.1), 1),\n )\n const insideX = THREE.TSL.float(1).sub(THREE.TSL.step(0.5, THREE.TSL.abs(videoUv.x.sub(0.5))))\n const insideY = THREE.TSL.float(1).sub(THREE.TSL.step(0.5, THREE.TSL.abs(videoUv.y.sub(0.5))))\n const material = new MeshBasicNodeMaterial({ depthTest: true, transparent: true })\n material.colorNode = THREE.TSL.texture(videoTexture, videoUv).rgb\n material.opacityNode = insideX.mul(insideY).mul(THREE.TSL.min(fadeX, fadeY)).mul(this.videoOpacity)\n // 模型几何体\n const geometry = new SphereGeometry(1, 64, 64)\n // 因为是从内向外看,需要翻转 X 轴。\n geometry.scale(-1, 1, 1)\n // 点位视频模型\n const videoMesh = new Mesh(geometry, material)\n videoMesh.name = 'pano-video-plugin'\n this.videoMesh = videoMesh\n // five work 存在,说明已经加载过数据。\n if (this.fiveUtil.workUtil.work) this.onFiveDataLoaded()\n // 插件初始化时如果是开启状态,添加事件监听。\n if (this.enabled) this.addEventListeners()\n // 如果初始化时满足挂载条件,需要挂载副作用。\n this.mountIfNeeded()\n }\n\n /**\n * 取消静音\n *\n * @warning 需要注意:由于大部分浏览器的限制,视频的声音必须在用户有交互事件后才能开启,否则会被浏览器禁用视频播放。\n */\n public unmute = async (userAction = false) => {\n if (this.disposed) return\n if (!this.video.paused) return this.play(userAction, false)\n const session = this.playbackController?.begin({ userAction, audible: true })\n if (this.playbackController && !session) return\n this.session = session\n const operations = session?.bind(this.video) ?? this.video\n operations.muted = false\n }\n\n public async play(userAction = false, muted = false) {\n if (this.disposed) return\n const session = this.playbackController?.begin({ userAction, audible: !muted })\n if (this.playbackController && !session) return\n this.session = session\n const generation = ++this.playbackGeneration\n const operations = session?.bind(this.video) ?? this.video\n operations.muted = muted\n try { await operations.play() } catch (error) {\n if (session?.signal.aborted || generation !== this.playbackGeneration) return\n if ((error as Error).name === 'AbortError') { this.pause(); return }\n this.pause()\n throw error\n }\n }\n\n public pause() {\n // disable removes the native pause listener before unmounting the video.\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n this.fadeAnimation?.cancel()\n this.fadeAnimation = undefined\n if (this.videoOpacity.value > 0) this.videoOpacity.value = 1\n this.video.removeEventListener('timeupdate', this.onVideoTimeUpdate)\n this.playbackController?.cancel()\n this.playbackGeneration++\n this.session = undefined\n this.video.muted = true\n this.video.pause()\n }\n\n public mute() {\n const operations = this.session?.bind(this.video) ?? this.video\n operations.muted = true\n }\n\n /** 彻底销毁,不响应之后的任何事件 */\n public dispose() {\n if (this.disposed) return\n this.disable()\n this.playbackController?.dispose()\n this._disposed = true\n this.videoTexture.dispose()\n this.videoMesh.geometry.dispose()\n this.videoMesh.material.dispose()\n }\n\n public enable() {\n if (this.disposed) return\n if (this.enabled) return\n this._enabled = true\n if (!this.observer && this.five.work) this.onFiveDataLoaded()\n this.addEventListeners()\n this.mountIfNeeded()\n }\n\n /** 禁用插件 */\n public disable() {\n if (this.disposed) return\n if (!this.enabled) return\n this._enabled = false\n this.removeEventListeners()\n this.unmount()\n }\n\n /** 切换到全景模式并看向视频\n * @remark 如果遇到不能自动播放的问题,需要放到用户交互事件中调用。\n */\n public lookAtVideo() {\n if (!this.observer) return\n const uvCenter = this.getUVCenter()\n if (!uvCenter) return\n const position = this.uv2Position(uvCenter[0], uvCenter[1])\n if (!position) return\n const direction = new Vector3().subVectors(position, this.observer.position).normalize()\n const { longitude, latitude } = directionToLongitudeAndLatitude(direction)\n this.five.setState({ mode: 'Panorama', panoIndex: this.panoIndex, longitude, latitude })\n // setState 不会触发 wantsMoveToPano 事件,因此需要手动触发。\n this.onFiveWantsMoveToPano(this.panoIndex)\n }\n\n /** 把 uv 值转换成位置 */\n private uv2Position = (_u: number, _v: number) => {\n const r = 1\n // π: 180°\n const PI = Math.PI\n // 2π: 360°\n const _2PI = Math.PI * 2\n const u = _u\n const v = 1 - _v\n // 构造原始球面坐标\n // 球面原始朝向是 Z 轴正方向。\n // v = 0.5,即 X、Z 取到最大值。\n // x、z 的变化相当于 -X 轴绕 +Y 轴逆时针旋转 360° 回到 -X 轴。\n // 此时 x = -r * cos(2π * u)、z = r * sin(2π * u)\n // v 的变换相当于 -Y 轴绕 +Z 轴逆时针旋转 180°。\n // 此时 x = -r * cos(2π * u) * sin(π * v)、y = r * cos(π * v)、z = r * sin(2π * u) * sin(π * v)\n const originPosition = new Vector3(\n -r * Math.cos(_2PI * u) * Math.sin(PI * v),\n r * Math.cos(PI * v),\n r * Math.sin(_2PI * u) * Math.sin(PI * v),\n )\n // 由于从内向外看,需要翻转 X 轴坐标。\n originPosition.setX(-originPosition.x)\n\n const observer = this.fiveUtil.workUtil.getResolvedObserver(this.panoIndex)\n if (!observer) return this.logWarning(`点位 ${this.panoIndex} 不存在,请检查 Five 数据是否正常。`)\n const transition = observer.position.clone()\n const quaternion = observer.quaternion.clone()\n\n const finalPosition = originPosition.clone()\n // 原因同模型旋转。\n finalPosition.applyAxisAngle(new Vector3(0, 1, 0), Math.PI / 2)\n finalPosition.applyQuaternion(quaternion)\n finalPosition.add(transition)\n\n return finalPosition\n }\n\n /** 获取视频中心点的 uv */\n private getUVCenter() {\n if (!this.origin) return\n const u = this.origin[0] + this.origin[2] / 2\n const v = this.origin[1] + this.origin[3] / 2\n return [u, v] as const\n }\n\n /** 添加时间监听 */\n private addEventListeners() {\n this.five.on('loaded', this.onFiveDataLoaded)\n this.five.on('modeChange', this.onFiveModeChange)\n this.five.on('panoArrived', this.onFivePanoArrived)\n this.five.on('panoWillArrive', this.onFivePanoWillArrive)\n this.five.on('wantsMoveToPano', this.onFiveWantsMoveToPano)\n this.five.on('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.on('initAnimationEnded', this.onFiveInitAnimationEnded)\n this.video.addEventListener('loadeddata', this.onVideoDataLoaded)\n this.video.addEventListener('canplay', this.onVideoDataLoaded)\n this.video.addEventListener('canplaythrough', this.onVideoDataLoaded)\n this.video.addEventListener('emptied', this.onVideoEmptied)\n this.video.addEventListener('seeked', this.onVideoSeeked)\n this.video.addEventListener('playing', this.onVideoPlaying)\n this.video.addEventListener('pause', this.onVideoPaused)\n }\n\n /** 移除事件监听 */\n private removeEventListeners() {\n this.five.off('loaded', this.onFiveDataLoaded)\n this.five.off('modeChange', this.onFiveModeChange)\n this.five.off('panoArrived', this.onFivePanoArrived)\n this.five.off('panoWillArrive', this.onFivePanoWillArrive)\n this.five.off('wantsMoveToPano', this.onFiveWantsMoveToPano)\n this.five.off('wantsTapGesture', this.onFiveWantsTapGesture)\n this.five.off('initAnimationEnded', this.onFiveInitAnimationEnded)\n this.video.removeEventListener('loadeddata', this.onVideoDataLoaded)\n this.video.removeEventListener('canplay', this.onVideoDataLoaded)\n this.video.removeEventListener('canplaythrough', this.onVideoDataLoaded)\n this.video.removeEventListener('emptied', this.onVideoEmptied)\n this.video.removeEventListener('seeked', this.onVideoSeeked)\n this.video.removeEventListener('playing', this.onVideoPlaying)\n this.video.removeEventListener('pause', this.onVideoPaused)\n }\n\n /** 如果满足 mount 条件,mount */\n private mountIfNeeded() {\n const currentFiveState = this.five.getCurrentState()\n if (currentFiveState.mode === 'Panorama' && currentFiveState.panoIndex === this.panoIndex && this.enabled) {\n this.mount()\n }\n }\n\n /** 挂载:加载视频资源;添加模型。 */\n private mount() {\n if (this.disposed) return this.logWarning('插件已经销毁,无法挂载。')\n if (this.url === '') return this.logWarning('视频资源不存在。')\n // if (this.panoIndex )\n if (this.video.src !== this.url) {\n this.videoDataLoaded = false\n this.video.src = this.url\n }\n // 如果视频正在播放,不做任何操作。\n if (!this.video.paused) return\n this.play(false, this.video.muted).catch((error) => {\n this.logWarning(error instanceof Error ? error.message : '视频播放失败。')\n })\n }\n\n /** 卸载:销毁视频资源;移除模型。 */\n private unmount() {\n this.pause()\n this.video.pause()\n // 去除模型后下次播放时,需要渐变显示,这里透明度重置为0。\n this.videoOpacity.value = 0\n this.videoDataLoaded = false\n this.video.removeAttribute('src')\n this.video.load()\n this.five.scene.remove(this.videoMesh)\n }\n\n /** 暂停视频,去除模型。 */\n private hide() {\n this.pause()\n this.video.pause()\n // 去除模型后下次播放时,需要渐变显示,这里透明度重置为0。\n this.videoOpacity.value = 0\n this.five.scene.remove(this.videoMesh)\n }\n\n /** Five 数据加载后需要根据点位位姿调整点位模型位置 */\n private onFiveDataLoaded = () => {\n const observer = this.fiveUtil.workUtil.getResolvedObserver(this.panoIndex)\n if (!observer) return this.logWarning(`点位 ${this.panoIndex} 不存在,请检查 Five 数据是否正常。`)\n // 初始化依赖 work 的数据\n this.observer = observer\n // 初始化模型位姿\n const { x, y, z, w } = observer.quaternion\n const quaternion = new Quaternion(x, y, z, w)\n const position = observer.position\n this.videoMesh.position.fromArray([position.x, position.y, position.z])\n // 重置模型旋转\n this.videoMesh.quaternion.set(0, 0, 0, 1)\n // 绕 Y 轴逆时针旋转 90 度\n // 这里是因为历史问题,算法模块里面转了 90 度,所以前端也要转 90 度。\n // 后面可以联系 @饶童 一起改掉。\n this.videoMesh.rotateOnAxis(new Vector3(0, 1, 0), Math.PI / 2)\n // 应用点位旋转\n this.videoMesh.applyQuaternion(quaternion)\n }\n\n /** 兼容视频播放 */\n private onFiveWantsMoveToPano = (panoIndex: number) => {\n // 点位不匹配,不做任何操作。\n if (panoIndex !== this.panoIndex) return\n // 如果视频之前播放过,不用再做兼容\n if (this.hasVideoEverPlayed) return\n this.play(false, true).catch(() => {\n // 视频播放失败时,不做任何操作。\n })\n }\n\n /** 走到某个点位上时,挂载/卸载视频 */\n private onFivePanoArrived = (panoIndex: number) => {\n if (this.disposed) return this.logWarning('实例已被销毁')\n if (!this.enabled) return\n // 如果点位条件满足,挂载。\n if (this.panoIndex === panoIndex) this.mount()\n }\n\n private onFivePanoWillArrive = (panoIndex: number) => {\n // wantsMoveToPano 和 panoArrived 可能不是同一个点位,如果不一致,销毁副作用。\n if (panoIndex !== this.panoIndex) return this.unmount()\n if (this.panoIndex !== panoIndex) this.unmount()\n }\n\n /** Five 模型变化 */\n private onFiveModeChange = (mode: Mode) => {\n if (mode !== 'Panorama') this.hide()\n // Panorama 的判断在 onFiveInitAnimationEnded\n }\n\n /** Five mode change 动画结束 */\n private onFiveInitAnimationEnded = () => {\n const currentFiveState = this.five.getCurrentState()\n if (currentFiveState.mode === 'Panorama' && currentFiveState.panoIndex === this.panoIndex) this.mount()\n }\n\n /** Five Canvas 点击 */\n private onFiveWantsTapGesture = (raycaster: Raycaster) => {\n if (!this.five.scene.children.includes(this.videoMesh)) return\n if (this.disposed) return this.logWarning('实例已被销毁')\n if (!this.enabled) return this.logWarning('实例已被禁用')\n const [intersection] = raycaster.intersectObject(this.videoMesh)\n if (!intersection) return\n const isIntersectInVideo = this.checkIntersectionInBounding(this.origin, intersection)\n if (isIntersectInVideo) {\n const event = {\n target: this,\n _preventDefaultReturn: false,\n preventDefault: () => {\n event._preventDefaultReturn = true\n },\n }\n this.hooks.emit('click', event)\n if (event._preventDefaultReturn === false) {\n if (this.video.muted) this.unmute(true)\n else { this.mute() }\n }\n return false as const\n }\n }\n\n /** video canplaythrough 事件触发 */\n private onVideoDataLoaded = () => {\n this.videoDataLoaded = this.hasCurrentFrame()\n if (this.video.paused === false && this.video.src !== '') this.onVideoPlayingAndLoaded()\n }\n\n /** video playing 事件触发\n * @remarks\n * 事件触发时机:\n * - video is ready to start after having been paused.\n * - video is ready to play after delayed due to lack of data.\n * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video\n */\n private onVideoPlaying = () => {\n this.hasVideoEverPlayed = true\n // 空视频不能挂载。\n if (!this.enabled) return\n // A cached video can already have a frame without another canplaythrough.\n this.videoDataLoaded = this.hasCurrentFrame()\n if (this.videoDataLoaded) this.onVideoPlayingAndLoaded()\n }\n\n /** 触发 playing 和 canplaythrough */\n private onVideoPlayingAndLoaded = () => {\n if (!this.videoDataLoaded || !this.hasCurrentFrame() || this.video.paused) return\n this.video.removeEventListener('timeupdate', this.onVideoTimeUpdate)\n // Do not wait for Safari's throttled timeupdate after a decoded frame is ready.\n this.onVideoTimeUpdate()\n }\n\n private hasCurrentFrame() {\n return this.video.readyState >= 2 && this.video.videoWidth > 0 && this.video.videoHeight > 0\n }\n\n private onVideoTimeUpdate = () => {\n if (this.disposed || !this.enabled || this.video.paused || !this.hasCurrentFrame()) return\n if (this.panoIndex !== this.five.getCurrentState().panoIndex || this.five.getCurrentState().mode !== 'Panorama') return\n if (!this.renderFiveDisposer) {\n let lastVersion = this.videoTexture.version\n this.renderFiveDisposer = requestAnimationFrameInterval(() => {\n if (this.video.paused || !this.hasCurrentFrame()) return\n // Retry when Safari's frame callback has not advanced the texture.\n // Keep normal rVFC-driven uploads without adding another upload per tick.\n if (this.videoTexture.version === lastVersion) this.videoTexture.needsUpdate = true\n lastVersion = this.videoTexture.version\n this.five.needsRender = true\n }, 30)\n }\n this.videoTexture.needsUpdate = true\n this.five.needsRender = true\n this.five.scene.add(this.videoMesh)\n if (this.videoOpacity.value === 0) {\n this.fadeAnimation?.cancel()\n const opacity = { value: 0 }\n this.fadeAnimation = animate(opacity, {\n value: 1, duration: 300, ease: 'linear',\n onUpdate: () => { this.videoOpacity.value = opacity.value },\n onComplete: () => { this.videoOpacity.value = 1; this.fadeAnimation = undefined },\n })\n }\n }\n\n /** video pause 事件触发 */\n private onVideoPaused = () => {\n // The browser may queue pause before a newer play request has started.\n if (!this.video.paused) return\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n }\n\n private onVideoEmptied = () => {\n // A queued unload event may arrive after the replacement frame is ready.\n if (this.hasCurrentFrame()) return\n this.videoDataLoaded = false\n this.renderFiveDisposer?.()\n this.renderFiveDisposer = undefined\n this.fadeAnimation?.cancel()\n this.fadeAnimation = undefined\n this.videoOpacity.value = 0\n this.five.scene.remove(this.videoMesh)\n this.five.needsRender = true\n }\n\n private onVideoSeeked = () => {\n if (this.disposed || !this.enabled || !this.hasCurrentFrame()) return\n this.videoTexture.needsUpdate = true\n this.five.needsRender = true\n }\n\n /** 控制台打印警告 */\n private logWarning(meg: string) {\n console.warn(`⛔ ==> [VideoMeshController]:`, meg)\n }\n\n /** 检测射线与模型的交点是不是在视频的范围内 */\n private checkIntersectionInBounding(bounding: number[], target: Intersection) {\n if (!target.uv) return false\n const [u, v] = target.uv.toArray()\n const [minU, _minV, width, height] = bounding\n const minV = 1 - _minV - height\n const maxU = minU + width\n const maxV = minV + height\n return u >= minU && u <= maxU && v >= minV && v <= maxV\n }\n}\n","import type { PlaybackManager } from '../shared-utils/playback'\nimport type { Five } from '@realsee/five-webgpu'\nimport type { LoadParams, PluginEventMap, PluginState, PluginData, VideoItem } from './typings'\nimport { VideoMeshController } from './VideoMeshController'\nimport * as BasePlugin from '../base/BasePlugin'\n\nexport class PanoVideoPluginController extends BasePlugin.Controller<PluginState, PluginEventMap> {\n /** 插件 State */\n public get state() {\n return {\n enabled: this.enabled,\n }\n }\n\n /** 插件是否已被销毁 */\n public get disposed() {\n return this._disposed\n }\n\n public controllerMap: Map<string, VideoMeshController> = new Map()\n\n public data?: PluginData\n\n private enabled = true\n private _disposed = false\n private readonly removeFiveDisposeListener: () => void\n\n public constructor(five: Five, private options?: { mediaManager?: PlaybackManager }) {\n super(five)\n // Five emits dispose synchronously, before it releases the renderer.\n this.removeFiveDisposeListener = five.on('dispose', () => {\n try { this.dispose() } catch (error) {\n // Five must finish disposing its other resources and the renderer.\n console.error('[PanoVideoPluginController]: dispose failed', error)\n }\n })\n }\n\n /** 加载点位视频数据,加载数据并不代表会加载点位视频。 */\n public load(data: PluginData, params?: LoadParams) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (typeof params?.initialState?.enabled !== 'undefined' && params.initialState.enabled !== this.enabled) {\n params.initialState.enabled ? this.enable() : this.disable()\n }\n this.clear()\n // 初始化 controller 实例\n data.list.forEach((panoVideoItem) => {\n const panoIndex = panoVideoItem.pano_index\n const renderID = panoVideoItem.render_id\n panoVideoItem.video_list.forEach((videoItem) => {\n this.controllerMap.set(\n videoItem.render_id,\n new VideoMeshController(this.five, {\n mediaManager: this.options?.mediaManager,\n ...videoItem,\n fiveUtil: this.fiveUtil,\n panoIndex,\n renderID,\n hooks: this.hooks,\n initialState: { enabled: this.enabled },\n }),\n )\n })\n })\n\n this.data = data\n\n this.hooks.emit('dataLoaded', data)\n }\n\n /** 开启插件功能。 */\n public enable(options?: BasePlugin.BaseOptions) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (this.enabled) return\n this.enabled = true\n Array.from(this.controllerMap.values()).forEach((controller) => controller.enable())\n const userAction = options?.userAction ?? true\n this.hooks.emit('enable', { userAction })\n }\n\n /** 禁用插件功能。 */\n public disable(options?: BasePlugin.BaseOptions) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n if (!this.enabled) return\n this.enabled = false\n Array.from(this.controllerMap.values()).forEach((controller) => controller.disable())\n const userAction = options?.userAction ?? true\n this.hooks.emit('disable', { userAction })\n }\n\n /** 看向某个视频。\n * - 会自动切换到全景模式。\n * - 如果遇到不能自动播放的问题,需要放到用户交互事件中调用。\n */\n public lookAtVideoItemByRenderID(id: string) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.lookAtVideo()\n }\n\n /**\n * 取消静音。\n *\n * 大部分浏览器需要用户交互后才能开启视频声音。\n *\n * 如果需要取消静音,建议在用户交互事件中调用本方法。\n *\n * 例如:\n *\n * ```jsx\n * onClick={() => {\n * panoVideoPluginController.lookAtVideoItemByRenderID('xxx')\n * panoVideoPluginController.unmuteByRenderID('xxx')\n * }}\n * ```\n */\n public unmuteByRenderID(id: string, userAction = false) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.unmute(userAction)\n }\n\n /** 为一个点位添加视频(可以是多条)。 */\n public add(panoIndex: number, videoItems: VideoItem[]) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n videoItems.forEach((videoItem) => {\n if (this.controllerMap.get(videoItem.render_id)) return this.logWarning(`ID 为 ${videoItem.render_id} 的点位视频已存在`)\n const renderID = videoItem.render_id\n this.controllerMap.set(\n videoItem.render_id,\n new VideoMeshController(this.five, {\n mediaManager: this.options?.mediaManager,\n ...videoItem,\n fiveUtil: this.fiveUtil,\n panoIndex,\n renderID,\n hooks: this.hooks,\n initialState: { enabled: this.enabled },\n }),\n )\n })\n }\n\n /** 根据 VideoItem render_id 删除某个视频。 */\n public removeByRenderID(id: string) {\n if (this.disposed) return this.logWarning('插件已被销毁')\n const controller = this.controllerMap.get(id)\n if (!controller) return this.logWarning(`ID 为 ${id} 的点位视频不存在`)\n controller.dispose()\n this.controllerMap.delete(id)\n }\n\n /** 清空现有数据 */\n public clear() {\n if (this.disposed) return this.logWarning('插件已被销毁')\n this.releaseControllers()\n }\n\n /** 销毁插件 */\n public dispose() {\n if (this.disposed) return\n this._disposed = true\n this.removeFiveDisposeListener()\n this.releaseControllers()\n }\n\n private releaseControllers() {\n const controllers = Array.from(this.controllerMap.values())\n this.controllerMap.clear()\n // Retire every video even if a material disposal listener throws.\n const errors: unknown[] = []\n for (const controller of controllers) {\n try { controller.dispose() } catch (error) { errors.push(error) }\n }\n if (errors.length) throw errors[0]\n }\n\n /** 控制台打印警告 */\n // TODO: 全局函数 curry 化\n private logWarning(meg: string) {\n console.warn(`⛔ ==> [PanoVideoPluginController]:`, meg)\n }\n}\n","import type * as BasePlugin from '../base/BasePluginWithData'\nimport type { VideoMeshController } from './VideoMeshController'\n\n/** 单个视频元素 */\nexport interface VideoItem {\n /** client render ID\n * @remarks 为什么不用 id 作为唯一标识?\n * - id 是后端生成的,而 render_id 是前端生成的,在编辑时为了保证在请求后端数据之前也能进行渲染,使用额外的 id 进行渲染。\n * - 为了保证两端的数据一致性,插件里使用 render_id 作为唯一 ID。\n */\n render_id: string\n /** 文件地址 */\n url: string\n /** 算法处理的视频 uv 信息\n * @description [left, top, width, height]\n */\n origin: number[]\n}\n\n/** 点位视频元素 */\nexport interface PanoVideoItem {\n /** client render ID */\n render_id: string\n /** 视频播放点位 */\n pano_index: number\n /** 视频列表 */\n video_list: VideoItem[]\n}\n\n/** 点位视频模型参数 */\nexport interface VideoMeshParams {\n /** client render ID */\n renderID: string\n /** video 文件地址 */\n url: string\n /** 算法处理的视频 uv 信息\n * @description [left, top, width, height]\n */\n origin: number[]\n /** 视频播放点位 */\n panoIndex: number\n /** 初始状态 */\n initialState?: {\n enabled?: boolean\n }\n}\n\n/** 加载数据时的额外参数 */\nexport interface LoadParams {\n initialState?: {\n enabled?: boolean\n }\n}\n\nexport interface PluginState {\n enabled: boolean\n}\n\nexport interface PluginData {\n list: PanoVideoItem[]\n}\n\nexport interface PluginEventMap extends BasePlugin.EventMap<PluginState, PluginData> {\n /** 点位视频模型开启 */\n enable: (params: { userAction: boolean }) => void\n /** 点位视频模型关闭 */\n disable: (params: { userAction: boolean }) => void\n /** 点位视频被点击 */\n click: (event: { target: VideoMeshController; preventDefault: () => void }) => void\n}\n","import type { PlaybackManager } from '../shared-utils/playback'\nimport type { FivePlugin } from '@realsee/five-webgpu'\nimport { PanoVideoPluginController } from './Controller'\nimport * as _PanoVideoPluginType from './typings'\n\n/** 点位视频播放插件\n * - 支持一次性加载多组数据。\n * - 走到点位上时播放视频(可能是多个)。\n * - 走出点位时销毁视频。\n * - 允许动态开启和禁用功能。\n * - 视频只能在全景模式且点位一致时才会播放。不满足条件会自动销毁。\n * - 不做多媒体缓存,缓解内存占用。\n */\nexport const PanoVideoPlugin: FivePlugin<{ mediaManager?: PlaybackManager } | undefined, PanoVideoPluginController> = (five, options) => {\n return new PanoVideoPluginController(five, options)\n}\n\nexport { _PanoVideoPluginType as PanoVideoPluginType }\nexport type PanoVideoPluginParameterType = { mediaManager?: PlaybackManager } | undefined\nexport type PanoVideoPluginReturnType = InstanceType<typeof PanoVideoPluginController>\nexport default PanoVideoPlugin\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { n as t } from "./isNil-CQNA0Sbe.js";
3
3
  import { t as n } from "./BetterTween-DmptqE8m.js";
4
4
  import { i as r } from "./animationFrame-CacKXN8l.js";
5
5
  import { t as i } from "./equal-BiDAilPV.js";
6
- import { t as a } from "./BasePluginWithData-Cz_hCIai.js";
6
+ import { t as a } from "./BasePluginWithData-6nBdzY9e.js";
7
7
  import * as o from "three/webgpu";
8
8
  import { CubicBezierCurve3 as s, QuadraticBezierCurve3 as c } from "three/webgpu";
9
9
  //#region src/PipelinePlugin/utils/formatData.ts
@@ -383,4 +383,4 @@ var m = class extends o.Curve {
383
383
  //#endregion
384
384
  export { y as t };
385
385
 
386
- //# sourceMappingURL=pipeline-BqVMSO6-.js.map
386
+ //# sourceMappingURL=pipeline-CdRT0_qH.js.map