@operato/board 10.0.0-beta.2 → 10.0.0-beta.21
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.
- package/CHANGELOG.md +175 -0
- package/dist/src/data-storage/board-model-cache.d.ts +30 -0
- package/dist/src/data-storage/board-model-cache.js +93 -0
- package/dist/src/data-storage/board-model-cache.js.map +1 -0
- package/dist/src/graphql/playback-subscription.d.ts +74 -0
- package/dist/src/graphql/playback-subscription.js +191 -0
- package/dist/src/graphql/playback-subscription.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/modeller/edit-toolbar-style.js +38 -1
- package/dist/src/modeller/edit-toolbar-style.js.map +1 -1
- package/dist/src/modeller/edit-toolbar.d.ts +7 -16
- package/dist/src/modeller/edit-toolbar.js +197 -199
- package/dist/src/modeller/edit-toolbar.js.map +1 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.d.ts +2 -1
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js +7 -11
- package/dist/src/modeller/scene-viewer/ox-scene-viewer.js.map +1 -1
- package/dist/src/ox-board-modeller.d.ts +5 -1
- package/dist/src/ox-board-modeller.js +82 -5
- package/dist/src/ox-board-modeller.js.map +1 -1
- package/dist/src/ox-board-viewer.d.ts +50 -1
- package/dist/src/ox-board-viewer.js +269 -25
- package/dist/src/ox-board-viewer.js.map +1 -1
- package/dist/src/ox-playback-controls.d.ts +48 -0
- package/dist/src/ox-playback-controls.js +419 -0
- package/dist/src/ox-playback-controls.js.map +1 -0
- package/dist/src/selector/ox-board-selector.js +11 -1
- package/dist/src/selector/ox-board-selector.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-board-modeller.js","sourceRoot":"","sources":["../../src/ox-board-modeller.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/fab/fab.js'\nimport '@hatiolab/things-scene'\nimport './modeller/scene-viewer/ox-scene-handler.js'\nimport './modeller/scene-viewer/ox-scene-layer.js'\nimport './modeller/scene-viewer/ox-scene-property.js'\nimport './modeller/scene-viewer/ox-scene-viewer.js'\nimport './ox-board-viewer.js'\n\nimport { saveAs } from 'file-saver'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { MODE_EDIT, Scene, SCENE_MODE, SceneMode } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPopup } from '@operato/popup'\nimport { isMacOS, togglefullscreen } from '@operato/utils'\n\nimport { ComponentToolbar } from './modeller/component-toolbar/component-toolbar.js'\nimport { EditToolbar } from './modeller/edit-toolbar.js'\nimport { PropertySidebar } from './modeller/property-sidebar.js'\nimport { ComponentGroup, ComponentTemplate } from './types.js'\nimport OxSceneViewer from './modeller/scene-viewer/ox-scene-viewer.js'\n\nconst MACOS = isMacOS()\n\nconst ICON_HTOOLBAR = new URL('../../icons/icon-htoolbar.png', import.meta.url).href\nconst ICON_FULLSCREEN = new URL('../../icons/icon-fullscreen.png', import.meta.url).href\nconst ICON_COLLAPSE = new URL('../../icons/icon-collapse.png', import.meta.url).href\nconst ICON_COLLAPSE_ACTIVE = new URL('../../icons/icon-collapse-active.png', import.meta.url).href\n\nvar Registry: ComponentGroup[] = []\n\n@customElement('ox-board-modeller')\nexport class BoardModeller extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n height: 100%;\n overflow: hidden;\n }\n\n edit-toolbar {\n flex: 45px;\n max-height: 45px;\n }\n\n div[content] {\n flex: 1;\n max-height: calc(100% - 45px);\n\n display: flex;\n flex-direction: row;\n }\n\n component-toolbar {\n max-height: 100%;\n }\n\n property-sidebar {\n overflow: hidden;\n }\n\n #scene-wrap {\n position: relative;\n\n flex: 1;\n display: flex;\n flex-direction: row;\n }\n\n ox-scene-viewer {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n\n md-fab {\n position: absolute;\n right: 15px;\n bottom: 15px;\n z-index: 1000;\n }\n\n ox-popup {\n width: 90%;\n height: 90%;\n left: 50%;\n top: 50%;\n transform: translateX(-50%) translateY(-50%);\n background: var(--md-sys-color-on-secondary-container, black);\n\n display: flex;\n justify-content: center;\n flex-direction: column;\n }\n\n ox-board-viewer {\n width: 98%;\n height: 98%;\n margin: auto;\n padding: 0;\n }\n `\n ]\n\n static registerGroup(group: ComponentGroup) {\n var found = Registry.find(inRegisterGroup => inRegisterGroup.name == group.name)\n\n if (found) {\n found = {\n ...found,\n ...group\n }\n } else {\n Registry.push(group)\n }\n }\n\n static registerTemplate(templates: ComponentTemplate[]): void {\n templates &&\n templates.forEach(template => {\n var groups: string[] = typeof template.group == 'string' ? [template.group] : template.group\n\n Registry.filter(group => groups.includes(group.name)).forEach(group => {\n if (!group.templates.find(inGroupTemplate => inGroupTemplate.type == template.type)) {\n group.templates.push(template)\n }\n })\n })\n }\n\n static get groups(): ComponentGroup[] {\n return Registry\n }\n\n static getGroup(name: string) {\n return Registry.find(group => group.name === name)\n }\n\n @property({ type: String }) boardName: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: String }) baseUrl: string = ''\n @property({ type: Array }) selected: any[] = []\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n @property({ type: Object }) provider: any = null\n @property({ type: Boolean }) hideProperty: boolean = false\n @property({ type: String }) overlay: string = ''\n @property({ type: Object }) scene?: Scene\n @property({ type: Array }) componentGroupList: any[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n\n @query('edit-toolbar') private editToolbar!: EditToolbar\n @query('ox-scene-viewer') private viewer!: OxSceneViewer\n\n private group: string = ''\n private shortcutHandler?: (e: KeyboardEvent) => void\n\n constructor() {\n super()\n\n document.addEventListener('get-all-scene-component-ids', (e: Event) => {\n var { component, callback } = (e as CustomEvent).detail\n\n if (!this.scene) return\n\n var ids\n if (component) {\n ids = this.scene.findAll(component).map((c: any) => c.model.id)\n } else {\n // @ts-ignore\n ids = this.scene.ids.map(({ key }) => key)\n }\n\n ids = ids.filter(Boolean).sort()\n callback(ids)\n })\n\n this.style.setProperty('--url-icon-htoolbar', `url(${ICON_HTOOLBAR})`)\n this.style.setProperty('--url-icon-fullscreen', `url(${ICON_FULLSCREEN})`)\n this.style.setProperty('--url-icon-collapse', `url(${ICON_COLLAPSE})`)\n this.style.setProperty('--url-icon-collapse-active', `url(${ICON_COLLAPSE_ACTIVE})`)\n }\n\n static get scopedElements() {\n return {\n 'edit-toolbar': EditToolbar,\n 'property-sidebar': PropertySidebar,\n 'component-toolbar': ComponentToolbar\n }\n }\n\n render() {\n return html`\n <edit-toolbar\n .scene=${this.scene}\n .selected=${this.selected}\n @hide-property-changed=${(e: CustomEvent) => (this.hideProperty = e.detail.value)}\n @open-preview=${() => this.preview()}\n @download-model=${() => this.downloadModel()}\n @modeller-fullscreen=${() => togglefullscreen(this)}\n >\n ${this.renderBrandingZone()}\n </edit-toolbar>\n\n <div content>\n <component-toolbar\n .scene=${this.scene}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n .componentGroupList=${this.componentGroupList}\n .group=${this.group}\n >\n </component-toolbar>\n\n <div id=\"scene-wrap\">\n <ox-scene-viewer\n id=\"scene\"\n .scene=${this.scene}\n @scene-changed=${(e: CustomEvent) => {\n this.scene = e.detail.value\n }}\n .model=${this.model}\n .selected=${this.selected}\n @selected-changed=${(e: CustomEvent) => {\n this.selected = e.detail.value\n }}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n fit=\"ratio\"\n .baseUrl=${this.baseUrl}\n @contextmenu=${() => this.onContextMenu()}\n .provider=${this.provider}\n name=\"modeller\"\n >\n <ox-scene-layer type=\"selection-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"modeling-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"add-layer\"> </ox-scene-layer>\n <ox-scene-layer type=\"guide-layer\">\n <ox-scene-property name=\"ruler\" value=\"disabled\"></ox-scene-property>\n </ox-scene-layer>\n <ox-scene-layer type=\"shift-layer\">\n <ox-scene-property name=\"text\" value=\"${this.overlay}\"></ox-scene-property>\n <ox-scene-property name=\"alpha\" value=\"0.3\"></ox-scene-property>\n <ox-scene-property name=\"fontFamily\" value=\"arial\"></ox-scene-property>\n <ox-scene-property name=\"fontSize\" value=\"30\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"fontColor\" value=\"navy\"></ox-scene-property>\n <ox-scene-property name=\"textBaseline\" value=\"top\"></ox-scene-property>\n <ox-scene-property name=\"textAlign\" value=\"left\"></ox-scene-property>\n <ox-scene-property name=\"paddingTop\" value=\"50\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"paddingLeft\" value=\"50\" type=\"number\"></ox-scene-property>\n </ox-scene-layer>\n <ox-scene-handler type=\"text-editor\"></ox-scene-handler>\n <ox-scene-handler type=\"move-handler\"></ox-scene-handler>\n <ox-scene-handler type=\"paste-handler\"></ox-scene-handler>\n </ox-scene-viewer>\n\n <md-fab @click=${() => this.onTapSave()} title=\"save\">\n <md-icon slot=\"icon\">save</md-icon>\n </md-fab>\n </div>\n\n <property-sidebar\n .scene=${this.scene}\n .selected=${this.selected}\n .collapsed=${this.hideProperty}\n .fonts=${this.fonts}\n .propertyEditor=${this.propertyEditor}\n >\n </property-sidebar>\n </div>\n `\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n this.bindShortcutEvent()\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n this.unbindShortcutEvent()\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('scene') && this.scene) {\n this.scene.mode = MODE_EDIT\n }\n }\n\n close() {\n this.model = null\n this.requestUpdate()\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n switch (e.code) {\n case 'KeyS':\n if (ctrlKey) {\n this.onTapSave()\n e.preventDefault()\n }\n break\n }\n }\n\n preview() {\n const board = {\n id: 'preview',\n model: this.scene?.model ? JSON.parse(JSON.stringify(this.scene.model)) : null\n }\n\n OxPopup.open({\n template: html` <ox-board-viewer style=\"flex: 1;\" .provider=${this.provider} .board=${board}></ox-board-viewer> `,\n style: 'width: 80vw; height: 80vh;',\n backdrop: true\n })\n\n requestAnimationFrame(() => {\n dispatchEvent(new Event('resize'))\n })\n }\n\n downloadModel() {\n if (!this.scene) return\n\n var model = JSON.stringify(this.model, null, 2)\n var filename = (this.boardName || 'NONAME') + '-' + Date.now() + '.json'\n saveAs(new Blob([model], { type: 'application/octet-stream' }), filename)\n }\n\n renderBrandingZone() {\n return html``\n }\n\n onTapSave() {\n this.dispatchEvent(new CustomEvent('save-model', { bubbles: true, composed: true, detail: { model: this.model } }))\n }\n\n bindShortcutEvent() {\n // TODO: Global Hotkey에 대한 정의를 edit-toolbar에서 가져올 수 있도록 수정해야 함.\n const GLOBAL_HOTKEYS = ['Digit1', 'Digit2', 'F11', 'KeyD', 'KeyP', 'KeyS']\n\n this.shortcutHandler = (e: KeyboardEvent) => {\n const target = e.composedPath()[0] as HTMLElement\n var tagName = target.tagName\n var isInput = target.isContentEditable || tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA'\n var isGlobalHotkey = GLOBAL_HOTKEYS.includes(e.code)\n\n if (!isGlobalHotkey && isInput) return\n if (!this.editToolbar.onShortcut(e)) this.onShortcut(e)\n }\n\n document.addEventListener('keydown', this.shortcutHandler)\n }\n\n unbindShortcutEvent() {\n if (this.shortcutHandler) {\n document.removeEventListener('keydown', this.shortcutHandler)\n delete this.shortcutHandler\n }\n }\n\n undoable(): boolean {\n return !!this.scene?.undoable()\n }\n\n redoable(): boolean {\n return !!this.scene?.redoable()\n }\n\n preserve(): void {\n this.scene?.preserve()\n }\n\n hasUnpreservedChanges(): boolean {\n return !!this.scene?.hasUnpreservedChanges()\n }\n\n onContextMenu() {}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-board-modeller.js","sourceRoot":"","sources":["../../src/ox-board-modeller.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@material/web/fab/fab.js'\nimport '@hatiolab/things-scene'\nimport './modeller/scene-viewer/ox-scene-handler.js'\nimport './modeller/scene-viewer/ox-scene-layer.js'\nimport './modeller/scene-viewer/ox-scene-property.js'\nimport './modeller/scene-viewer/ox-scene-viewer.js'\nimport './ox-board-viewer.js'\n\nimport { saveAs } from 'file-saver'\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { LoadTracker, LoadingOverlay, MODE_EDIT, Scene, SCENE_MODE, SceneMode } from '@hatiolab/things-scene'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { OxPopup } from '@operato/popup'\nimport { openPopup } from '@operato/layout'\nimport { i18next } from '@operato/i18n'\nimport { isMacOS, togglefullscreen } from '@operato/utils'\n\nimport { ComponentToolbar } from './modeller/component-toolbar/component-toolbar.js'\nimport { EditToolbar } from './modeller/edit-toolbar.js'\nimport { PropertySidebar } from './modeller/property-sidebar.js'\nimport { ComponentGroup, ComponentTemplate } from './types.js'\nimport OxSceneViewer from './modeller/scene-viewer/ox-scene-viewer.js'\n\nconst MACOS = isMacOS()\n\nconst ICON_HTOOLBAR = new URL('../../icons/icon-htoolbar.png', import.meta.url).href\nconst ICON_FULLSCREEN = new URL('../../icons/icon-fullscreen.png', import.meta.url).href\nconst ICON_COLLAPSE = new URL('../../icons/icon-collapse.png', import.meta.url).href\nconst ICON_COLLAPSE_ACTIVE = new URL('../../icons/icon-collapse-active.png', import.meta.url).href\n\nvar Registry: ComponentGroup[] = []\n\n@customElement('ox-board-modeller')\nexport class BoardModeller extends ScopedElementsMixin(LitElement) {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n height: 100%;\n overflow: hidden;\n }\n\n edit-toolbar {\n flex: 45px;\n max-height: 45px;\n }\n\n div[content] {\n flex: 1;\n max-height: calc(100% - 45px);\n\n display: flex;\n flex-direction: row;\n }\n\n component-toolbar {\n max-height: 100%;\n }\n\n property-sidebar {\n overflow: hidden;\n }\n\n #scene-wrap {\n position: relative;\n\n flex: 1;\n display: flex;\n flex-direction: row;\n }\n\n ox-scene-viewer {\n flex: 1;\n width: 100%;\n height: 100%;\n }\n\n md-fab {\n position: absolute;\n right: 15px;\n bottom: 15px;\n z-index: 1000;\n }\n\n ox-popup {\n width: 90%;\n height: 90%;\n left: 50%;\n top: 50%;\n transform: translateX(-50%) translateY(-50%);\n background: var(--md-sys-color-on-secondary-container, black);\n\n display: flex;\n justify-content: center;\n flex-direction: column;\n }\n\n ox-board-viewer {\n width: 98%;\n height: 98%;\n margin: auto;\n padding: 0;\n }\n `\n ]\n\n static registerGroup(group: ComponentGroup) {\n var found = Registry.find(inRegisterGroup => inRegisterGroup.name == group.name)\n\n if (found) {\n found = {\n ...found,\n ...group\n }\n } else {\n Registry.push(group)\n }\n }\n\n static registerTemplate(templates: ComponentTemplate[]): void {\n templates &&\n templates.forEach(template => {\n var groups: string[] = typeof template.group == 'string' ? [template.group] : template.group\n\n Registry.filter(group => groups.includes(group.name)).forEach(group => {\n if (!group.templates.find(inGroupTemplate => inGroupTemplate.type == template.type)) {\n group.templates.push(template)\n }\n })\n })\n }\n\n static get groups(): ComponentGroup[] {\n return Registry\n }\n\n static getGroup(name: string) {\n return Registry.find(group => group.name === name)\n }\n\n @property({ type: String }) boardName: string = ''\n @property({ type: Object }) model: any = null\n @property({ type: String }) baseUrl: string = ''\n @property({ type: Array }) selected: any[] = []\n @property({ type: Number }) mode: SceneMode = SCENE_MODE.EDIT\n @property({ type: Object }) provider: any = null\n @property({ type: Boolean }) hideProperty: boolean = false\n @property({ type: String }) overlay: string = ''\n @property({ type: Object }) scene?: Scene\n @property({ type: Object }) loadTracker?: LoadTracker\n @property({ type: Array }) componentGroupList: any[] = []\n @property({ type: Array }) fonts: any[] = []\n @property({ type: Array }) propertyEditor: any[] = []\n\n @query('edit-toolbar') private editToolbar!: EditToolbar\n @query('ox-scene-viewer') private viewer!: OxSceneViewer\n\n private group: string = ''\n private shortcutHandler?: (e: KeyboardEvent) => void\n private _loadingOverlay?: LoadingOverlay\n\n constructor() {\n super()\n\n document.addEventListener('get-all-scene-component-ids', (e: Event) => {\n var { component, callback } = (e as CustomEvent).detail\n\n if (!this.scene) return\n\n var ids\n if (component) {\n ids = this.scene.findAll(component).map((c: any) => c.model.id)\n } else {\n // @ts-ignore\n ids = this.scene.ids.map(({ key }) => key)\n }\n\n ids = ids.filter(Boolean).sort()\n callback(ids)\n })\n\n this.style.setProperty('--url-icon-htoolbar', `url(${ICON_HTOOLBAR})`)\n this.style.setProperty('--url-icon-fullscreen', `url(${ICON_FULLSCREEN})`)\n this.style.setProperty('--url-icon-collapse', `url(${ICON_COLLAPSE})`)\n this.style.setProperty('--url-icon-collapse-active', `url(${ICON_COLLAPSE_ACTIVE})`)\n }\n\n static get scopedElements() {\n return {\n 'edit-toolbar': EditToolbar,\n 'property-sidebar': PropertySidebar,\n 'component-toolbar': ComponentToolbar\n }\n }\n\n render() {\n return html`\n <edit-toolbar\n .scene=${this.scene}\n .selected=${this.selected}\n @hide-property-changed=${(e: CustomEvent) => (this.hideProperty = e.detail.value)}\n @open-preview=${() => this.preview()}\n @open-data-binding=${() => this.openDataBinding()}\n @download-model=${() => this.downloadModel()}\n @modeller-fullscreen=${() => togglefullscreen(this)}\n >\n ${this.renderBrandingZone()}\n </edit-toolbar>\n\n <div content>\n <component-toolbar\n .scene=${this.scene}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n .componentGroupList=${this.componentGroupList}\n .group=${this.group}\n >\n </component-toolbar>\n\n <div id=\"scene-wrap\">\n <ox-scene-viewer\n id=\"scene\"\n .scene=${this.scene}\n .loadTracker=${this.loadTracker}\n @scene-changed=${(e: CustomEvent) => {\n this.scene = e.detail.value\n }}\n .model=${this.model}\n .selected=${this.selected}\n @selected-changed=${(e: CustomEvent) => {\n this.selected = e.detail.value\n }}\n .mode=${this.mode}\n @mode-changed=${(e: CustomEvent) => {\n this.mode = e.detail.value\n }}\n fit=\"ratio\"\n .baseUrl=${this.baseUrl}\n @contextmenu=${() => this.onContextMenu()}\n .provider=${this.provider}\n name=\"modeller\"\n >\n <ox-scene-layer type=\"snap-guide-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"selection-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"modeling-layer\"></ox-scene-layer>\n <ox-scene-layer type=\"add-layer\"> </ox-scene-layer>\n <ox-scene-layer type=\"shift-layer\">\n <ox-scene-property name=\"text\" value=\"${this.overlay}\"></ox-scene-property>\n <ox-scene-property name=\"alpha\" value=\"0.3\"></ox-scene-property>\n <ox-scene-property name=\"fontFamily\" value=\"arial\"></ox-scene-property>\n <ox-scene-property name=\"fontSize\" value=\"30\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"fontColor\" value=\"navy\"></ox-scene-property>\n <ox-scene-property name=\"textBaseline\" value=\"top\"></ox-scene-property>\n <ox-scene-property name=\"textAlign\" value=\"left\"></ox-scene-property>\n <ox-scene-property name=\"paddingTop\" value=\"50\" type=\"number\"></ox-scene-property>\n <ox-scene-property name=\"paddingLeft\" value=\"50\" type=\"number\"></ox-scene-property>\n </ox-scene-layer>\n <ox-scene-handler type=\"text-editor\"></ox-scene-handler>\n <ox-scene-handler type=\"move-handler\"></ox-scene-handler>\n <ox-scene-handler type=\"paste-handler\"></ox-scene-handler>\n </ox-scene-viewer>\n\n <md-fab @click=${() => this.onTapSave()} title=\"save\">\n <md-icon slot=\"icon\">save</md-icon>\n </md-fab>\n </div>\n\n <property-sidebar\n .scene=${this.scene}\n .selected=${this.selected}\n .collapsed=${this.hideProperty}\n .fonts=${this.fonts}\n .propertyEditor=${this.propertyEditor}\n >\n </property-sidebar>\n </div>\n `\n }\n\n connectedCallback(): void {\n super.connectedCallback()\n this.bindShortcutEvent()\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback()\n this.unbindShortcutEvent()\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('loadTracker') && this.loadTracker) {\n if (!this._loadingOverlay) {\n this._loadingOverlay = new LoadingOverlay()\n }\n this._loadingOverlay.attach(this.renderRoot as HTMLElement, this.loadTracker)\n }\n\n if (changes.has('scene') && this.scene) {\n this.scene.mode = MODE_EDIT\n ;(this.scene as any).onDataBindingToggle = () => this.openDataBinding()\n }\n }\n\n close() {\n this.model = null\n this.requestUpdate()\n }\n\n onShortcut(e: KeyboardEvent) {\n if (MACOS) var ctrlKey = e.metaKey\n else var ctrlKey = e.ctrlKey\n\n switch (e.code) {\n case 'KeyS':\n if (ctrlKey) {\n this.onTapSave()\n e.preventDefault()\n }\n break\n }\n }\n\n preview() {\n const board = {\n id: 'preview',\n model: this.scene?.model ? JSON.parse(JSON.stringify(this.scene.model)) : null\n }\n\n OxPopup.open({\n template: html` <ox-board-viewer style=\"flex: 1;\" .provider=${this.provider} .board=${board}></ox-board-viewer> `,\n style: 'width: 80vw; height: 80vh;',\n backdrop: true,\n preventCloseOnBlur: true\n })\n\n requestAnimationFrame(() => {\n dispatchEvent(new Event('resize'))\n })\n }\n\n private _dataBindingPopup?: any\n\n openDataBinding() {\n // 토글: 이미 열려있으면 닫기\n if (this._dataBindingPopup) {\n this._dataBindingPopup.close()\n this._dataBindingPopup = null\n return\n }\n\n if (!this.scene) return\n\n const selected = this.scene.selected?.[0]\n if (!selected) return\n\n import('@operato/property-panel/data-binding-popup.js')\n\n const PROPS = [\n '',\n 'text',\n 'fillStyle',\n 'strokeStyle',\n 'fontColor',\n 'value',\n 'data',\n 'source',\n 'hidden',\n 'started',\n 'play',\n 'ref',\n 'action',\n 'options',\n 'rotate',\n 'dimension',\n 'location',\n 'accessor',\n 'appendum',\n 'tag',\n 'tap',\n '(action)'\n ].map(p => ({ name: p, label: p }))\n\n const template = html`\n <data-binding-popup\n .mappings=${[...(selected.model.mappings || [])]}\n .properties=${PROPS}\n .selected=${selected}\n ></data-binding-popup>\n `\n\n // document 레벨에서 mappings-change 이벤트 수신 (openPopup 컨텍스트에서 Lit 이벤트 바인딩 불가)\n const onMappingsChange = (e: Event) => {\n const detail = (e as CustomEvent).detail\n if (detail?.mappings) {\n selected.set('mappings', detail.mappings)\n }\n }\n document.addEventListener('mappings-change', onMappingsChange)\n\n this._dataBindingPopup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: `${i18next.t('label.data-spread')} — ${selected.get('id') || selected.get('type')}`\n })\n\n // 팝업이 외부에서 닫힐 때 참조 정리\n this._dataBindingPopup?.addEventListener?.('closed', () => {\n document.removeEventListener('mappings-change', onMappingsChange)\n this._dataBindingPopup = null\n })\n }\n\n downloadModel() {\n if (!this.scene) return\n\n var model = JSON.stringify(this.model, null, 2)\n var filename = (this.boardName || 'NONAME') + '-' + Date.now() + '.json'\n saveAs(new Blob([model], { type: 'application/octet-stream' }), filename)\n }\n\n renderBrandingZone() {\n return html``\n }\n\n onTapSave() {\n this.dispatchEvent(new CustomEvent('save-model', { bubbles: true, composed: true, detail: { model: this.model } }))\n }\n\n bindShortcutEvent() {\n // TODO: Global Hotkey에 대한 정의를 edit-toolbar에서 가져올 수 있도록 수정해야 함.\n const GLOBAL_HOTKEYS = ['Digit1', 'Digit2', 'F11', 'KeyD', 'KeyP', 'KeyS']\n\n this.shortcutHandler = (e: KeyboardEvent) => {\n const target = e.composedPath()[0] as HTMLElement\n var tagName = target.tagName\n var isInput = target.isContentEditable || tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA'\n var isGlobalHotkey = GLOBAL_HOTKEYS.includes(e.code)\n\n if (!isGlobalHotkey && isInput) return\n if (!this.editToolbar.onShortcut(e)) this.onShortcut(e)\n }\n\n document.addEventListener('keydown', this.shortcutHandler)\n }\n\n unbindShortcutEvent() {\n if (this.shortcutHandler) {\n document.removeEventListener('keydown', this.shortcutHandler)\n delete this.shortcutHandler\n }\n }\n\n undoable(): boolean {\n return !!this.scene?.undoable()\n }\n\n redoable(): boolean {\n return !!this.scene?.redoable()\n }\n\n preserve(): void {\n this.scene?.preserve()\n }\n\n hasUnpreservedChanges(): boolean {\n return !!this.scene?.hasUnpreservedChanges()\n }\n\n onContextMenu() {}\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import '@material/web/icon/icon.js';
|
|
2
2
|
import '@material/web/fab/fab.js';
|
|
3
3
|
import { LitElement, PropertyValues } from 'lit';
|
|
4
|
-
import { Component, ReferenceProvider } from '@hatiolab/things-scene';
|
|
4
|
+
import { Component, LoadTracker, ReferenceProvider } from '@hatiolab/things-scene';
|
|
5
|
+
import './ox-playback-controls.js';
|
|
5
6
|
export declare class BoardViewer extends LitElement {
|
|
6
7
|
static styles: import("lit").CSSResult[];
|
|
7
8
|
baseUrl: string;
|
|
@@ -10,8 +11,21 @@ export declare class BoardViewer extends LitElement {
|
|
|
10
11
|
data: any;
|
|
11
12
|
values: any;
|
|
12
13
|
history: boolean;
|
|
14
|
+
/** 앱에서 미리 생성한 LoadTracker. fetch 시작 전에 생성하면 네트워크 시간도 추적. */
|
|
15
|
+
loadTracker?: LoadTracker;
|
|
13
16
|
hideFullscreen: boolean;
|
|
14
17
|
hideNavigation: boolean;
|
|
18
|
+
playbackEnabled: boolean;
|
|
19
|
+
playbackTimeRange?: {
|
|
20
|
+
from: Date;
|
|
21
|
+
to: Date;
|
|
22
|
+
};
|
|
23
|
+
private _playbackState;
|
|
24
|
+
private _playbackActive;
|
|
25
|
+
private _playbackSpeed;
|
|
26
|
+
private _playbackCurrentTime;
|
|
27
|
+
private _playbackProvider;
|
|
28
|
+
private _savedRealProvider;
|
|
15
29
|
_scene: any;
|
|
16
30
|
_forward: {
|
|
17
31
|
id: string;
|
|
@@ -21,6 +35,7 @@ export declare class BoardViewer extends LitElement {
|
|
|
21
35
|
id: string;
|
|
22
36
|
scene: any;
|
|
23
37
|
}[];
|
|
38
|
+
private _loadingOverlay?;
|
|
24
39
|
_oldtarget?: HTMLElement;
|
|
25
40
|
_fade_animations?: Array<Animation>;
|
|
26
41
|
currentBoardId?: string;
|
|
@@ -28,7 +43,10 @@ export declare class BoardViewer extends LitElement {
|
|
|
28
43
|
_target: HTMLElement;
|
|
29
44
|
_prev: HTMLElement;
|
|
30
45
|
_next: HTMLElement;
|
|
46
|
+
_fabExpanded: boolean;
|
|
47
|
+
get _is3dMode(): boolean;
|
|
31
48
|
_fullscreen: HTMLElement;
|
|
49
|
+
_fabGroup: HTMLElement;
|
|
32
50
|
render(): import("lit-html").TemplateResult<1>;
|
|
33
51
|
private resizeHandler;
|
|
34
52
|
connectedCallback(): void;
|
|
@@ -36,6 +54,7 @@ export declare class BoardViewer extends LitElement {
|
|
|
36
54
|
updated(changes: PropertyValues<this>): void;
|
|
37
55
|
initSceneAsync(): Promise<void>;
|
|
38
56
|
initScene(): void;
|
|
57
|
+
private _ensureOverlay;
|
|
39
58
|
closeScene(): void;
|
|
40
59
|
releaseScene(): void;
|
|
41
60
|
setupScene({ id, scene }: {
|
|
@@ -50,6 +69,7 @@ export declare class BoardViewer extends LitElement {
|
|
|
50
69
|
onTapNext(): void;
|
|
51
70
|
onTapPrev(): void;
|
|
52
71
|
onTapFullscreen(): void;
|
|
72
|
+
onTapToggle3D(): void;
|
|
53
73
|
onRunBoard(): void;
|
|
54
74
|
onLinkGoto(targetBoardId: string, options: any, fromComponent: Component): void;
|
|
55
75
|
onLinkGotoPlaylist(targetPlayGroupName: string, options: any, fromComponent: Component): void;
|
|
@@ -61,6 +81,35 @@ export declare class BoardViewer extends LitElement {
|
|
|
61
81
|
onExportData(filename: string, value: string | number | object, component: Component): Promise<void>;
|
|
62
82
|
onImportData(_: string, value: string | number | object, component: Component): Promise<void>;
|
|
63
83
|
onClickEvent(e: MouseEvent, hint: any): void;
|
|
84
|
+
/**
|
|
85
|
+
* 외부에서 플레이백을 활성화한다.
|
|
86
|
+
* playback-enabled 속성을 설정하면 컨트롤바가 나타나고,
|
|
87
|
+
* 이 메서드로 시간 범위 등 상세 설정을 할 수 있다.
|
|
88
|
+
*/
|
|
89
|
+
enablePlayback(config?: {
|
|
90
|
+
timeRange?: {
|
|
91
|
+
from: Date;
|
|
92
|
+
to: Date;
|
|
93
|
+
};
|
|
94
|
+
}): void;
|
|
95
|
+
disablePlayback(): void;
|
|
96
|
+
private _onTogglePlaybackPanel;
|
|
97
|
+
private _onPlaybackStart;
|
|
98
|
+
private _onPlaybackPause;
|
|
99
|
+
private _onPlaybackResume;
|
|
100
|
+
private _onPlaybackStop;
|
|
101
|
+
private _onPlaybackSeek;
|
|
102
|
+
private _onPlaybackSpeed;
|
|
103
|
+
private _startPlayback;
|
|
104
|
+
private _stopPlayback;
|
|
105
|
+
/**
|
|
106
|
+
* 모든 tag 컴포넌트의 기존 구독을 해제한다.
|
|
107
|
+
*/
|
|
108
|
+
private _unsubscribeAll;
|
|
109
|
+
/**
|
|
110
|
+
* 모든 tag 컴포넌트를 현재 provider로 재구독한다.
|
|
111
|
+
*/
|
|
112
|
+
private _resubscribeAll;
|
|
64
113
|
hidePopup(): void;
|
|
65
114
|
getSceneData(): any;
|
|
66
115
|
getSceneValues(): any;
|
|
@@ -4,11 +4,13 @@ import '@material/web/fab/fab.js';
|
|
|
4
4
|
import { css, html, LitElement } from 'lit';
|
|
5
5
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
6
6
|
import * as XLSX from 'xlsx';
|
|
7
|
-
import { create, SCENE_MODE } from '@hatiolab/things-scene';
|
|
7
|
+
import { create, LoadTracker, LoadingOverlay, SCENE_MODE } from '@hatiolab/things-scene';
|
|
8
8
|
import { isIOS, togglefullscreen } from '@operato/utils';
|
|
9
9
|
import { ScrollbarStyles } from '@operato/styles';
|
|
10
10
|
import { BoardDataStorage } from './data-storage/data-storage.js';
|
|
11
11
|
import { DataSubscriptionProviderImpl } from './graphql/data-subscription.js';
|
|
12
|
+
import { PlaybackProvider } from './graphql/playback-subscription.js';
|
|
13
|
+
import './ox-playback-controls.js';
|
|
12
14
|
import { runScenario, startScenario } from './graphql/scenario.js';
|
|
13
15
|
import { fetchPlayGroupByName } from './graphql/play-group.js';
|
|
14
16
|
function objectToQueryString(obj) {
|
|
@@ -36,28 +38,27 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
36
38
|
this.history = false;
|
|
37
39
|
this.hideFullscreen = false;
|
|
38
40
|
this.hideNavigation = false;
|
|
41
|
+
this.playbackEnabled = false;
|
|
42
|
+
this._playbackState = 'idle';
|
|
43
|
+
this._playbackActive = false;
|
|
44
|
+
this._playbackSpeed = 1;
|
|
45
|
+
this._playbackCurrentTime = '';
|
|
46
|
+
this._playbackProvider = null;
|
|
47
|
+
this._savedRealProvider = null;
|
|
39
48
|
this._scene = null;
|
|
40
49
|
this._forward = [];
|
|
41
50
|
this._backward = [];
|
|
42
51
|
this.currentBoardId = (_a = this.board) === null || _a === void 0 ? void 0 : _a.id;
|
|
52
|
+
this._fabExpanded = false;
|
|
43
53
|
this.resizeHandler = () => {
|
|
44
54
|
this._scene && this._scene.fit();
|
|
45
55
|
};
|
|
46
56
|
}
|
|
57
|
+
get _is3dMode() {
|
|
58
|
+
var _a, _b, _c;
|
|
59
|
+
return !!((_c = (_b = (_a = this._scene) === null || _a === void 0 ? void 0 : _a.root) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.threed);
|
|
60
|
+
}
|
|
47
61
|
render() {
|
|
48
|
-
var fullscreen = !isIOS() && !this.hideFullscreen
|
|
49
|
-
? html `
|
|
50
|
-
<md-fab
|
|
51
|
-
id="fullscreen"
|
|
52
|
-
@click=${(e) => this.onTapFullscreen()}
|
|
53
|
-
@mouseover=${(e) => this.transientShowButtons(true)}
|
|
54
|
-
@mouseout=${(e) => this.transientShowButtons()}
|
|
55
|
-
title="fullscreen"
|
|
56
|
-
>
|
|
57
|
-
<md-icon slot="icon">${document.fullscreenElement ? 'fullscreen_exit' : 'fullscreen'}</md-icon>
|
|
58
|
-
</md-fab>
|
|
59
|
-
`
|
|
60
|
-
: html ``;
|
|
61
62
|
var prev = !this.hideNavigation
|
|
62
63
|
? html `
|
|
63
64
|
<md-icon
|
|
@@ -92,7 +93,60 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
92
93
|
></div>
|
|
93
94
|
|
|
94
95
|
<slot></slot>
|
|
95
|
-
${next}
|
|
96
|
+
${next}
|
|
97
|
+
|
|
98
|
+
${!isIOS() && !this.hideFullscreen ? html `
|
|
99
|
+
<div
|
|
100
|
+
fab-group
|
|
101
|
+
?expanded=${this._fabExpanded}
|
|
102
|
+
@mouseover=${(e) => this.transientShowButtons(true)}
|
|
103
|
+
@mouseout=${(e) => this.transientShowButtons()}
|
|
104
|
+
>
|
|
105
|
+
<md-fab
|
|
106
|
+
class="main-fab"
|
|
107
|
+
?expanded=${this._fabExpanded}
|
|
108
|
+
@click=${() => { this._fabExpanded = !this._fabExpanded; }}
|
|
109
|
+
title="menu"
|
|
110
|
+
><md-icon slot="icon">add</md-icon></md-fab>
|
|
111
|
+
|
|
112
|
+
<md-fab
|
|
113
|
+
class="sub-fab"
|
|
114
|
+
@click=${() => { this._fabExpanded = false; this.onTapFullscreen(); }}
|
|
115
|
+
title="fullscreen"
|
|
116
|
+
><md-icon slot="icon">${document.fullscreenElement ? 'fullscreen_exit' : 'fullscreen'}</md-icon></md-fab>
|
|
117
|
+
|
|
118
|
+
<md-fab
|
|
119
|
+
class="sub-fab"
|
|
120
|
+
@click=${() => { this._fabExpanded = false; this.onTapToggle3D(); }}
|
|
121
|
+
title=${this._is3dMode ? '2D mode' : '3D mode'}
|
|
122
|
+
><md-icon slot="icon">${this._is3dMode ? 'view_in_ar' : '3d_rotation'}</md-icon></md-fab>
|
|
123
|
+
|
|
124
|
+
${this.playbackEnabled ? html `
|
|
125
|
+
<md-fab
|
|
126
|
+
class="sub-fab"
|
|
127
|
+
@click=${() => { this._fabExpanded = false; this._onTogglePlaybackPanel(); }}
|
|
128
|
+
title="playback"
|
|
129
|
+
><md-icon slot="icon">${this._playbackActive ? 'stop' : 'history'}</md-icon></md-fab>
|
|
130
|
+
` : html ``}
|
|
131
|
+
</div>
|
|
132
|
+
` : html ``}
|
|
133
|
+
|
|
134
|
+
${this._playbackActive
|
|
135
|
+
? html `
|
|
136
|
+
<ox-playback-controls
|
|
137
|
+
.playbackState=${this._playbackState}
|
|
138
|
+
.speed=${this._playbackSpeed}
|
|
139
|
+
.currentTime=${this._playbackCurrentTime}
|
|
140
|
+
.timeRange=${this.playbackTimeRange || { from: new Date(Date.now() - 3600000), to: new Date() }}
|
|
141
|
+
@playback-start=${this._onPlaybackStart}
|
|
142
|
+
@playback-pause=${this._onPlaybackPause}
|
|
143
|
+
@playback-resume=${this._onPlaybackResume}
|
|
144
|
+
@playback-stop=${this._onPlaybackStop}
|
|
145
|
+
@playback-seek=${this._onPlaybackSeek}
|
|
146
|
+
@playback-speed=${this._onPlaybackSpeed}
|
|
147
|
+
></ox-playback-controls>
|
|
148
|
+
`
|
|
149
|
+
: html ``}
|
|
96
150
|
`;
|
|
97
151
|
}
|
|
98
152
|
connectedCallback() {
|
|
@@ -111,7 +165,16 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
111
165
|
this.closeScene();
|
|
112
166
|
}
|
|
113
167
|
updated(changes) {
|
|
168
|
+
// loadTracker가 외부에서 전달되면 즉시 overlay 연결 (fetch 중에도 표시)
|
|
169
|
+
if (changes.has('loadTracker') && this.loadTracker) {
|
|
170
|
+
this._ensureOverlay(this.loadTracker);
|
|
171
|
+
}
|
|
114
172
|
if (changes.has('board')) {
|
|
173
|
+
// tracker: 외부에서 안 왔으면 여기서 생성 (reset 하지 않음 — 연속성 유지)
|
|
174
|
+
if (!this.loadTracker) {
|
|
175
|
+
this.loadTracker = new LoadTracker();
|
|
176
|
+
this._ensureOverlay(this.loadTracker);
|
|
177
|
+
}
|
|
115
178
|
this.hidePopup();
|
|
116
179
|
this.closeScene();
|
|
117
180
|
if (this.board && this.board.id) {
|
|
@@ -147,7 +210,8 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
147
210
|
refProvider: this.provider,
|
|
148
211
|
dataStorage: this.board.id !== 'preview' ? new BoardDataStorage(this.board.id) : undefined,
|
|
149
212
|
dataSubscriptionProvider: new DataSubscriptionProviderImpl(),
|
|
150
|
-
handlers: ['waypoint-handler']
|
|
213
|
+
handlers: ['waypoint-handler'],
|
|
214
|
+
loading: { tracker: this.loadTracker }
|
|
151
215
|
});
|
|
152
216
|
if (this.baseUrl) {
|
|
153
217
|
this._scene.baseUrl = this.baseUrl;
|
|
@@ -155,7 +219,20 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
155
219
|
// this.provider!.add(this.board.id, this._scene)
|
|
156
220
|
this.setupScene({ id: this.board.id, scene: this._scene });
|
|
157
221
|
}
|
|
222
|
+
_ensureOverlay(tracker) {
|
|
223
|
+
if (!this._loadingOverlay) {
|
|
224
|
+
this._loadingOverlay = new LoadingOverlay();
|
|
225
|
+
}
|
|
226
|
+
this._loadingOverlay.attach(this.renderRoot, tracker);
|
|
227
|
+
}
|
|
158
228
|
closeScene() {
|
|
229
|
+
// 플레이백 중이면 정리
|
|
230
|
+
if (this._playbackProvider) {
|
|
231
|
+
this._playbackProvider.dispose();
|
|
232
|
+
this._playbackProvider = null;
|
|
233
|
+
this._savedRealProvider = null;
|
|
234
|
+
this._playbackState = 'idle';
|
|
235
|
+
}
|
|
159
236
|
if (this._scene) {
|
|
160
237
|
this.unbindSceneEvents(this._scene);
|
|
161
238
|
this._scene.target = null;
|
|
@@ -285,7 +362,8 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
285
362
|
transientShowButtons(stop) {
|
|
286
363
|
var buttons = [];
|
|
287
364
|
!this.hideNavigation && buttons.push(this._next, this._prev);
|
|
288
|
-
|
|
365
|
+
if (this._fabGroup)
|
|
366
|
+
buttons.push(this._fabGroup);
|
|
289
367
|
if (buttons.length == 0) {
|
|
290
368
|
return;
|
|
291
369
|
}
|
|
@@ -308,7 +386,7 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
308
386
|
}
|
|
309
387
|
this._forward.length <= 0 ? this._next.setAttribute('hidden', '') : this._next.removeAttribute('hidden');
|
|
310
388
|
this._backward.length <= 0 ? this._prev.setAttribute('hidden', '') : this._prev.removeAttribute('hidden');
|
|
311
|
-
this.
|
|
389
|
+
this._fabGroup && this._fabGroup.removeAttribute('hidden');
|
|
312
390
|
this._fade_animations.forEach(animation => {
|
|
313
391
|
animation.cancel();
|
|
314
392
|
if (stop)
|
|
@@ -346,6 +424,15 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
346
424
|
onTapFullscreen() {
|
|
347
425
|
togglefullscreen(this, () => this.requestUpdate(), () => this.requestUpdate());
|
|
348
426
|
}
|
|
427
|
+
onTapToggle3D() {
|
|
428
|
+
if (!this._scene)
|
|
429
|
+
return;
|
|
430
|
+
const root = this._scene.root;
|
|
431
|
+
if (!root)
|
|
432
|
+
return;
|
|
433
|
+
root.set('threed', !this._is3dMode);
|
|
434
|
+
this.requestUpdate();
|
|
435
|
+
}
|
|
349
436
|
onRunBoard() {
|
|
350
437
|
this.dispatchEvent(new CustomEvent('run-board', { bubbles: true, composed: true, detail: this.board.id }));
|
|
351
438
|
}
|
|
@@ -452,6 +539,122 @@ let BoardViewer = class BoardViewer extends LitElement {
|
|
|
452
539
|
// clickComponent 이벤트만 발생시킨다.
|
|
453
540
|
window.dispatchEvent(new CustomEvent('clickComponent', { detail: component }));
|
|
454
541
|
}
|
|
542
|
+
/* playback */
|
|
543
|
+
/**
|
|
544
|
+
* 외부에서 플레이백을 활성화한다.
|
|
545
|
+
* playback-enabled 속성을 설정하면 컨트롤바가 나타나고,
|
|
546
|
+
* 이 메서드로 시간 범위 등 상세 설정을 할 수 있다.
|
|
547
|
+
*/
|
|
548
|
+
enablePlayback(config) {
|
|
549
|
+
this.playbackEnabled = true;
|
|
550
|
+
if (config === null || config === void 0 ? void 0 : config.timeRange) {
|
|
551
|
+
this.playbackTimeRange = config.timeRange;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
disablePlayback() {
|
|
555
|
+
this._stopPlayback();
|
|
556
|
+
this._playbackActive = false;
|
|
557
|
+
this.playbackEnabled = false;
|
|
558
|
+
}
|
|
559
|
+
_onTogglePlaybackPanel() {
|
|
560
|
+
if (this._playbackActive) {
|
|
561
|
+
// 패널 닫기 — 재생 중이면 중지
|
|
562
|
+
this._stopPlayback();
|
|
563
|
+
this._playbackActive = false;
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
this._playbackActive = true;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
async _onPlaybackStart(e) {
|
|
570
|
+
const { fromTime, speed } = e.detail;
|
|
571
|
+
await this._startPlayback(fromTime, speed);
|
|
572
|
+
}
|
|
573
|
+
async _onPlaybackPause() {
|
|
574
|
+
var _a;
|
|
575
|
+
await ((_a = this._playbackProvider) === null || _a === void 0 ? void 0 : _a.pause());
|
|
576
|
+
}
|
|
577
|
+
async _onPlaybackResume() {
|
|
578
|
+
var _a;
|
|
579
|
+
await ((_a = this._playbackProvider) === null || _a === void 0 ? void 0 : _a.resume());
|
|
580
|
+
}
|
|
581
|
+
_onPlaybackStop() {
|
|
582
|
+
this._stopPlayback();
|
|
583
|
+
this._playbackActive = false;
|
|
584
|
+
}
|
|
585
|
+
async _onPlaybackSeek(e) {
|
|
586
|
+
var _a;
|
|
587
|
+
await ((_a = this._playbackProvider) === null || _a === void 0 ? void 0 : _a.seek(e.detail.toTime));
|
|
588
|
+
}
|
|
589
|
+
async _onPlaybackSpeed(e) {
|
|
590
|
+
var _a;
|
|
591
|
+
await ((_a = this._playbackProvider) === null || _a === void 0 ? void 0 : _a.setSpeed(e.detail.speed));
|
|
592
|
+
}
|
|
593
|
+
async _startPlayback(fromTime, speed) {
|
|
594
|
+
if (!this._scene)
|
|
595
|
+
return;
|
|
596
|
+
const rootContainer = this._scene.rootContainer;
|
|
597
|
+
// 실시간 provider 보관 및 구독 해제
|
|
598
|
+
if (!this._savedRealProvider) {
|
|
599
|
+
this._savedRealProvider = rootContainer.app.dataSubscriptionProvider;
|
|
600
|
+
await this._unsubscribeAll(rootContainer);
|
|
601
|
+
}
|
|
602
|
+
// PlaybackProvider 생성
|
|
603
|
+
this._playbackProvider = new PlaybackProvider((status) => {
|
|
604
|
+
this._playbackState = status.state;
|
|
605
|
+
this._playbackSpeed = status.speed;
|
|
606
|
+
this._playbackCurrentTime = status.currentTime;
|
|
607
|
+
});
|
|
608
|
+
// provider 교체 및 재구독
|
|
609
|
+
rootContainer.app.dataSubscriptionProvider = this._playbackProvider;
|
|
610
|
+
await this._resubscribeAll(rootContainer);
|
|
611
|
+
// 플레이백 시작
|
|
612
|
+
await this._playbackProvider.start(fromTime, speed);
|
|
613
|
+
}
|
|
614
|
+
async _stopPlayback() {
|
|
615
|
+
if (!this._scene || !this._playbackProvider)
|
|
616
|
+
return;
|
|
617
|
+
const rootContainer = this._scene.rootContainer;
|
|
618
|
+
// 플레이백 구독 해제
|
|
619
|
+
this._playbackProvider.dispose();
|
|
620
|
+
await this._unsubscribeAll(rootContainer);
|
|
621
|
+
// 실시간 provider 복귀
|
|
622
|
+
if (this._savedRealProvider) {
|
|
623
|
+
rootContainer.app.dataSubscriptionProvider = this._savedRealProvider;
|
|
624
|
+
await this._resubscribeAll(rootContainer);
|
|
625
|
+
this._savedRealProvider = null;
|
|
626
|
+
}
|
|
627
|
+
this._playbackProvider = null;
|
|
628
|
+
this._playbackState = 'idle';
|
|
629
|
+
this._playbackCurrentTime = '';
|
|
630
|
+
this._playbackSpeed = 1;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* 모든 tag 컴포넌트의 기존 구독을 해제한다.
|
|
634
|
+
*/
|
|
635
|
+
async _unsubscribeAll(rootContainer) {
|
|
636
|
+
const promises = [];
|
|
637
|
+
rootContainer.model_layer.traverse((component) => {
|
|
638
|
+
var _a;
|
|
639
|
+
if ((_a = component.model) === null || _a === void 0 ? void 0 : _a.tag) {
|
|
640
|
+
promises.push(rootContainer.unsubscribe(component.model.tag, component));
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
await Promise.all(promises);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* 모든 tag 컴포넌트를 현재 provider로 재구독한다.
|
|
647
|
+
*/
|
|
648
|
+
async _resubscribeAll(rootContainer) {
|
|
649
|
+
const promises = [];
|
|
650
|
+
rootContainer.model_layer.traverse((component) => {
|
|
651
|
+
var _a;
|
|
652
|
+
if ((_a = component.model) === null || _a === void 0 ? void 0 : _a.tag) {
|
|
653
|
+
promises.push(rootContainer.subscribe(component.model.tag, component));
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
await Promise.all(promises);
|
|
657
|
+
}
|
|
455
658
|
hidePopup() {
|
|
456
659
|
if (this.popup) {
|
|
457
660
|
this.removeChild(this.popup);
|
|
@@ -584,11 +787,40 @@ BoardViewer.styles = [
|
|
|
584
787
|
z-index: 1000;
|
|
585
788
|
}
|
|
586
789
|
|
|
587
|
-
|
|
790
|
+
[fab-group] {
|
|
588
791
|
position: absolute;
|
|
589
792
|
bottom: 15px;
|
|
590
793
|
right: 16px;
|
|
591
794
|
z-index: 1000;
|
|
795
|
+
display: flex;
|
|
796
|
+
flex-direction: column-reverse;
|
|
797
|
+
gap: 8px;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
[fab-group] md-fab {
|
|
801
|
+
--md-fab-container-width: 48px;
|
|
802
|
+
--md-fab-container-height: 48px;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
[fab-group] md-fab.main-fab md-icon {
|
|
806
|
+
transition: transform 0.3s;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
[fab-group] md-fab.main-fab[expanded] md-icon {
|
|
810
|
+
transform: rotate(45deg);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
[fab-group] md-fab.sub-fab {
|
|
814
|
+
--md-fab-container-width: 40px;
|
|
815
|
+
--md-fab-container-height: 40px;
|
|
816
|
+
transform: scale(0);
|
|
817
|
+
opacity: 0;
|
|
818
|
+
transition: transform 0.2s, opacity 0.2s;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
[fab-group][expanded] md-fab.sub-fab {
|
|
822
|
+
transform: scale(1);
|
|
823
|
+
opacity: 1;
|
|
592
824
|
}
|
|
593
825
|
|
|
594
826
|
[hidden] {
|
|
@@ -621,6 +853,9 @@ __decorate([
|
|
|
621
853
|
__decorate([
|
|
622
854
|
property({ type: Boolean })
|
|
623
855
|
], BoardViewer.prototype, "history", void 0);
|
|
856
|
+
__decorate([
|
|
857
|
+
property({ type: Object })
|
|
858
|
+
], BoardViewer.prototype, "loadTracker", void 0);
|
|
624
859
|
__decorate([
|
|
625
860
|
property({ type: Boolean, reflect: true, attribute: 'hide-fullscreen' })
|
|
626
861
|
], BoardViewer.prototype, "hideFullscreen", void 0);
|
|
@@ -628,20 +863,23 @@ __decorate([
|
|
|
628
863
|
property({ type: Boolean, reflect: true, attribute: 'hide-navigation' })
|
|
629
864
|
], BoardViewer.prototype, "hideNavigation", void 0);
|
|
630
865
|
__decorate([
|
|
631
|
-
|
|
632
|
-
], BoardViewer.prototype, "
|
|
866
|
+
property({ type: Boolean, reflect: true, attribute: 'playback-enabled' })
|
|
867
|
+
], BoardViewer.prototype, "playbackEnabled", void 0);
|
|
868
|
+
__decorate([
|
|
869
|
+
property({ type: Object, attribute: 'playback-time-range' })
|
|
870
|
+
], BoardViewer.prototype, "playbackTimeRange", void 0);
|
|
633
871
|
__decorate([
|
|
634
872
|
state()
|
|
635
|
-
], BoardViewer.prototype, "
|
|
873
|
+
], BoardViewer.prototype, "_playbackState", void 0);
|
|
636
874
|
__decorate([
|
|
637
875
|
state()
|
|
638
|
-
], BoardViewer.prototype, "
|
|
876
|
+
], BoardViewer.prototype, "_playbackActive", void 0);
|
|
639
877
|
__decorate([
|
|
640
878
|
state()
|
|
641
|
-
], BoardViewer.prototype, "
|
|
879
|
+
], BoardViewer.prototype, "_playbackSpeed", void 0);
|
|
642
880
|
__decorate([
|
|
643
881
|
state()
|
|
644
|
-
], BoardViewer.prototype, "
|
|
882
|
+
], BoardViewer.prototype, "_playbackCurrentTime", void 0);
|
|
645
883
|
__decorate([
|
|
646
884
|
query('#target')
|
|
647
885
|
], BoardViewer.prototype, "_target", void 0);
|
|
@@ -651,9 +889,15 @@ __decorate([
|
|
|
651
889
|
__decorate([
|
|
652
890
|
query('#next')
|
|
653
891
|
], BoardViewer.prototype, "_next", void 0);
|
|
892
|
+
__decorate([
|
|
893
|
+
state()
|
|
894
|
+
], BoardViewer.prototype, "_fabExpanded", void 0);
|
|
654
895
|
__decorate([
|
|
655
896
|
query('#fullscreen')
|
|
656
897
|
], BoardViewer.prototype, "_fullscreen", void 0);
|
|
898
|
+
__decorate([
|
|
899
|
+
query('[fab-group]')
|
|
900
|
+
], BoardViewer.prototype, "_fabGroup", void 0);
|
|
657
901
|
BoardViewer = __decorate([
|
|
658
902
|
customElement('ox-board-viewer')
|
|
659
903
|
], BoardViewer);
|