@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
118 lines (114 loc) • 4.75 kB
text/typescript
/**
* 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);
}
}