UNPKG

@polygonjs/polygonjs

Version:

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

93 lines (92 loc) 3.48 kB
"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; } }