UNPKG

@polygonjs/polygonjs

Version:

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

118 lines (114 loc) 4.75 kB
/** * Creates CSS3DObjects. * * @remarks * This is very useful to create 2D html labels that would be positioned at specific points in the 3D world. * Note that the camera must be configured to use a CSS2DRenderer to display them * * */ import {TypedSopNode} from './_Base'; import {CoreGroup} from '../../../core/geometry/Group'; import {CoreCSSObjectAttribute, DEFAULT_CSS3DOBJECT} from '../../../core/render/CSSRenderers/CSSObjectAttribute'; import {createCSS3DObject} from '../../../core/render/CSSRenderers/CSS3DObject'; import {Poly} from '../../Poly'; import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {StringParamLanguage} from '../../params/utils/OptionsController'; import {SopType} from '../../poly/registers/nodes/types/Sop'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {CoreObjectType, ObjectContent} from '../../../core/geometry/ObjectContent'; import {stringToAttribNames} from '../../../core/String'; import {Object3D} from 'three'; import {replaceChild} from '../../poly/PolyOnObjectsAddRemoveHooksController'; class CSS3DObjectSopParamsConfig extends NodeParamsConfig { /** @param toggles on if attributes are copied from the geometry to the html element */ copyAttributes = ParamConfig.BOOLEAN(true); /** @param names of the attributes that are copied from the geometry to the html element */ attributesToCopy = ParamConfig.STRING('', { visibleIf: {copyAttributes: true}, }); /** @param HTML elements may appear to large at first, so this gives you a quick way to scale them down */ scale = ParamConfig.FLOAT(0.02); /** @param defines if the vertex id attribute is used to create the html id attribute */ overrideId = ParamConfig.BOOLEAN(true); /** @param value of the html element id attribute */ id = ParamConfig.STRING(DEFAULT_CSS3DOBJECT.id, { visibleIf: {overrideId: 1}, }); /** @param defines if the vertex class attribute is used to create the html class */ overrideClassName = ParamConfig.BOOLEAN(true); /** @param value of the html class */ className = ParamConfig.STRING(DEFAULT_CSS3DOBJECT.className, { visibleIf: {overrideClassName: 1}, }); /** @param defines if the vertex html attribute is used to create the html content */ overrideHTML = ParamConfig.BOOLEAN(true); /** @param value of the html content */ html = ParamConfig.STRING(DEFAULT_CSS3DOBJECT.html, { visibleIf: {overrideHTML: 1}, language: StringParamLanguage.HTML, }); } const ParamsConfig = new CSS3DObjectSopParamsConfig(); export class CSS3DObjectSopNode extends TypedSopNode<CSS3DObjectSopParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return SopType.CSS3D_OBJECT; } override initializeNode() { this.io.inputs.setCount(0, 1); this.io.inputs.initInputsClonedState(InputCloneMode.FROM_NODE); } override cook(inputCoreGroups: CoreGroup[]) { const coreGroup = inputCoreGroups[0]; if (coreGroup) { // if there are input objects, // add attributes to them const objects = coreGroup.allObjects(); for (const object of objects) { this._addAttributes(object); } this.setCoreGroup(coreGroup); } else { const object = new Object3D(); object.name = this.name(); this._addAttributes(object); this.setObjects([object]); } } private _addAttributes(object: ObjectContent<CoreObjectType>) { Poly.onObjectsAddRemoveHooks.assignOnAddHookHandler(object, this); // CoreCSSObjectAttribute.setNodeId(object, this.graphNodeId()); if (this.pv.overrideId) { CoreCSSObjectAttribute.setElementId(object, this.pv.id); } if (this.pv.overrideClassName) { CoreCSSObjectAttribute.setElementClass(object, this.pv.className); } if (this.pv.overrideHTML) { CoreCSSObjectAttribute.setElementHTML(object, this.pv.html); } CoreCSSObjectAttribute.setCopyAttributes(object, this.pv.copyAttributes); CoreCSSObjectAttribute.setAttributesToCopy(object, this.pv.attributesToCopy); CoreCSSObjectAttribute.setScale(object, this.pv.scale); } public override updateObjectOnAdd(object: Object3D, parent: Object3D) { const id = CoreCSSObjectAttribute.getElementId(object); const className = CoreCSSObjectAttribute.getElementClass(object); const html = CoreCSSObjectAttribute.getElementHTML(object); const copyAttributes = CoreCSSObjectAttribute.getCopyAttributes(object); const attributesToCopy = CoreCSSObjectAttribute.getAttributesToCopy(object); const scale = CoreCSSObjectAttribute.getScale(object); const attribNames: string[] = []; const CSSObject = createCSS3DObject({ object, id, className, html, copyAttributes, attributesToCopy: stringToAttribNames(attributesToCopy, attribNames), scale, }); replaceChild(parent, object, CSSObject); } }