@lightningjs/renderer
Version:
Lightning 3 Renderer
236 lines • 8.75 kB
JavaScript
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 Comcast Cable Communications Management, LLC.
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CoreNode, UpdateType } from './CoreNode.js';
import { assertTruthy } from '../utils.js';
import { Matrix3d } from './lib/Matrix3d.js';
export var CanvasTextUpdateType;
(function (CanvasTextUpdateType) {
CanvasTextUpdateType[CanvasTextUpdateType["None"] = 0] = "None";
CanvasTextUpdateType[CanvasTextUpdateType["Text"] = 1] = "Text";
CanvasTextUpdateType[CanvasTextUpdateType["Font"] = 2] = "Font";
CanvasTextUpdateType[CanvasTextUpdateType["All"] = 4] = "All";
// TextAlign = 4,
// TextBaseline = 8,
// MaxWidth = 16,
// LineHeight = 32,
})(CanvasTextUpdateType || (CanvasTextUpdateType = {}));
/**
* An CoreNode in the Renderer scene graph that renders text using Canvas 2D.
*
* @remarks
* A Text Node is the second graphical building block of the Renderer scene
* graph. It renders text using a specific text renderer that is automatically
* chosen based on the font requested and what type of fonts are installed
* into an app.
*
* The text renderer can be overridden by setting the `textRendererOverride`
*
* The `texture` and `shader` properties are managed by loaded text renderer and
* should not be set directly.
*
* For non-text rendering, see {@link CoreNode}.
*/
export class CoreTextCanvasNode extends CoreNode {
textUpdateType = CanvasTextUpdateType.None;
textProps = {};
textRenderer;
fontLoaded = false;
constructor(stage, props, textRenderer) {
super(stage, props);
this.textProps = {
text: props.text,
fontSize: props.fontSize,
fontFamily: props.fontFamily,
fontStretch: props.fontStretch,
fontStyle: props.fontStyle,
fontWeight: props.fontWeight,
textAlign: props.textAlign,
contain: props.contain,
letterSpacing: props.letterSpacing,
lineHeight: props.lineHeight,
maxLines: props.maxLines,
textBaseline: props.textBaseline,
verticalAlign: props.verticalAlign,
overflowSuffix: props.overflowSuffix,
wordWrap: props.contain !== 'none',
debug: props.debug ?? false,
};
// set the font style string
this.textProps.fontStyleString = [
props.fontStretch,
props.fontStyle,
props.fontWeight,
].join(' ');
// locking it to Canvas 2D for now
this.textRenderer = textRenderer;
this.setTextUpdateType(CanvasTextUpdateType.All);
}
setTextUpdateType(updateType) {
this.textUpdateType = updateType;
}
// handle text updates first
update(delta, parentClippingRect) {
super.update(delta, parentClippingRect);
if (this.fontLoaded === false && this.textUpdateType !== CanvasTextUpdateType.Font) {
this.processFont();
}
// No need to do any text updates if the font is not loaded
if (this.fontLoaded === false) {
return;
}
if (this.textUpdateType === CanvasTextUpdateType.Text) {
this.updateText();
}
this.textUpdateType = CanvasTextUpdateType.None;
}
updateText() {
const { textProps } = this;
const texture = this.textRenderer.renderText(this.props, this.fontFace);
if (texture !== null) {
this.texture = texture;
}
}
async updateFont() {
if (this.textRenderer.isFontLoaded() === true) {
this.fountFace = this.textRenderer.getFontFace();
this.fontLoaded = true;
return;
}
this.fontFace = await this.textRenderer.loadFont(this.fontSize, this.fontFamily, this.fontStretch, this.fontStyle, this.fontWeight);
this.fontLoaded = true;
}
get text() {
return this.textProps.text || '';
}
set text(value) {
this.textProps.text = value || '';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get fontSize() {
assertTruthy(this.textProps.fontSize !== undefined, 'fontSize');
return this.textProps.fontSize;
}
set fontSize(value) {
this.textProps.fontSize = value;
this.setTextUpdateType(CanvasTextUpdateType.Font);
}
get fontFamily() {
assertTruthy(this.textProps.fontFamily !== undefined, 'fontFamily');
return this.textProps.fontFamily;
}
set fontFamily(value) {
this.textProps.fontFamily = value;
this.setTextUpdateType(CanvasTextUpdateType.Font);
}
get fontStretch() {
assertTruthy(this.textProps.fontStretch !== undefined, 'fontStretch');
return this.textProps.fontStretch;
}
set fontStretch(value) {
this.textProps.fontStretch = value || 'normal';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get fontStyle() {
assertTruthy(this.textProps.fontStyle !== undefined, 'fontStyle');
return this.textProps.fontStyle;
}
set fontStyle(value) {
this.textProps.fontStyle = value || 'normal';
this.setTextUpdateType(CanvasTextUpdateType.Font | CanvasTextUpdateType.Text);
}
get fontWeight() {
assertTruthy(this.textProps.fontWeight !== undefined, 'fontWeight');
return this.textProps.fontWeight;
}
set fontWeight(value) {
this.textProps.fontWeight = value || 'normal';
this.setTextUpdateType(CanvasTextUpdateType.Font | CanvasTextUpdateType.Text);
}
get textAlign() {
assertTruthy(this.textProps.textAlign !== undefined, 'textAlign');
return this.textProps.textAlign;
}
set textAlign(value) {
this.textProps.textAlign = value || 'left';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get contain() {
assertTruthy(this.textProps.contain !== undefined, 'contain');
return this.textProps.contain;
}
set contain(value) {
this.textProps.contain = value || 'none';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get letterSpacing() {
assertTruthy(this.textProps.letterSpacing !== undefined, 'letterSpacing');
return this.textProps.letterSpacing;
}
set letterSpacing(value) {
this.textProps.letterSpacing = value || 0;
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get lineHeight() {
return this.textProps.lineHeight;
}
set lineHeight(value) {
this.textProps.lineHeight = value;
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get maxLines() {
assertTruthy(this.textProps.maxLines !== undefined, 'maxLines');
return this.textProps.maxLines;
}
set maxLines(value) {
this.textProps.maxLines = value || 0;
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get textBaseline() {
assertTruthy(this.textProps.textBaseline !== undefined, 'textBaseline');
return this.textProps.textBaseline;
}
set textBaseline(value) {
this.textProps.textBaseline = value || 'alphabetic';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get verticalAlign() {
assertTruthy(this.textProps.verticalAlign !== undefined, 'verticalAlign');
return this.textProps.verticalAlign;
}
set verticalAlign(value) {
this.textProps.verticalAlign = value || 'middle';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get overflowSuffix() {
assertTruthy(this.textProps.overflowSuffix !== undefined, 'overflowSuffix');
return this.textProps.overflowSuffix;
}
set overflowSuffix(value) {
this.textProps.overflowSuffix = value || '...';
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
get debug() {
return this.textProps.debug;
}
set debug(value) {
this.textProps.debug = value;
this.setTextUpdateType(CanvasTextUpdateType.Text);
}
}
//# sourceMappingURL=CoreTextNodeCanvas.js.map