phaser4-rex-plugins
Version:
625 lines (494 loc) • 16.8 kB
JavaScript
import DefaultPropertyMap from './PropertyMap.js';
import MeasureText from './MeasureText.js';
import CONST from '../const.js';
import WRAPMODE from './WrapModes.js';
import GetStyle from '../../../utils/canvas/GetStyle.js';
const GetAdvancedValue = Phaser.Utils.Objects.GetAdvancedValue;
const GetValue = Phaser.Utils.Objects.GetValue;
class TextStyle {
constructor(text, style, propertyMap) {
this.parent = text;
// parent.updateText()
// parent.width, parent.height
if (propertyMap === undefined) {
propertyMap = DefaultPropertyMap;
}
this.propertyMap = propertyMap;
this.backgroundColor;
this.backgroundColor2;
this.backgroundHorizontalGradient;
this.backgroundStrokeColor;
this.backgroundStrokeLineWidth;
this.backgroundCornerRadius;
this.backgroundCornerIteration;
this.fontFamily;
this.fontSize;
this.fontStyle;
this.color;
this.stroke;
this.strokeThickness;
this.shadowOffsetX;
this.shadowOffsetY;
this.shadowColor;
this.shadowBlur;
this.shadowStroke;
this.shadowFill;
this.underlineColor;
this.underlineThickness;
this.underlineOffset;
this.strikethroughColor;
this.strikethroughThickness;
this.strikethroughOffset;
this.halign;
this.valign;
this.maxLines;
this.fixedWidth;
this.fixedHeight;
this.resolution;
this.xOffset;
this.rtl;
this.testString;
this.baselineX;
this.baselineY;
this.wrapMode;
this.wrapWidth;
this.wrapCallback;
this.wrapCallbackScope;
this._font;
// Set to defaults + user style
this.setStyle(style, false, true);
}
get isWrapFitMode() {
return (this.fixedWidth > 0) && (this.wrapMode !== CONST.NO_WRAP) && (this.wrapWidth === 0);
}
setStyle(style, updateText, setDefaults) {
if (updateText === undefined) {
updateText = true;
}
if (setDefaults === undefined) {
setDefaults = false;
}
// Compatible with Text game object
if (style && style.hasOwnProperty('wordWrap')) {
var wordWrap = style.wordWrap;
if (wordWrap.hasOwnProperty('width')) {
style.wrap = {
mode: 'word',
width: wordWrap.width,
}
}
}
if (style && style.hasOwnProperty('wrap')) {
var wrap = style.wrap;
if (wrap.hasOwnProperty('mode')) {
var mode = wrap.mode;
if (typeof mode === 'string') {
wrap.mode = WRAPMODE[mode];
}
} else {
if (wrap.hasOwnProperty('width')) {
wrap.mode = 1;
}
}
}
// default halign of RTL is 'right'
if (style && style.rtl && setDefaults && (!style.hasOwnProperty('halign'))) {
style.halign = 'right';
}
// Avoid type mutation
if (style && style.hasOwnProperty('fontSize') && typeof style.fontSize === 'number') {
style.fontSize = style.fontSize.toString() + 'px';
}
var propertyMap = this.propertyMap;
for (var key in propertyMap) {
var prop = propertyMap[key]; // [ Object Key, Default Value, preCallback ]
var objKey = prop[0];
var defaultValue = (setDefaults) ? prop[1] : this[key];
var postCallback = prop[2];
if (key === 'wrapCallback' || key === 'wrapCallbackScope') {
// Callback & scope should be set without processing the values
this[key] = GetValue(style, objKey, defaultValue);
} else {
var value = GetAdvancedValue(style, objKey, defaultValue);
if (postCallback) {
value = postCallback(value);
}
this[key] = value;
}
}
// Allow for 'font' override
var font = GetValue(style, 'font', null);
if (font === null) {
this._font = this.fontStyle + ' ' + this.fontSize + ' ' + this.fontFamily;
} else {
this._font = font;
}
// Allow for 'fill' to be used in place of 'color'
var fill = GetValue(style, 'fill', null);
if (fill !== null) {
this.color = GetStyle(fill);
}
var metrics = GetValue(style, 'metrics', false);
// Provide optional TextMetrics in the style object to avoid the canvas look-up / scanning
// Doing this is reset if you then change the font of this TextStyle after creation
if (metrics) {
this.metrics = {
ascent: GetValue(metrics, 'ascent', 0),
descent: GetValue(metrics, 'descent', 0),
fontSize: GetValue(metrics, 'fontSize', 0)
};
} else if (updateText || (!this.metrics)) {
this.metrics = MeasureText(this);
}
if (updateText) {
return this.parent.updateText();
} else {
return this.parent;
}
}
syncFont(canvas, context) {
context.font = this._font;
}
syncStyle(canvas, context) {
context.textBaseline = 'alphabetic';
context.fillStyle = this.color;
context.strokeStyle = this.stroke;
context.lineWidth = this.strokeThickness;
context.lineCap = 'round';
context.lineJoin = 'round';
}
syncShadow(context, enabled) {
if (enabled) {
context.shadowOffsetX = this.shadowOffsetX;
context.shadowOffsetY = this.shadowOffsetY;
context.shadowColor = this.shadowColor;
context.shadowBlur = this.shadowBlur;
} else {
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowColor = 0;
context.shadowBlur = 0;
}
}
update(recalculateMetrics) {
if (recalculateMetrics) {
this._font = `${this.fontStyle} ${this.fontSize} ${this.fontFamily}`.trim();
this.metrics = MeasureText(this);
}
return this.parent.updateText(recalculateMetrics);
}
buildFont() {
var newFont = `${this.fontStyle} ${this.fontSize} ${this.fontFamily}`.trim();
if (newFont !== this._font) {
this._font = newFont;
//this.metrics = MeasureText(this);
}
return this;
}
setFont(font) {
if (typeof font === 'string') {
this.fontFamily = font;
this.fontSize = '';
this.fontStyle = '';
} else {
this.fontFamily = GetValue(font, 'fontFamily', 'Courier');
this.fontSize = GetValue(font, 'fontSize', '16px');
this.fontStyle = GetValue(font, 'fontStyle', '');
}
return this.update(true);
}
setFontFamily(family) {
this.fontFamily = family;
return this.update(true);
}
setFontStyle(style) {
this.fontStyle = style;
return this.update(true);
}
setFontSize(size) {
if (typeof size === 'number') {
size = size.toString() + 'px';
}
this.fontSize = size;
return this.update(true);
}
setTestString(string) {
this.testString = string;
return this.update(true);
}
setFixedSize(width, height) {
this.fixedWidth = width;
this.fixedHeight = height;
if (width) {
this.parent.width = width;
}
if (height) {
this.parent.height = height;
}
return this.update(this.isWrapFitMode);
}
setResolution(value) {
this.resolution = value;
return this.update(false);
}
setXOffset(value) {
this.xOffset = value;
return this.update(false);
}
setBackgroundColor(color, color2, isHorizontalGradient) {
if (isHorizontalGradient === undefined) {
isHorizontalGradient = true;
}
this.backgroundColor = GetStyle(color, this.parent.canvas, this.parent.context);
this.backgroundColor2 = GetStyle(color2, this.parent.canvas, this.parent.context);
this.backgroundHorizontalGradient = isHorizontalGradient;
return this.update(false);
}
setBackgroundStrokeColor(color, lineWidth) {
this.backgroundStrokeColor = GetStyle(color, this.parent.canvas, this.parent.context);
this.backgroundStrokeLineWidth = lineWidth;
return this.update(false);
}
setBackgroundCornerRadius(radius, iteration) {
this.backgroundCornerRadius = radius;
this.backgroundCornerIteration = iteration;
return this.update(false);
}
setFill(color) {
this.color = GetStyle(color, this.parent.canvas, this.parent.context);
return this.update(false);
}
setColor(color) {
this.color = GetStyle(color, this.parent.canvas, this.parent.context);
return this.update(false);
}
setStroke(color, thickness) {
if (color === undefined) {
// Reset the stroke to zero (disabling it)
this.strokeThickness = 0;
} else {
if (thickness === undefined) {
thickness = this.strokeThickness;
}
this.stroke = GetStyle(color, this.parent.canvas, this.parent.context);
this.strokeThickness = thickness;
}
return this.update(true);
}
setShadow(x, y, color, blur, shadowStroke, shadowFill) {
if (x === undefined) {
x = 0;
}
if (y === undefined) {
y = 0;
}
if (color === undefined) {
color = '#000';
}
if (blur === undefined) {
blur = 0;
}
if (shadowStroke === undefined) {
shadowStroke = false;
}
if (shadowFill === undefined) {
shadowFill = true;
}
this.shadowOffsetX = x;
this.shadowOffsetY = y;
this.shadowColor = GetStyle(color, this.parent.canvas, this.parent.context);
this.shadowBlur = blur;
this.shadowStroke = shadowStroke;
this.shadowFill = shadowFill;
return this.update(false);
}
setShadowOffset(x, y) {
if (x === undefined) {
x = 0;
}
if (y === undefined) {
y = x;
}
this.shadowOffsetX = x;
this.shadowOffsetY = y;
return this.update(false);
}
setShadowColor(color) {
if (color === undefined) {
color = '#000';
}
this.shadowColor = GetStyle(color, this.parent.canvas, this.parent.context);
return this.update(false);
}
setShadowBlur(blur) {
if (blur === undefined) {
blur = 0;
}
this.shadowBlur = blur;
return this.update(false);
}
setShadowStroke(enabled) {
this.shadowStroke = enabled;
return this.update(false);
}
setShadowFill(enabled) {
this.shadowFill = enabled;
return this.update(false);
}
setUnderline(color, thickness, offset) {
if (color === undefined) {
color = '#000';
}
if (thickness === undefined) {
thickness = 0;
}
if (offset === undefined) {
offset = 0;
}
this.underlineColor = GetStyle(color, this.parent.canvas, this.parent.context);
this.underlineThickness = thickness;
this.underlineOffset = offset;
return this.update(false);
}
setUnderlineColor(color) {
if (color === undefined) {
color = '#000';
}
this.underlineColor = GetStyle(color, this.parent.canvas, this.parent.context);
return this.update(false);
}
setUnderlineThickness(thickness) {
if (thickness === undefined) {
thickness = 0;
}
this.underlineThickness = thickness;
return this.update(false);
}
setUnderlineOffset(offset) {
if (offset === undefined) {
offset = 0;
}
this.underlineOffset = offset;
return this.update(false);
}
setStrikethrough(color, thickness, offset) {
if (color === undefined) {
color = '#000';
}
if (thickness === undefined) {
thickness = 0;
}
if (offset === undefined) {
offset = 0;
}
this.strikethroughColor = GetStyle(color, this.parent.canvas, this.parent.context);
this.strikethroughThickness = thickness;
this.strikethroughOffset = offset;
return this.update(false);
}
setStrikethroughColor(color) {
if (color === undefined) {
color = '#000';
}
this.strikethroughColor = GetStyle(color, this.parent.canvas, this.parent.context);
return this.update(false);
}
setStrikethroughThickness(thickness) {
if (thickness === undefined) {
thickness = 0;
}
this.strikethroughThickness = thickness;
return this.update(false);
}
setStrikethroughOffset(offset) {
if (offset === undefined) {
offset = 0;
}
this.strikethroughOffset = offset;
return this.update(false);
}
setWrapMode(mode) {
if (typeof mode === 'string') {
mode = WRAPMODE[mode.toLowerCase()] || 0;
}
this.wrapMode = mode;
return this.update(true);
}
setWrapWidth(width) {
this.wrapWidth = width;
return this.update(false);
}
setAlign(halign, valign) {
if (halign === undefined) {
halign = 'left';
}
if (valign === undefined) {
valign = 'top';
}
this.halign = halign;
this.valign = valign;
return this.update(false);
}
setHAlign(halign) {
if (halign === undefined) {
halign = 'left';
}
this.halign = halign;
return this.update(false);
}
setVAlign(valign) {
if (valign === undefined) {
valign = 'top';
}
this.valign = valign;
return this.update(false);
}
setMaxLines(max) {
if (max === undefined) {
max = 0;
}
this.maxLines = max;
return this.update(false);
}
getTextMetrics() {
var metrics = this.metrics;
return {
ascent: metrics.ascent,
descent: metrics.descent,
fontSize: metrics.fontSize
};
}
setTextMetrics(metrics, font) {
this.metrics.ascent = metrics.ascent;
this.metrics.descent = metrics.descent;
this.metrics.fontSize = metrics.fontSize;
if (font) {
if (typeof font === 'string') {
this.fontFamily = font;
this.fontSize = '';
this.fontStyle = '';
} else {
this.fontFamily = GetValue(font, 'fontFamily', this.fontFamily);
this.fontSize = GetValue(font, 'fontSize', this.fontSize);
this.fontStyle = GetValue(font, 'fontStyle', this.fontStyle);
}
}
return this.parent.updateText(true);
}
get lineHeight() {
return this.metrics.fontSize + this.parent.lineSpacing;
}
toJSON() {
var output = {};
var propertyMap = this.propertyMap;
for (var key in propertyMap) {
output[key] = this[key];
}
output.metrics = this.getTextMetrics();
return output;
}
destroy() {
this.parent = undefined;
}
}
export default TextStyle;