@realsee/vreo 1.0.0-alpha.9 → 1.1.0-dev.0

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 (132) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +46 -36
  3. package/lib/PlayController/index.js +1 -1
  4. package/lib/Player/Controller.d.ts +3 -2
  5. package/lib/Player/Controller.js +31 -14
  6. package/lib/Player/index.js +27 -16
  7. package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +2 -2
  8. package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +7 -12
  9. package/lib/Player/modules/VideoAgent/index.js +1 -1
  10. package/lib/Player/modules/Wave/index.js +160 -25
  11. package/lib/Player/modules/keyframes/BgMusic/index.js +52 -40
  12. package/lib/Player/modules/keyframes/PanoTag/index.js +1 -0
  13. package/lib/fivePlugins/CameraMovementPlugin/index.js +3 -2
  14. package/lib/shared-utils/Audio.d.ts +14 -0
  15. package/lib/shared-utils/Audio.js +158 -0
  16. package/lib/shared-utils/{AduioLike.d.ts → AudioLike.d.ts} +0 -0
  17. package/lib/shared-utils/{AduioLike.js → AudioLike.js} +4 -6
  18. package/lib/shared-utils/animationFrame/tween.d.ts +3 -58
  19. package/lib/shared-utils/animationFrame/tween.js +3 -9
  20. package/lib/typings/VreoUnit.d.ts +8 -5
  21. package/package.json +8 -6
  22. package/stylesheets/default.css +7 -2
  23. package/docs/.nojekyll +0 -1
  24. package/docs/assets/custom.css +0 -78
  25. package/docs/assets/highlight.css +0 -127
  26. package/docs/assets/icons.css +0 -1043
  27. package/docs/assets/icons.png +0 -0
  28. package/docs/assets/icons@2x.png +0 -0
  29. package/docs/assets/main.js +0 -52
  30. package/docs/assets/search.js +0 -1
  31. package/docs/assets/style.css +0 -1414
  32. package/docs/assets/widgets.png +0 -0
  33. package/docs/assets/widgets@2x.png +0 -0
  34. package/docs/classes/Player.AudioLike.html +0 -52
  35. package/docs/classes/Player.Controller.html +0 -54
  36. package/docs/classes/Player.Player-1.html +0 -50
  37. package/docs/classes/Player.VideoAgentMesh.html +0 -142
  38. package/docs/classes/Player.VideoAgentScene.html +0 -1
  39. package/docs/demo/assets/AppReact.6ca5d1d2.js +0 -1
  40. package/docs/demo/assets/default.5a762ce2.js +0 -3988
  41. package/docs/demo/assets/default.bc4c715d.css +0 -1
  42. package/docs/demo/assets/dynamic.efc5200d.js +0 -1
  43. package/docs/demo/assets/examples.80a27156.js +0 -25
  44. package/docs/demo/assets/examples.dac4a6fe.css +0 -1
  45. package/docs/demo/assets/index.9331038f.css +0 -1
  46. package/docs/demo/assets/index.ca7c5881.js +0 -1
  47. package/docs/demo/assets/main.c164d1d2.js +0 -1
  48. package/docs/demo/assets/react.2ee8565f.css +0 -1
  49. package/docs/demo/assets/react.a4774aef.js +0 -25
  50. package/docs/demo/assets/znRoyv06SZQeqA7m.0057e8ae.js +0 -1
  51. package/docs/demo/examples.html +0 -17
  52. package/docs/demo/index-react-dynamic.html +0 -20
  53. package/docs/demo/index-react.html +0 -20
  54. package/docs/demo/index.html +0 -19
  55. package/docs/enums/Player.InfoPanelStyleEnum.html +0 -1
  56. package/docs/enums/Player.InfoPanelTypeEnum.html +0 -3
  57. package/docs/enums/Player.PanoEffectEnum.html +0 -5
  58. package/docs/enums/Player.PanoTagEnum.html +0 -3
  59. package/docs/enums/Player.PanoTagStyleEnum.html +0 -7
  60. package/docs/enums/Player.VreoKeyframeEnum.html +0 -25
  61. package/docs/enums/fivePlugins.CameraMovementEffect.html +0 -1
  62. package/docs/enums/fivePlugins.Rotation.html +0 -1
  63. package/docs/index.html +0 -245
  64. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +0 -1
  65. package/docs/interfaces/Player.PlayerConfigs.html +0 -7
  66. package/docs/interfaces/Player.Vertex.html +0 -3
  67. package/docs/interfaces/Player.VideoAgentMeshOptions.html +0 -8
  68. package/docs/interfaces/Player.VreoKeyframe.html +0 -3
  69. package/docs/interfaces/Player.VreoUnit.html +0 -3
  70. package/docs/interfaces/Player.VreoVideo.html +0 -3
  71. package/docs/interfaces/fivePlugins.CSS3DRenderPluginExportType.html +0 -4
  72. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +0 -1
  73. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +0 -7
  74. package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +0 -1
  75. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +0 -1
  76. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +0 -1
  77. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +0 -1
  78. package/docs/interfaces/fivePlugins.Vector3Position.html +0 -3
  79. package/docs/interfaces/react.VreoActionCallbacks.html +0 -23
  80. package/docs/interfaces/react.VreoProviderProps.html +0 -1
  81. package/docs/modules/Player.html +0 -37
  82. package/docs/modules/custom.html +0 -3
  83. package/docs/modules/fivePlugins.html +0 -6
  84. package/docs/modules/react.html +0 -1
  85. package/docs/modules.html +0 -1
  86. package/resources/PlayController/createHTMLAudioElement.ts +0 -53
  87. package/resources/PlayController/index.ts +0 -154
  88. package/resources/Player/App.tsx +0 -66
  89. package/resources/Player/Controller.ts +0 -294
  90. package/resources/Player/custom/SpatialScenePanel/index.tsx +0 -264
  91. package/resources/Player/hooks.ts +0 -26
  92. package/resources/Player/index.tsx +0 -227
  93. package/resources/Player/modules/Drawer/index.tsx +0 -40
  94. package/resources/Player/modules/PopUp/index.tsx +0 -26
  95. package/resources/Player/modules/ResizeObserver/index.tsx +0 -23
  96. package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +0 -302
  97. package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +0 -56
  98. package/resources/Player/modules/VideoAgent/index.tsx +0 -53
  99. package/resources/Player/modules/Wave/index.tsx +0 -18
  100. package/resources/Player/modules/keyframes/BgMusic/index.tsx +0 -66
  101. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +0 -37
  102. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +0 -165
  103. package/resources/Player/modules/keyframes/ModelVideo/index.tsx +0 -77
  104. package/resources/Player/modules/keyframes/PanoEffect/index.tsx +0 -99
  105. package/resources/Player/modules/keyframes/PanoEffect/lineAnime.ts +0 -31
  106. package/resources/Player/modules/keyframes/PanoTag/index.tsx +0 -82
  107. package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +0 -117
  108. package/resources/Player/modules/keyframes/Prompter/index.tsx +0 -56
  109. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +0 -99
  110. package/resources/Player/modules/keyframes/VideoEffect/index.tsx +0 -115
  111. package/resources/Player/typings.ts +0 -49
  112. package/resources/fivePlugins/CSS3DRenderPlugin/centerPoint.ts +0 -5
  113. package/resources/fivePlugins/CSS3DRenderPlugin/createResizeObserver.ts +0 -17
  114. package/resources/fivePlugins/CSS3DRenderPlugin/evenNumber.ts +0 -4
  115. package/resources/fivePlugins/CSS3DRenderPlugin/index.ts +0 -254
  116. package/resources/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.ts +0 -5
  117. package/resources/fivePlugins/CameraMovementPlugin/index.ts +0 -226
  118. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +0 -59
  119. package/resources/fivePlugins/ModelTVVideoPlugin/index.ts +0 -278
  120. package/resources/index.ts +0 -1
  121. package/resources/react/index.tsx +0 -121
  122. package/resources/shared-utils/AduioLike.ts +0 -109
  123. package/resources/shared-utils/Preloader.ts +0 -35
  124. package/resources/shared-utils/addResizeListener.ts +0 -46
  125. package/resources/shared-utils/animationFrame/BetterTween.ts +0 -33
  126. package/resources/shared-utils/animationFrame/index.ts +0 -48
  127. package/resources/shared-utils/animationFrame/tween.ts +0 -51
  128. package/resources/shared-utils/createTransMatrix.ts +0 -12
  129. package/resources/shared-utils/getFileExpandedName.ts +0 -6
  130. package/resources/shared-utils/getMediaInfo.ts +0 -52
  131. package/resources/shared-utils/setElementDataset.ts +0 -18
  132. package/resources/typings/VreoUnit.ts +0 -314
@@ -1,99 +0,0 @@
1
- import * as React from 'react'
2
- import { parseWork, Work } from '@realsee/five'
3
- import { useController, useFiveInstance } from '../../../hooks'
4
- import { UpdateVRPanoramaData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
-
6
- export function UpdateVRPanorama() {
7
- const controller = useController()
8
- const five = useFiveInstance()
9
- const deafultWorkRef = React.useRef<string[] | null>(null)
10
- const updateWorkRef = React.useRef<Work | null>(null)
11
-
12
- // 恢复默认 VR
13
- const restoreCallback = React.useCallback(() => {
14
- // 先清理掉 之前的 VR 数据备份
15
- updateWorkRef.current = null
16
-
17
- if (deafultWorkRef.current) {
18
- const work = parseWork(deafultWorkRef.current)
19
- five.load(work)
20
- }
21
-
22
- }, [])
23
-
24
- // 暂停时: 恢复默认 VR
25
- const pausedCallback = React.useCallback(() => {
26
- if (deafultWorkRef.current) {
27
- const work = parseWork(deafultWorkRef.current)
28
- Object.assign(window, {$rawWork: work})
29
- five.load(work)
30
- }
31
- }, [])
32
-
33
- // 播放时:如果暂停前有更新 VR 需要还原
34
- const playingCallback = React.useCallback(() => {
35
- if (!updateWorkRef.current) {
36
- return
37
- }
38
- five.load(updateWorkRef.current)
39
- }, [])
40
-
41
- React.useEffect(() => {
42
- const callback = (keyframe: VreoKeyframe) => {
43
- if (!deafultWorkRef.current) {
44
- deafultWorkRef.current = five.work.raw.works
45
- }
46
-
47
- const data = keyframe.data as UpdateVRPanoramaData
48
-
49
- // 如果数据中有新 work 数据,则直接载入
50
- if (data.work) {
51
- updateWorkRef.current = parseWork(data.work)
52
- five.load(updateWorkRef.current)
53
- return
54
- }
55
-
56
- const lastRawWork = five.work?.raw.works[0]
57
-
58
-
59
- // 动态场景:不提供完成的签名数据,需重新整理
60
- if (data.dynamic_scene && !data.panorama) {
61
- const lastWork = JSON.parse(lastRawWork)
62
- const panorama = lastWork.panorama
63
- const index = data.dynamic_scene.images.index
64
- panorama.list[index] = data.dynamic_scene.images
65
- data.panorama = panorama
66
- delete data.dynamic_scene
67
- }
68
-
69
- Object.assign(window, {$work1: JSON.parse(lastRawWork), $work2: data, parseWork: parseWork})
70
-
71
- updateWorkRef.current = parseWork([lastRawWork, data])
72
- five.load(updateWorkRef.current)
73
- }
74
-
75
- controller.on(VreoKeyframeEnum.UpdateVRPanorama, callback)
76
-
77
- // 离开 将之前的内容清空
78
- controller.on(VreoKeyframeEnum.Exit, restoreCallback)
79
-
80
- // 新载入数据 将之前的内容清空
81
- controller.on('loaded', restoreCallback)
82
-
83
- // 暂停 回到默认状态
84
- controller.on('paused', pausedCallback)
85
- // 播放 回归暂停前状态
86
- controller.on('playing', playingCallback)
87
-
88
- return () => {
89
- // 清理事件监听
90
- controller.off(VreoKeyframeEnum.UpdateVRPanorama, callback)
91
- controller.off(VreoKeyframeEnum.Exit, restoreCallback)
92
- controller.off('loaded', restoreCallback)
93
- controller.off('paused', pausedCallback)
94
- controller.off('playing', playingCallback)
95
- }
96
- }, [])
97
-
98
- return <></>
99
- }
@@ -1,115 +0,0 @@
1
- import classNames from 'classnames'
2
- import * as React from 'react'
3
- // import { Preloader } from '../../../../shared-utils/Preloader'
4
- import { VideoEffectData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
5
- import { useController, useFiveInstance } from '../../../hooks'
6
-
7
- const inlinePlay = (videoInstance?: HTMLVideoElement | null) => {
8
- if (!videoInstance) return
9
- const canplaythrough = () => {
10
- videoInstance.removeEventListener('canplaythrough', canplaythrough)
11
- try {
12
- videoInstance.play()
13
- } catch (error) {}
14
- }
15
- videoInstance.addEventListener('canplaythrough', canplaythrough)
16
- videoInstance.load()
17
- }
18
-
19
- // const emptyVideo = '//vrlab-static.ljcdn.com/release/web/leisure.69fd3522.mov'
20
- const PI = Math.PI
21
- const PI_2 = PI * 2
22
-
23
- export function VideoEffect() {
24
- const ref = React.useRef<HTMLDivElement>(null)
25
- const videoRef = React.useRef<HTMLVideoElement | null>()
26
- const controller = useController()
27
- const timeoutRef = React.useRef<NodeJS.Timeout | null>()
28
-
29
- const [visible, setVisible] = React.useState(false)
30
- const five = useFiveInstance()
31
- const setBlobSrc = (blob: string) => {
32
- if (!videoRef.current) return
33
-
34
- videoRef.current.src = blob
35
- }
36
-
37
- React.useEffect(() => {
38
- const callback = async (keyframe: VreoKeyframe) => {
39
- const { start, end } = keyframe
40
- const { videoSrc, fov, direction, panoIndex, vector } = keyframe.data as VideoEffectData
41
- const [longitude, latitude] = (() => {
42
- if (vector) {
43
- return [vector.longitude, vector.latitude]
44
- }
45
- if (!direction) {
46
- return [0, 0]
47
- }
48
-
49
- let longitude = -Math.atan2(direction.x, -direction.z)
50
- longitude = ((longitude % PI_2) + PI_2) % PI_2
51
- const latitude = -Math.asin(direction.y / 1)
52
- return [longitude, latitude]
53
- })()
54
-
55
- five.setState({ fov, panoIndex, longitude, latitude }, true)
56
- setBlobSrc(videoSrc)
57
-
58
- inlinePlay(videoRef.current)
59
- setVisible(true)
60
-
61
- timeoutRef.current = setTimeout(() => {
62
- if (!videoRef.current?.paused) {
63
- videoRef.current?.pause()
64
- }
65
- setVisible(false)
66
- setBlobSrc('')
67
- }, end - start)
68
- }
69
-
70
- controller.on(VreoKeyframeEnum.VideoEffect, callback)
71
- return () => {
72
- controller.off(VreoKeyframeEnum.VideoEffect, callback)
73
- if (timeoutRef.current) {
74
- clearTimeout(timeoutRef.current)
75
- }
76
- }
77
- }, [controller])
78
-
79
- React.useEffect(() => {
80
- if (!ref.current) return
81
- const video = controller.configs?.videos?.videoEffect || document.createElement('video')
82
- // <video playsInline key="VideoEffect-video" className="VideoEffect-video" src={blobSrc} />
83
- video.setAttribute('playsinline', 'true')
84
- video.setAttribute('webkit-playsinline', 'true')
85
- video.setAttribute('autoplay', 'true')
86
- video.setAttribute('key', 'VideoEffect-video')
87
- video.setAttribute('class', 'VideoEffect-video')
88
-
89
- videoRef.current = video
90
- ref.current.append(videoRef.current)
91
- document.addEventListener(
92
- 'WeixinJSBridgeReady',
93
- function () {
94
- videoRef.current?.play()
95
- },
96
- false
97
- )
98
-
99
- if (!ref.current) return
100
- // const asyncfunc = async () => {
101
- // setBlobSrc(await URL.createObjectURL(await Preloader.blob(emptyVideo)))
102
- // inlinePlay(videoRef.current)
103
- // }
104
- // asyncfunc()
105
- }, [])
106
-
107
- return (
108
- <div
109
- ref={ref}
110
- className={classNames('VideoEffect', {
111
- 'VideoEffect--visible': visible,
112
- })}
113
- ></div>
114
- )
115
- }
@@ -1,49 +0,0 @@
1
- import React, { ReactNode } from 'react';
2
- import { Subscribe, Five } from '@realsee/five';
3
-
4
- import { VreoKeyframeConfigMap, VreoKeyframeEvent } from '../typings/VreoUnit'
5
- import { VideoAgentMeshOptions } from './modules/VideoAgent/VideoAgentMesh';
6
-
7
- export interface PlayerConfigs {
8
- /**
9
- * @deprecated rename to container
10
- */
11
- containter?: Element
12
- container?: Element
13
- keyframeMap: VreoKeyframeConfigMap
14
- /**
15
- * 微信端自动播放功能实现需要提前初始化 Video 实例。
16
- *
17
- * 如果需要支持微信浏览器端自动播放需要接入微信SDK及提前初始化好相关 Video 实例。
18
- */
19
- videos?: {
20
- videoEffect?: HTMLVideoElement
21
- modelTVVideo?: HTMLVideoElement
22
- }
23
-
24
- videoAgentMeshOptions?: VideoAgentMeshOptions
25
- /**
26
- * 如果需要在 底部面板添加自定义内容,可以传递个 React 组件。
27
- */
28
- customPanelChildren?: ReactNode
29
- customKeyframes?: React.FC<CustomVreoKeyframeProps>[]
30
- imageOptions?: { size: number }
31
- autoPreload?: boolean
32
- appSize?: AppSize
33
- appearance?: Appearance
34
- }
35
-
36
- export type AppSize = 'S' | 'M' | 'L' | 'XL'
37
-
38
- export type WaveAppearance = 'single' | 'double' | 'solid' | 'swap' | 'expand'
39
-
40
- export interface Appearance {
41
- waveStyle?: 'wave' | 'solid'
42
- }
43
-
44
- export type VreoSubscribe = Pick<Subscribe<VreoKeyframeEvent>, 'on' | 'once' | 'off'>
45
-
46
- export interface CustomVreoKeyframeProps {
47
- subscribe: VreoSubscribe
48
- five: Five
49
- }
@@ -1,5 +0,0 @@
1
- import { Vector3 } from 'three'
2
-
3
- export default function centerPoint(point1: Vector3, point2: Vector3): Vector3 {
4
- return new Vector3((point1.x + point2.x) / 2, (point1.y + point2.y) / 2, (point1.z + point2.z) / 2)
5
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * @description: 简陋的 ResizeObserver polyfill
3
- */
4
- export default function createResizeObserver(func: () => any, element?: HTMLElement) {
5
- if (!element || typeof ResizeObserver === 'undefined') {
6
- return {
7
- observe: () => window.addEventListener('resize', func),
8
- unobserve: () => window.removeEventListener('resize', func),
9
- }
10
- } else {
11
- const observer = new ResizeObserver(func)
12
- return {
13
- observe: () => observer.observe(element),
14
- unobserve: () => observer.unobserve(element),
15
- }
16
- }
17
- }
@@ -1,4 +0,0 @@
1
- export default function evenNumber(num: number, config?: { smaller?: boolean }): number {
2
- const roundNum = Math.round(num)
3
- return roundNum % 2 === 0 ? roundNum : roundNum + Number(config?.smaller ? -1 : 1)
4
- }
@@ -1,254 +0,0 @@
1
- import { FivePlugin } from '@realsee/five'
2
- import * as THREE from 'three'
3
- import { Scene, Vector3 } from 'three'
4
- import { CSS3DObject, CSS3DRenderer } from 'three/examples/jsm/renderers/CSS3DRenderer'
5
- import evenNumber from './evenNumber'
6
- import centerPoint from './centerPoint'
7
- import transformPositionToVector3 from './transformPositionToVector3'
8
- import createResizeObserver from './createResizeObserver'
9
-
10
- /**
11
- * 三维向量
12
- */
13
- export interface Vector3Position {
14
- x: number
15
- y: number
16
- z: number
17
- }
18
-
19
- export type CSS3DRenderPluginParameterType = undefined
20
- export interface CSS3DRenderPluginExportType {
21
- /**
22
- * @description: 根据传入的四个点位创建一个3d dom容器,可以通过ReactDom.render()的方式将react组件放到容器中
23
- * @param {Five} five
24
- * @param {Vector3[] | Vector3Position[]} points: 矩形四个点坐标
25
- * @param {number} config.ratio: 1px对应多少米,默认为 0.002,即1px对应2mm
26
- * @param {number} config.dpr: dpr, 默认为1
27
- * @param {HTMLElement} config.container: HTMLElement
28
- * @param {number} config.autoRender: 默认为true,如果需要手动render则传false
29
- * @param {'front' | 'behind'} config.mode: 两种模式
30
- * @param {HTMLElement} config.behindFiveContainer: 如果config.mode为'behind',需要传入容器,并确保此容器位five下方,且中间没有其他dom元素遮挡
31
- * @return {{ container: HTMLElement; dispose: () => void }}: container: dom容器, dispose: 清理函数
32
- */
33
- create3DDomContainer: (
34
- points: Vector3[] | Vector3Position[],
35
- config?: { ratio?: number; dpr?: number; autoRender?: boolean; container?: HTMLElement; [key: string]: any } & (
36
- | { mode?: 'front' }
37
- | { mode: 'behind'; behindFiveContainer: HTMLElement }
38
- ),
39
- ) => { container: HTMLElement; dispose: () => void; css3DObject: CSS3DObject; render?: () => void } | void
40
-
41
- /**
42
- * @description: 销毁所有的渲染内容
43
- * @return {void}
44
- */
45
- disposeAll: () => void
46
- }
47
-
48
- type Create3DDomContainerInterface = CSS3DRenderPluginExportType['create3DDomContainer']
49
- type Create3DDomContainerConfigInterface = NonNullable<Parameters<Create3DDomContainerInterface>[1]>
50
- interface CSS3DRenderPluginState {
51
- disposeCallbacks: (() => boolean)[]
52
- frontMode?: {
53
- scene: Scene
54
- css3DRenderer: CSS3DRenderer
55
- }
56
- behindMode?: {
57
- scene: Scene
58
- css3DRenderer: CSS3DRenderer
59
- }
60
- }
61
-
62
- /**
63
- * **CSS3DRenderPlugin** 提供矩形区域(三维空间四个坐标点),你可以在此矩形区域中渲染 DOM 内容。
64
- * 实现原理参考[CSS3DRenderer](https://threejs.org/docs/index.html?q=CSS3D#examples/en/renderers/CSS3DRenderer)。
65
- *
66
- * @returns
67
- */
68
- export const CSS3DRenderPlugin: FivePlugin<CSS3DRenderPluginParameterType, CSS3DRenderPluginExportType> = (five) => {
69
- const state: CSS3DRenderPluginState = { disposeCallbacks: [] }
70
- const create3DDomContainer = (
71
- ...params: Parameters<Create3DDomContainerInterface>
72
- ): ReturnType<Create3DDomContainerInterface> => {
73
- const points = params[0].map((point) => (point instanceof Vector3 ? point : transformPositionToVector3(point)))
74
- const config = params[1]
75
- if (points?.length < 4) return console.error('points must be equal or greater than than 4')
76
- if (!five?.model?.loaded) return console.error('five.model.loaded is: ', five?.model?.loaded)
77
- const fiveElement = five.getElement()
78
- if (!fiveElement) return console.error('five.getElement() is ' + fiveElement)
79
-
80
- const disposers: any[] = []
81
- const ratio = config?.ratio || 0.00216
82
- if (ratio <= 0.00215) console.warn('if you need click css3DElement on safari, ratio must be greater than 0.00215')
83
- const dpr = config?.dpr || 1
84
- const mode = config?.mode || 'front'
85
- const autoRender = config?.autoRender ?? true
86
- const behindFiveContainer = config?.behindFiveContainer || fiveElement.parentElement || document.body
87
- const container = config?.container || document.createElement('div')
88
- container.classList.add('__Vreo-plugin--CSS3DRenderPlugin')
89
-
90
- // 获取css3DObject, 如果mode为behind的话,一起获取mesh
91
- const { css3DObject, mesh } = createObject(points, { ratio, dpr, container, mode })
92
-
93
- // ======= INIT START =======
94
- let resizeObserver:
95
- | {
96
- observe?: () => void
97
- unobserve?: () => void
98
- }
99
- | undefined
100
- const frontModeUnInited = mode === 'front' && !state.frontMode
101
- const behindModeUnInited = mode === 'behind' && !state.behindMode
102
- const inited = !(frontModeUnInited || behindModeUnInited)
103
- let stopRenderFlag = false
104
- let requestAnimationFrameId: number | null = null
105
-
106
- if (behindModeUnInited) {
107
- state.behindMode = { scene: new Scene(), css3DRenderer: new CSS3DRenderer() }
108
- }
109
- if (frontModeUnInited) {
110
- state.frontMode = { scene: new Scene(), css3DRenderer: new CSS3DRenderer() }
111
- }
112
- const { scene, css3DRenderer } = mode === 'behind' ? state.behindMode! : state.frontMode!
113
-
114
- const render = (() => {
115
- if (!inited) {
116
- const css3DRendererSetSize = () => {
117
- // 这里evenNumber策略是遇到奇数会加1,不知道为啥会触发滚动条显示,导致fiveElement变小,fiveElement变小又触发了这里的resize,宽高变小,滚动条消失,然后又触发resize。。。无限循环
118
- // 为了规避上面这种情况,evenNumber设置了一个参数,遇到奇数可选择减一
119
- const rendererWidth = evenNumber(fiveElement.clientWidth, { smaller: true })
120
- const rendererHeight = evenNumber(fiveElement.clientHeight, { smaller: true })
121
- css3DRenderer.setSize(rendererWidth, rendererHeight)
122
- }
123
- css3DRendererSetSize()
124
- resizeObserver = createResizeObserver(css3DRendererSetSize, fiveElement)
125
- css3DRenderer.domElement.style.position = 'absolute'
126
- css3DRenderer.domElement.style.top = '0'
127
- css3DRenderer.domElement.style.userSelect = 'none'
128
- css3DRenderer.domElement.style.pointerEvents = 'none'
129
-
130
- const renderEveryFrame = () => {
131
- if (stopRenderFlag) return
132
- requestAnimationFrameId = requestAnimationFrame(renderEveryFrame)
133
- css3DRenderer.render(scene!, five.camera)
134
- }
135
- return () => {
136
- scene.add(css3DObject)
137
- resizeObserver?.observe?.()
138
- renderEveryFrame()
139
- if (mode === 'behind' && mesh) {
140
- five.scene.add(mesh)
141
- disposers.push(() => mesh && five.scene.remove(mesh))
142
- }
143
- }
144
- } else {
145
- return () => {
146
- scene.add(css3DObject)
147
- }
148
- }
149
- })()
150
- if (frontModeUnInited) {
151
- const wrapper = fiveElement.parentElement || document.body
152
- wrapper.appendChild(css3DRenderer.domElement)
153
- }
154
- if (behindModeUnInited) {
155
- const wrapper = behindFiveContainer
156
- wrapper.appendChild(css3DRenderer.domElement)
157
- }
158
- // ======= INIT END =======
159
-
160
- const dispose = () => {
161
- stopRenderFlag = true
162
- disposers.forEach((d) => d?.())
163
- scene.remove(css3DObject)
164
- if (typeof requestAnimationFrameId === 'number') cancelAnimationFrame(requestAnimationFrameId)
165
- if (scene.children.length === 0) {
166
- css3DRenderer.domElement.remove()
167
- if (mode === 'front') state.frontMode = undefined
168
- if (mode === 'behind') state.behindMode = undefined
169
- if (!state.behindMode && !state.frontMode) {
170
- resizeObserver?.unobserve?.()
171
- }
172
- }
173
- return true
174
- }
175
- const idx = state.disposeCallbacks.findIndex((item) => item === dispose)
176
- if (idx !== -1) {
177
- state.disposeCallbacks.splice(idx, 1)
178
- } else {
179
- state.disposeCallbacks.push(dispose)
180
- }
181
-
182
- if (autoRender) render()
183
- return { container, dispose, css3DObject, render: autoRender ? undefined : render }
184
- }
185
-
186
- const createObject = (
187
- points: Vector3[],
188
- config: Required<Pick<Create3DDomContainerConfigInterface, 'ratio' | 'dpr' | 'container'>> &
189
- Pick<Create3DDomContainerConfigInterface, 'mode'>,
190
- ) => {
191
- const { ratio, dpr, container: element, mode } = config
192
- const planeWidth = points[0].distanceTo(points[1])
193
- const planeHeight = points[1].distanceTo(points[2])
194
- const domWidthPx = evenNumber((planeWidth / ratio) * dpr)
195
- const domHeightPx = evenNumber((planeHeight / ratio) * dpr)
196
-
197
- const css3DObject = new CSS3DObject(element)
198
- css3DObject.scale.set(ratio, ratio, ratio)
199
- element.style.width = domWidthPx + 'px'
200
- element.style.height = domHeightPx + 'px'
201
- element.style.pointerEvents = 'none'
202
-
203
- const centerPosition = centerPoint(points[0], points[2])
204
-
205
- const vector01 = points[1].clone().sub(points[0]) // 点0 -> 点1 的向量
206
- const vector12 = points[2].clone().sub(points[1]) // 点1 -> 点2 的向量
207
-
208
- // 旋转
209
- const rotateXAngle = new Vector3(0, 1, 0).angleTo(new Vector3(0, vector12.y, vector12.z))
210
- const rotateYAngle = new Vector3(1, 0, 0).angleTo(new Vector3(vector01.x, 0, vector01.z))
211
- const rotateZAngle = vector01.angleTo(new Vector3(vector01.x, 0, vector01.z))
212
- /**
213
- * [0,1,0] => [0,0,1] 为rolate Worldx正方向
214
- * [0,0,1] => [0,1,0] 为rolate Worldy正方向
215
- * [0,1,1] => [-1,0,0] 为rolate Worldz正方向
216
- */
217
- const rotateX = (vector12.z > 0 ? -1 : 1) * rotateXAngle
218
- const rotateY = (vector01.z < 0 ? 1 : -1) * rotateYAngle
219
- const rotateZ = ((vector01.x > 0 && vector01.y < 0) || (vector01.x < 0 && vector01.y > 0) ? -1 : 1) * rotateZAngle
220
-
221
- css3DObject.rotateOnWorldAxis(new Vector3(1, 0, 0), rotateX) // x
222
- css3DObject.rotateOnWorldAxis(new Vector3(0, 1, 0), rotateY) // y
223
- css3DObject.rotateOnWorldAxis(new Vector3(0, 0, 1), rotateZ) // z
224
-
225
- css3DObject.position.set(centerPosition.x, centerPosition.y, centerPosition.z)
226
-
227
- let mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial> | undefined
228
- if (mode === 'behind') {
229
- const material = new THREE.MeshBasicMaterial({
230
- opacity: 0,
231
- transparent: false,
232
- side: THREE.DoubleSide,
233
- })
234
- const geometry = new THREE.PlaneGeometry(domWidthPx, domHeightPx)
235
- mesh = new THREE.Mesh(geometry, material)
236
- mesh.name = 'CSS3DRenderPlugin-mesh'
237
- mesh.position.copy(css3DObject.position)
238
- mesh.rotation.copy(css3DObject.rotation)
239
- mesh.scale.copy(css3DObject.scale)
240
- }
241
-
242
- return { css3DObject, mesh }
243
- }
244
-
245
- return {
246
- create3DDomContainer,
247
- disposeAll: () => {
248
- state.disposeCallbacks.forEach((d) => d?.())
249
- state.disposeCallbacks = []
250
- },
251
- }
252
- }
253
-
254
- export default CSS3DRenderPlugin
@@ -1,5 +0,0 @@
1
- import { Vector3 } from 'three'
2
-
3
- const transformPositionToVector3 = ({ x, y, z }: { x: number; y: number; z: number }) => new Vector3(x, y, z)
4
-
5
- export default transformPositionToVector3