UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

93 lines (82 loc) 3.19 kB
import {Camera} from 'three'; import {ParamConfig} from '../../engine/nodes/utils/params/ParamsConfig'; import {StringParamLanguage} from '../../engine/params/utils/OptionsController'; import {Constructor} from '../../types/GlobalTypes'; import {CameraAttribute} from './CoreCamera'; import {coreObjectClassFactory} from '../geometry/CoreObjectFactory'; export function CoreCameraViewerCodeParamConfig<TBase extends Constructor>(Base: TBase) { return class Mixin extends Base { /** @param viewerId */ viewerId = ParamConfig.STRING('my-viewer'); /** @param shadow root */ // shadowRoot = ParamConfig.BOOLEAN(false); /** @param HTML */ html = ParamConfig.STRING('', { language: StringParamLanguage.HTML, }); }; } interface CreateViewerCodeOptions { camera: Camera; } interface ViewerConfigOptions { viewerId: string; // shadowRoot: boolean; html: string; } interface CreateViewerElementOptions { domElement: HTMLElement; canvas: HTMLCanvasElement; CSSClass: string; } export class ViewerCodeConfig { constructor(public readonly options: ViewerConfigOptions) {} createViewerElement(options: CreateViewerElementOptions) { const {viewerId, html} = this.options; const {domElement, canvas, CSSClass} = options; const _container = document.createElement('div'); // function _createShadow(element: HTMLElement) { // element.attachShadow({mode: 'open'}); // return element; // } const container = _container; //shadowRoot == true ? _createShadow(_container) : _container; container.style.height = '100%'; container.innerHTML = html; domElement?.appendChild(container); container.classList.add(CSSClass); const viewerElement = container.querySelector(`#${viewerId}`); if (!viewerElement) { console.error(`failed to find element with id ${viewerId}`); return; } viewerElement.appendChild(canvas); // since <script> tags add with .innerHTML are not run, // we need to force them function executeScriptElements(containerElement: HTMLElement | ShadowRoot) { const scriptElements = containerElement.querySelectorAll('script'); Array.from(scriptElements).forEach((scriptElement) => { const clonedElement = document.createElement('script'); Array.from(scriptElement.attributes).forEach((attribute) => { clonedElement.setAttribute(attribute.name, attribute.value); }); clonedElement.text = scriptElement.text; scriptElement.parentNode?.replaceChild(clonedElement, scriptElement); }); } executeScriptElements(container); return viewerElement; } } export class CoreCameraViewerCodeController { static viewerCodeConfig(options: CreateViewerCodeOptions): ViewerCodeConfig | undefined { const {camera} = options; const coreObjectClass = coreObjectClassFactory(camera); const viewerId = coreObjectClass.attribValue(camera, CameraAttribute.VIEWER_ID) as string | null; // const shadowRoot = CoreObject.attribValue(camera, CameraAttribute.VIEWER_SHADOW_ROOT) as boolean | null; const html = coreObjectClass.attribValue(camera, CameraAttribute.VIEWER_HTML) as string | null; if (viewerId == null || html == null) { return; } return new ViewerCodeConfig({viewerId, html}); } }