UNPKG

@polygonjs/polygonjs

Version:

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

125 lines (120 loc) 4.85 kB
/** * Creates CSS2DObjects. * * @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 {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig'; import {StringParamLanguage} from '../../params/utils/OptionsController'; import {SopType} from '../../poly/registers/nodes/types/Sop'; import {Poly} from '../../Poly'; import {CoreCSSObjectAttribute, DEFAULT_CSS2DOBJECT} from '../../../core/render/CSSRenderers/CSSObjectAttribute'; import {createCSS2DObject} from '../../../core/render/CSSRenderers/CSS2DObject'; import {stringToAttribNames} from '../../../core/String'; import {Object3D} from 'three'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {replaceChild} from '../../poly/PolyOnObjectsAddRemoveHooksController'; import {CoreObjectType, ObjectContent} from '../../../core/geometry/ObjectContent'; class CSS2DObjectSopParamsConfig 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 defines if the htmlId 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_CSS2DOBJECT.id, { visibleIf: {overrideId: 1}, }); /** @param defines if the htmlClass attribute is used to create the html class */ overrideClassName = ParamConfig.BOOLEAN(true); /** @param value of the html class */ className = ParamConfig.STRING(DEFAULT_CSS2DOBJECT.className, { visibleIf: {overrideClassName: 1}, }); /** @param defines if the html attribute is used to create the html content */ overrideHTML = ParamConfig.BOOLEAN(true); /** @param value of the html content */ html = ParamConfig.STRING(DEFAULT_CSS2DOBJECT.html, { visibleIf: {overrideHTML: 1}, language: StringParamLanguage.HTML, }); } const ParamsConfig = new CSS2DObjectSopParamsConfig(); export class CSS2DObjectSopNode extends TypedSopNode<CSS2DObjectSopParamsConfig> { override paramsConfig = ParamsConfig; static override type() { return SopType.CSS2D_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 threejs objects, // add attributes to them const objects = coreGroup.allObjects(); for (const object of objects) { this._addAttributes(object); } this.setCoreGroup(coreGroup); } else { // if no input, create CSS object // and also add attributes. // Even if the attributes can be redundant, // they give clues that they can be changed // to update the output const attribNames: string[] = []; const group = createCSS2DObject({ id: this.pv.id, className: this.pv.className, html: this.pv.html, copyAttributes: this.pv.copyAttributes, attributesToCopy: stringToAttribNames(this.pv.attributesToCopy, attribNames), }); group.name = this.name(); this._addAttributes(group); this.setObjects([group]); } } private _addAttributes(object: ObjectContent<CoreObjectType>) { Poly.onObjectsAddRemoveHooks.assignOnAddHookHandler(object, this); 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); } 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 attribNames: string[] = []; const CSSObject = createCSS2DObject({ object, id, className, html, copyAttributes, attributesToCopy: stringToAttribNames(attributesToCopy, attribNames), }); replaceChild(parent, object, CSSObject); } }