2017-11-30 01:20:02 +00:00
|
|
|
var AddToDOM = require('../../../dom/AddToDOM');
|
|
|
|
var CanvasPool = require('../../../display/canvas/CanvasPool');
|
2017-03-15 01:07:58 +00:00
|
|
|
var Class = require('../../../utils/Class');
|
2017-07-04 00:59:31 +00:00
|
|
|
var Components = require('../../components');
|
2017-11-30 01:20:02 +00:00
|
|
|
var GameObject = require('../../GameObject');
|
|
|
|
var GetTextSize = require('../GetTextSize');
|
2017-11-30 17:17:18 +00:00
|
|
|
var GetValue = require('../../../utils/object/GetValue');
|
2017-11-30 01:20:02 +00:00
|
|
|
var RemoveFromDOM = require('../../../dom/RemoveFromDOM');
|
2017-03-13 23:38:48 +00:00
|
|
|
var TextRender = require('./TextRender');
|
|
|
|
var TextStyle = require('../TextStyle');
|
|
|
|
|
|
|
|
var Text = new Class({
|
|
|
|
|
2017-04-05 01:10:48 +00:00
|
|
|
Extends: GameObject,
|
|
|
|
|
2017-03-13 23:38:48 +00:00
|
|
|
Mixins: [
|
|
|
|
Components.Alpha,
|
|
|
|
Components.BlendMode,
|
2017-07-04 11:01:27 +00:00
|
|
|
Components.Flip,
|
2017-03-13 23:38:48 +00:00
|
|
|
Components.GetBounds,
|
|
|
|
Components.Origin,
|
2017-04-11 13:15:38 +00:00
|
|
|
Components.RenderTarget,
|
2017-03-13 23:38:48 +00:00
|
|
|
Components.ScaleMode,
|
2017-07-04 11:01:27 +00:00
|
|
|
Components.ScrollFactor,
|
|
|
|
Components.Tint,
|
2017-03-13 23:38:48 +00:00
|
|
|
Components.Transform,
|
|
|
|
Components.Visible,
|
|
|
|
TextRender
|
|
|
|
],
|
|
|
|
|
|
|
|
initialize:
|
|
|
|
|
2017-07-14 13:30:20 +00:00
|
|
|
function Text (scene, x, y, text, style)
|
2017-03-13 23:38:48 +00:00
|
|
|
{
|
2017-03-15 01:07:58 +00:00
|
|
|
if (x === undefined) { x = 0; }
|
|
|
|
if (y === undefined) { y = 0; }
|
|
|
|
|
2017-07-14 13:30:20 +00:00
|
|
|
GameObject.call(this, scene, 'Text');
|
2017-03-13 23:38:48 +00:00
|
|
|
|
|
|
|
this.setPosition(x, y);
|
2017-03-20 16:28:09 +00:00
|
|
|
this.setOrigin(0, 0);
|
2017-03-13 23:38:48 +00:00
|
|
|
|
2017-03-15 01:07:58 +00:00
|
|
|
/**
|
|
|
|
* @property {HTMLCanvasElement} canvas - The canvas element that the text is rendered.
|
|
|
|
*/
|
|
|
|
this.canvas = CanvasPool.create(this);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {HTMLCanvasElement} context - The context of the canvas element that the text is rendered to.
|
|
|
|
*/
|
|
|
|
this.context = this.canvas.getContext('2d');
|
|
|
|
|
|
|
|
this.style = new TextStyle(this, style);
|
|
|
|
|
2017-03-15 23:08:59 +00:00
|
|
|
this.autoRound = true;
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The Regular Expression that is used to split the text up into lines, in
|
|
|
|
* multi-line text. By default this is `/(?:\r\n|\r|\n)/`.
|
|
|
|
* You can change this RegExp to be anything else that you may need.
|
|
|
|
* @property {Object} splitRegExp
|
|
|
|
*/
|
|
|
|
this.splitRegExp = /(?:\r\n|\r|\n)/;
|
|
|
|
|
2017-11-30 00:03:22 +00:00
|
|
|
// This is populated in this.setText
|
|
|
|
this.text = '';
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
this.resolution = 1;
|
|
|
|
|
2017-04-26 14:34:15 +00:00
|
|
|
/**
|
|
|
|
* Specify a padding value which is added to the line width and height when calculating the Text size.
|
2017-11-30 17:17:18 +00:00
|
|
|
* Allows you to add extra spacing if the browser is unable to accurately determine the true font dimensions.
|
2017-04-26 14:34:15 +00:00
|
|
|
* @property {Phaser.Point} padding
|
|
|
|
*/
|
2017-11-30 17:17:18 +00:00
|
|
|
this.padding = { left: 0, right: 0, top: 0, bottom: 0 };
|
2017-03-15 01:07:58 +00:00
|
|
|
|
2017-03-15 23:08:59 +00:00
|
|
|
this.width = 1;
|
|
|
|
this.height = 1;
|
|
|
|
|
2017-03-21 20:45:57 +00:00
|
|
|
this.canvasTexture = null;
|
2017-03-21 21:06:36 +00:00
|
|
|
this.dirty = false;
|
2017-03-21 20:08:43 +00:00
|
|
|
|
2017-11-30 01:20:02 +00:00
|
|
|
this.initRTL();
|
|
|
|
|
2017-11-30 17:17:18 +00:00
|
|
|
if (style && style.padding)
|
|
|
|
{
|
|
|
|
this.setPadding(style.padding);
|
|
|
|
}
|
|
|
|
|
2017-11-30 00:03:22 +00:00
|
|
|
this.setText(text);
|
2017-09-13 20:54:32 +00:00
|
|
|
|
|
|
|
var _this = this;
|
2017-09-29 11:58:47 +00:00
|
|
|
|
|
|
|
scene.sys.game.renderer.addContextRestoredCallback(function ()
|
|
|
|
{
|
2017-09-13 20:54:32 +00:00
|
|
|
_this.canvasTexture = null;
|
|
|
|
_this.dirty = true;
|
|
|
|
});
|
2017-03-15 01:07:58 +00:00
|
|
|
},
|
|
|
|
|
2017-11-30 01:20:02 +00:00
|
|
|
initRTL: function ()
|
|
|
|
{
|
|
|
|
if (!this.style.rtl)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Here is where the crazy starts.
|
|
|
|
//
|
|
|
|
// Due to browser implementation issues, you cannot fillText BiDi text to a canvas
|
|
|
|
// that is not part of the DOM. It just completely ignores the direction property.
|
|
|
|
|
|
|
|
this.canvas.dir = 'rtl';
|
|
|
|
|
|
|
|
// Experimental atm, but one day ...
|
|
|
|
this.context.direction = 'rtl';
|
|
|
|
|
|
|
|
// Add it to the DOM, but hidden within the parent canvas.
|
|
|
|
this.canvas.style.display = 'none';
|
|
|
|
|
|
|
|
AddToDOM(this.canvas, this.scene.sys.canvas);
|
|
|
|
|
|
|
|
// And finally we set the x origin
|
|
|
|
this.originX = 1;
|
|
|
|
},
|
|
|
|
|
2017-03-15 23:44:39 +00:00
|
|
|
setText: function (value)
|
|
|
|
{
|
2017-03-20 16:48:04 +00:00
|
|
|
if (Array.isArray(value))
|
|
|
|
{
|
|
|
|
value = value.join('\n');
|
|
|
|
}
|
|
|
|
|
2017-03-15 23:44:39 +00:00
|
|
|
if (value !== this.text)
|
|
|
|
{
|
2017-05-24 04:59:14 +00:00
|
|
|
this.text = value.toString();
|
2017-03-20 16:48:04 +00:00
|
|
|
|
2017-03-15 23:44:39 +00:00
|
|
|
this.updateText();
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2017-03-16 17:15:58 +00:00
|
|
|
setStyle: function (style)
|
|
|
|
{
|
|
|
|
return this.style.setStyle(style);
|
|
|
|
},
|
|
|
|
|
2017-03-20 16:28:09 +00:00
|
|
|
setFont: function (font)
|
|
|
|
{
|
|
|
|
return this.style.setFont(font);
|
|
|
|
},
|
|
|
|
|
2017-11-30 17:17:18 +00:00
|
|
|
setFontFamily: function (family)
|
|
|
|
{
|
|
|
|
return this.style.setFontFamily(family);
|
|
|
|
},
|
|
|
|
|
|
|
|
setFontSize: function (size)
|
|
|
|
{
|
|
|
|
return this.style.setFontSize(size);
|
|
|
|
},
|
|
|
|
|
|
|
|
setFontStyle: function (style)
|
|
|
|
{
|
|
|
|
return this.style.setFontStyle(style);
|
|
|
|
},
|
|
|
|
|
2017-03-20 16:28:09 +00:00
|
|
|
setFixedSize: function (width, height)
|
|
|
|
{
|
|
|
|
return this.style.setFixedSize(width, height);
|
|
|
|
},
|
|
|
|
|
|
|
|
setBackgroundColor: function (color)
|
|
|
|
{
|
|
|
|
return this.style.setBackgroundColor(color);
|
|
|
|
},
|
|
|
|
|
2017-12-01 03:11:41 +00:00
|
|
|
setFill: function (color)
|
|
|
|
{
|
|
|
|
return this.style.setFill(color);
|
|
|
|
},
|
|
|
|
|
2017-11-30 17:17:18 +00:00
|
|
|
setColor: function (color)
|
2017-03-20 16:28:09 +00:00
|
|
|
{
|
2017-11-30 17:17:18 +00:00
|
|
|
return this.style.setColor(color);
|
2017-03-20 16:28:09 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
setStroke: function (color, thickness)
|
|
|
|
{
|
|
|
|
return this.style.setStroke(color, thickness);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadow: function (x, y, color, blur, shadowStroke, shadowFill)
|
|
|
|
{
|
|
|
|
return this.style.setShadow(x, y, color, blur, shadowStroke, shadowFill);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadowOffset: function (x, y)
|
|
|
|
{
|
|
|
|
return this.style.setShadowOffset(x, y);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadowColor: function (color)
|
|
|
|
{
|
|
|
|
return this.style.setShadowColor(color);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadowBlur: function (blur)
|
|
|
|
{
|
|
|
|
return this.style.setShadowBlur(blur);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadowStroke: function (enabled)
|
|
|
|
{
|
|
|
|
return this.style.setShadowStroke(enabled);
|
|
|
|
},
|
|
|
|
|
|
|
|
setShadowFill: function (enabled)
|
|
|
|
{
|
|
|
|
return this.style.setShadowFill(enabled);
|
|
|
|
},
|
|
|
|
|
|
|
|
setAlign: function (align)
|
|
|
|
{
|
|
|
|
return this.style.setAlign(align);
|
|
|
|
},
|
|
|
|
|
2017-11-30 17:17:18 +00:00
|
|
|
// 'left' can be an object
|
|
|
|
// if only 'left' and 'top' are given they are treated as 'x' and 'y'
|
|
|
|
setPadding: function (left, top, right, bottom)
|
|
|
|
{
|
|
|
|
if (typeof left === 'object')
|
|
|
|
{
|
|
|
|
var config = left;
|
|
|
|
|
|
|
|
// If they specify x and/or y this applies to all
|
|
|
|
var x = GetValue(config, 'x', null);
|
|
|
|
|
|
|
|
if (x !== null)
|
|
|
|
{
|
|
|
|
left = x;
|
|
|
|
right = x;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
left = GetValue(config, 'left', 0);
|
|
|
|
right = GetValue(config, 'right', left);
|
|
|
|
}
|
|
|
|
|
|
|
|
var y = GetValue(config, 'y', null);
|
|
|
|
|
|
|
|
if (y !== null)
|
|
|
|
{
|
|
|
|
top = y;
|
|
|
|
bottom = y;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
top = GetValue(config, 'top', 0);
|
|
|
|
bottom = GetValue(config, 'bottom', top);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (left === undefined) { left = 0; }
|
|
|
|
if (top === undefined) { top = left; }
|
|
|
|
if (right === undefined) { right = left; }
|
|
|
|
if (bottom === undefined) { bottom = top; }
|
|
|
|
}
|
|
|
|
|
|
|
|
this.padding.left = left;
|
|
|
|
this.padding.top = top;
|
|
|
|
this.padding.right = right;
|
|
|
|
this.padding.bottom = bottom;
|
|
|
|
|
|
|
|
return this.updateText();
|
|
|
|
},
|
|
|
|
|
2017-03-20 16:28:09 +00:00
|
|
|
setMaxLines: function (max)
|
|
|
|
{
|
|
|
|
return this.style.setMaxLines(max);
|
|
|
|
},
|
|
|
|
|
2017-03-15 01:07:58 +00:00
|
|
|
updateText: function ()
|
|
|
|
{
|
|
|
|
var canvas = this.canvas;
|
|
|
|
var context = this.context;
|
|
|
|
var style = this.style;
|
2017-03-20 16:09:01 +00:00
|
|
|
var size = style.metrics;
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
var outputText = this.text;
|
|
|
|
|
|
|
|
// if (style.wordWrap)
|
|
|
|
// {
|
|
|
|
// outputText = this.runWordWrap(this.text);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Split text into lines
|
|
|
|
var lines = outputText.split(this.splitRegExp);
|
2017-03-13 23:38:48 +00:00
|
|
|
|
2017-03-15 01:07:58 +00:00
|
|
|
var textSize = GetTextSize(this, size, lines);
|
|
|
|
|
2017-12-01 03:11:41 +00:00
|
|
|
var padding = this.padding;
|
|
|
|
|
|
|
|
var w = textSize.width + padding.left + padding.right;
|
|
|
|
var h = textSize.height + padding.top + padding.bottom;
|
|
|
|
|
|
|
|
// console.log(textSize);
|
|
|
|
// console.log(padding);
|
|
|
|
// console.log(w, 'x', h);
|
|
|
|
// console.log('');
|
|
|
|
|
2017-03-20 16:09:01 +00:00
|
|
|
if (!style.fixedWidth)
|
|
|
|
{
|
2017-12-01 03:11:41 +00:00
|
|
|
this.width = w;
|
2017-03-20 16:09:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!style.fixedHeight)
|
|
|
|
{
|
2017-12-01 03:11:41 +00:00
|
|
|
this.height = h;
|
2017-03-20 16:09:01 +00:00
|
|
|
}
|
2017-03-15 23:08:59 +00:00
|
|
|
|
2017-11-07 01:32:53 +00:00
|
|
|
this.updateDisplayOrigin();
|
2017-03-15 23:44:39 +00:00
|
|
|
|
2017-12-01 03:11:41 +00:00
|
|
|
w *= this.resolution;
|
|
|
|
h *= this.resolution;
|
2017-03-20 16:09:01 +00:00
|
|
|
|
|
|
|
if (canvas.width !== w || canvas.height !== h)
|
|
|
|
{
|
|
|
|
canvas.width = w;
|
|
|
|
canvas.height = h;
|
|
|
|
}
|
2017-03-20 16:48:04 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
context.clearRect(0, 0, w, h);
|
|
|
|
}
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
if (style.backgroundColor)
|
|
|
|
{
|
|
|
|
context.fillStyle = style.backgroundColor;
|
2017-03-20 16:09:01 +00:00
|
|
|
context.fillRect(0, 0, w, h);
|
2017-03-15 01:07:58 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 00:16:20 +00:00
|
|
|
style.syncFont(canvas, context);
|
2017-03-15 01:07:58 +00:00
|
|
|
|
2017-04-26 02:55:37 +00:00
|
|
|
context.textBaseline = 'alphabetic';
|
2017-04-25 18:46:13 +00:00
|
|
|
|
|
|
|
// Apply padding
|
2017-11-30 17:17:18 +00:00
|
|
|
context.translate(padding.left, padding.top);
|
2017-04-25 18:46:13 +00:00
|
|
|
|
2017-03-15 01:07:58 +00:00
|
|
|
var linePositionX;
|
|
|
|
var linePositionY;
|
|
|
|
|
|
|
|
// Draw text line by line
|
|
|
|
for (var i = 0; i < textSize.lines; i++)
|
|
|
|
{
|
|
|
|
linePositionX = style.strokeThickness / 2;
|
|
|
|
linePositionY = (style.strokeThickness / 2 + i * textSize.lineHeight) + size.ascent;
|
|
|
|
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
linePositionY += (textSize.lineSpacing * i);
|
|
|
|
}
|
|
|
|
|
2017-11-30 01:20:02 +00:00
|
|
|
if (style.rtl)
|
2017-03-15 01:07:58 +00:00
|
|
|
{
|
2017-11-30 01:20:02 +00:00
|
|
|
linePositionX = w - linePositionX;
|
2017-03-15 01:07:58 +00:00
|
|
|
}
|
2017-11-30 17:17:18 +00:00
|
|
|
else if (style.align === 'right')
|
|
|
|
{
|
|
|
|
linePositionX += textSize.width - textSize.lineWidths[i];
|
|
|
|
}
|
|
|
|
else if (style.align === 'center')
|
2017-03-15 01:07:58 +00:00
|
|
|
{
|
2017-11-30 17:17:18 +00:00
|
|
|
linePositionX += (textSize.width - textSize.lineWidths[i]) / 2;
|
2017-03-15 01:07:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.autoRound)
|
|
|
|
{
|
|
|
|
linePositionX = Math.round(linePositionX);
|
|
|
|
linePositionY = Math.round(linePositionY);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (style.strokeThickness)
|
|
|
|
{
|
2017-03-20 16:09:01 +00:00
|
|
|
this.style.syncShadow(context, style.shadowStroke);
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
context.strokeText(lines[i], linePositionX, linePositionY);
|
|
|
|
}
|
|
|
|
|
2017-11-30 17:17:18 +00:00
|
|
|
if (style.color)
|
2017-03-15 01:07:58 +00:00
|
|
|
{
|
2017-03-20 16:09:01 +00:00
|
|
|
this.style.syncShadow(context, style.shadowFill);
|
2017-03-15 01:07:58 +00:00
|
|
|
|
|
|
|
context.fillText(lines[i], linePositionX, linePositionY);
|
|
|
|
}
|
|
|
|
}
|
2017-03-20 16:28:09 +00:00
|
|
|
|
2017-03-21 21:06:36 +00:00
|
|
|
this.dirty = true;
|
2017-03-21 20:08:43 +00:00
|
|
|
|
2017-03-20 16:28:09 +00:00
|
|
|
return this;
|
2017-04-12 23:35:27 +00:00
|
|
|
},
|
|
|
|
|
2017-04-26 14:54:23 +00:00
|
|
|
getTextMetrics: function ()
|
|
|
|
{
|
|
|
|
return this.style.getTextMetrics();
|
|
|
|
},
|
|
|
|
|
2017-04-12 23:35:27 +00:00
|
|
|
toJSON: function ()
|
|
|
|
{
|
|
|
|
var out = Components.ToJSON(this);
|
|
|
|
|
|
|
|
// Extra Text data is added here
|
|
|
|
|
|
|
|
var data = {
|
|
|
|
autoRound: this.autoRound,
|
|
|
|
text: this.text,
|
2017-04-25 17:24:37 +00:00
|
|
|
style: this.style.toJSON(),
|
2017-04-12 23:35:27 +00:00
|
|
|
resolution: this.resolution,
|
|
|
|
padding: {
|
2017-11-30 17:17:18 +00:00
|
|
|
left: this.padding.left,
|
|
|
|
right: this.padding.right,
|
|
|
|
top: this.padding.top,
|
|
|
|
bottom: this.padding.bottom
|
2017-04-12 23:35:27 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
out.data = data;
|
|
|
|
|
|
|
|
return out;
|
2017-11-30 01:20:02 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
preDestroy: function ()
|
|
|
|
{
|
|
|
|
if (this.style.rtl)
|
|
|
|
{
|
|
|
|
RemoveFromDOM(this.canvas);
|
|
|
|
}
|
|
|
|
|
|
|
|
CanvasPool.remove(this.canvas);
|
2017-03-21 23:14:25 +00:00
|
|
|
}
|
2017-11-30 01:20:02 +00:00
|
|
|
|
2017-03-13 23:38:48 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = Text;
|