polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
111 lines (93 loc) • 3 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 CSS3DRenderer to display them
*
*
*/
import {TypedSopNode} from './_Base';
import {CSS3DObject} from '../../../modules/three/examples/jsm/renderers/CSS3DRenderer';
import {CoreGroup} from '../../../core/geometry/Group';
interface Css2DObjectParams {
className: string;
text: string;
}
const ATTRIBUTE_NAME = {
className: 'class',
text: 'text',
};
const DEFAULT_VALUE = {
className: 'css2DObject',
text: 'default text',
};
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
class Css3DObjectSopParamsConfig extends NodeParamsConfig {
/** @param html class */
className = ParamConfig.STRING(DEFAULT_VALUE.className);
/** @param text content */
text = ParamConfig.STRING(DEFAULT_VALUE.text, {
multiline: true,
});
}
const ParamsConfig = new Css3DObjectSopParamsConfig();
export class Css3DObjectSopNode extends TypedSopNode<Css3DObjectSopParamsConfig> {
params_config = ParamsConfig;
static type() {
return 'css3DObject';
}
initializeNode() {
this.io.inputs.setCount(0, 1);
}
cook(input_contents: CoreGroup[]) {
const core_group = input_contents[0];
if (core_group) {
this._create_objects_from_input_points(core_group);
} else {
this._create_object_from_scratch();
}
}
private _create_objects_from_input_points(core_group: CoreGroup) {
const points = core_group.points();
const objects: CSS3DObject[] = [];
for (let point of points) {
const className = (point.attribValue(ATTRIBUTE_NAME.className) as string) || DEFAULT_VALUE.className;
const text = (point.attribValue(ATTRIBUTE_NAME.text) as string) || DEFAULT_VALUE.text;
const object = Css3DObjectSopNode.create_css_object({
className,
text,
});
object.position.copy(point.position());
object.updateMatrix();
objects.push(object);
}
this.setObjects(objects);
}
private _create_object_from_scratch() {
const object = Css3DObjectSopNode.create_css_object({
className: this.pv.className,
text: this.pv.text,
});
Css3DObjectSopNode._assign_clone_method(object);
this.setObjects([object]);
}
private static create_css_object(params: Css2DObjectParams) {
const element = document.createElement('div');
element.className = params.className;
element.textContent = params.text;
const object = new CSS3DObject(element);
object.matrixAutoUpdate = true;
Css3DObjectSopNode._assign_clone_method(object);
return object;
}
private static _assign_clone_method(css_object: CSS3DObject) {
css_object.clone = () => Css3DObjectSopNode.clone_css_object(css_object);
}
static clone_css_object(css_object: CSS3DObject) {
const new_object = new CSS3DObject(css_object.element);
new_object.matrixAutoUpdate = css_object.matrixAutoUpdate;
this._assign_clone_method(new_object);
return new_object;
}
}