@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
93 lines (92 loc) • 3.48 kB
JavaScript
"use strict";
import { DataTexture, Vector2, RGBAFormat, UnsignedByteType } from "three";
import { TypedCopNode } from "./_Base";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { TextureParamsController, TextureParamConfig } from "./utils/TextureParamsController";
import { DEFAULT_FONT_URL_TTF } from "../../../core/Assets";
import { EXTENSIONS_BY_NODE_TYPE_BY_CONTEXT } from "../../../core/loader/FileExtensionRegister";
import { CopType } from "../../poly/registers/nodes/types/Cop";
import { NodeContext } from "../../poly/NodeContext";
import { loadAndUseFont } from "../../../core/Text";
import { sanitizeName } from "../../../core/String";
const _v2 = new Vector2();
export function TextCopNodeParamConfig(Base) {
return class Mixin extends Base {
constructor() {
super(...arguments);
/** @param font used */
this.font = ParamConfig.STRING(DEFAULT_FONT_URL_TTF, {
fileBrowse: { extensions: EXTENSIONS_BY_NODE_TYPE_BY_CONTEXT[NodeContext.COP][CopType.TEXT] }
});
/** @param text created */
this.text = ParamConfig.STRING("polygonjs", {
multiline: true
});
/** @param render resolution */
this.resolution = ParamConfig.VECTOR2([256, 256]);
/** @param font size */
this.fontSize = ParamConfig.INTEGER(32, {
range: [0, 256],
rangeLocked: [true, false]
});
/** @param background color */
this.bgColor = ParamConfig.COLOR([0, 0, 0]);
/** @param background alpha */
this.bgAlpha = ParamConfig.FLOAT(0);
/** @param text color */
this.textColor = ParamConfig.COLOR([1, 1, 1]);
/** @param text alpha */
this.textAlpha = ParamConfig.FLOAT(1);
}
};
}
class TextCopParamConfig extends TextureParamConfig(TextCopNodeParamConfig(NodeParamsConfig)) {
}
const ParamsConfig = new TextCopParamConfig();
export class TextCopNode extends TypedCopNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this.textureParamsController = new TextureParamsController(this);
}
static type() {
return CopType.TEXT;
}
async cook() {
this._dataTexture = this._findOrCreateDataTexture();
const url = this.pv.font.split("/");
const fontNameFromUrl = url[url.length - 1].split(".")[0];
await loadAndUseFont({
texture: this._dataTexture,
text: this.pv.text,
fontFamily: sanitizeName(this.path()) + fontNameFromUrl,
fontSize: this.pv.fontSize,
fontUrl: this.pv.font,
resolution: this.pv.resolution,
bgColor: this.pv.bgColor,
bgAlpha: this.pv.bgAlpha,
textColor: this.pv.textColor,
textAlpha: this.pv.textAlpha
});
await this.textureParamsController.update(this._dataTexture);
this.setTexture(this._dataTexture);
}
_dataTextureResolutionValid(texture) {
const image = texture.source.data;
this._requestedResolution(_v2);
return image.width == _v2.x && image.height == _v2.y;
}
_requestedResolution(target) {
target.copy(this.pv.resolution);
}
_findOrCreateDataTexture() {
this._requestedResolution(_v2);
if (this._dataTexture && this._dataTextureResolutionValid(this._dataTexture)) {
return this._dataTexture;
}
const size = _v2.x * _v2.y * 4;
const pixelBuffer = new Uint8Array(size);
const dataTexture = new DataTexture(pixelBuffer, _v2.x, _v2.y, RGBAFormat, UnsignedByteType);
return dataTexture;
}
}