Browse Source

- Fixed dynamic updating of label properties.

kamadaKawai
Alex de Mulder 9 years ago
parent
commit
9b83e2ca0f
5 changed files with 78 additions and 64 deletions
  1. +1
    -0
      HISTORY.md
  2. +39
    -32
      dist/vis.js
  3. +1
    -1
      lib/network/modules/NodesHandler.js
  4. +2
    -1
      lib/network/modules/components/Node.js
  5. +35
    -30
      lib/network/modules/components/shared/Label.js

+ 1
- 0
HISTORY.md View File

@ -13,6 +13,7 @@ http://visjs.org
- Fixed #1152, updating images now works. - Fixed #1152, updating images now works.
- Fixed cleaning up of nodes. - Fixed cleaning up of nodes.
- Improved the positioning and CSS of the configurator and the color picker. - Improved the positioning and CSS of the configurator and the color picker.
- Fixed dynamic updating of label properties.
## 2015-07-27, version 4.7.0 ## 2015-07-27, version 4.7.0

+ 39
- 32
dist/vis.js View File

@ -27703,7 +27703,7 @@ return /******/ (function(modules) { // webpackBootstrap
} }
} }
// update the shape size in all nodes
// update the font in all nodes
if (options.font !== undefined) { if (options.font !== undefined) {
_componentsSharedLabel2['default'].parseOptions(this.options.font, options); _componentsSharedLabel2['default'].parseOptions(this.options.font, options);
for (var nodeId in this.body.nodes) { for (var nodeId in this.body.nodes) {
@ -28216,6 +28216,7 @@ return /******/ (function(modules) { // webpackBootstrap
if (!options) { if (!options) {
return; return;
} }
// basic options // basic options
if (options.id !== undefined) { if (options.id !== undefined) {
this.id = options.id; this.id = options.id;
@ -28268,8 +28269,8 @@ return /******/ (function(modules) { // webpackBootstrap
} }
} }
this.updateShape(currentShape);
this.updateLabelModule(); this.updateLabelModule();
this.updateShape(currentShape);
if (options.hidden !== undefined || options.physics !== undefined) { if (options.hidden !== undefined || options.physics !== undefined) {
return true; return true;
@ -28289,6 +28290,7 @@ return /******/ (function(modules) { // webpackBootstrap
if (this.options.label === undefined || this.options.label === null) { if (this.options.label === undefined || this.options.label === null) {
this.options.label = ''; this.options.label = '';
} }
this.labelModule.setOptions(this.options, true); this.labelModule.setOptions(this.options, true);
if (this.labelModule.baseSize !== undefined) { if (this.labelModule.baseSize !== undefined) {
this.baseFontSize = this.labelModule.baseSize; this.baseFontSize = this.labelModule.baseSize;
@ -28590,6 +28592,7 @@ return /******/ (function(modules) { // webpackBootstrap
this.pointToSelf = false; this.pointToSelf = false;
this.baseSize = undefined; this.baseSize = undefined;
this.fontOptions = {};
this.setOptions(options); this.setOptions(options);
this.size = { top: 0, left: 0, width: 0, height: 0, yLine: 0 }; // could be cached this.size = { top: 0, left: 0, width: 0, height: 0, yLine: 0 }; // could be cached
} }
@ -28599,16 +28602,20 @@ return /******/ (function(modules) { // webpackBootstrap
value: function setOptions(options) { value: function setOptions(options) {
var allowDeletion = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var allowDeletion = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
this.options = options;
this.nodeOptions = options;
// We want to keep the font options seperated from the node options.
// The node options have to mirror the globals when they are not overruled.
this.fontOptions = util.deepExtend({}, options.font, true);
if (options.label !== undefined) { if (options.label !== undefined) {
this.labelDirty = true; this.labelDirty = true;
} }
if (options.font !== undefined) { if (options.font !== undefined) {
Label.parseOptions(this.options.font, options, allowDeletion);
Label.parseOptions(this.fontOptions, options, allowDeletion);
if (typeof options.font === 'string') { if (typeof options.font === 'string') {
this.baseSize = this.options.font.size;
this.baseSize = this.fontOptions.size;
} else if (typeof options.font === 'object') { } else if (typeof options.font === 'object') {
if (options.font.size !== undefined) { if (options.font.size !== undefined) {
this.baseSize = options.font.size; this.baseSize = options.font.size;
@ -28631,11 +28638,11 @@ return /******/ (function(modules) { // webpackBootstrap
var baseline = arguments.length <= 4 || arguments[4] === undefined ? 'middle' : arguments[4]; var baseline = arguments.length <= 4 || arguments[4] === undefined ? 'middle' : arguments[4];
// if no label, return // if no label, return
if (this.options.label === undefined) return;
if (this.nodeOptions.label === undefined) return;
// check if we have to render the label // check if we have to render the label
var viewFontSize = this.options.font.size * this.body.view.scale;
if (this.options.label && viewFontSize < this.options.scaling.label.drawThreshold - 1) return;
var viewFontSize = this.fontOptions.size * this.body.view.scale;
if (this.nodeOptions.label && viewFontSize < this.nodeOptions.scaling.label.drawThreshold - 1) return;
// update the size cache if required // update the size cache if required
this.calculateLabelSize(ctx, selected, x, y, baseline); this.calculateLabelSize(ctx, selected, x, y, baseline);
@ -28654,12 +28661,12 @@ return /******/ (function(modules) { // webpackBootstrap
}, { }, {
key: '_drawBackground', key: '_drawBackground',
value: function _drawBackground(ctx) { value: function _drawBackground(ctx) {
if (this.options.font.background !== undefined && this.options.font.background !== "none") {
ctx.fillStyle = this.options.font.background;
if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") {
ctx.fillStyle = this.fontOptions.background;
var lineMargin = 2; var lineMargin = 2;
switch (this.options.font.align) {
switch (this.fontOptions.align) {
case 'middle': case 'middle':
ctx.fillRect(-this.size.width * 0.5, -this.size.height * 0.5, this.size.width, this.size.height); ctx.fillRect(-this.size.width * 0.5, -this.size.height * 0.5, this.size.width, this.size.height);
break; break;
@ -28688,11 +28695,11 @@ return /******/ (function(modules) { // webpackBootstrap
value: function _drawText(ctx, selected, x, y) { value: function _drawText(ctx, selected, x, y) {
var baseline = arguments.length <= 4 || arguments[4] === undefined ? 'middle' : arguments[4]; var baseline = arguments.length <= 4 || arguments[4] === undefined ? 'middle' : arguments[4];
var fontSize = this.options.font.size;
var fontSize = this.fontOptions.size;
var viewFontSize = fontSize * this.body.view.scale; var viewFontSize = fontSize * this.body.view.scale;
// this ensures that there will not be HUGE letters on screen by setting an upper limit on the visible text size (regardless of zoomLevel) // this ensures that there will not be HUGE letters on screen by setting an upper limit on the visible text size (regardless of zoomLevel)
if (viewFontSize >= this.options.scaling.label.maxVisible) {
fontSize = Number(this.options.scaling.label.maxVisible) / this.body.view.scale;
if (viewFontSize >= this.nodeOptions.scaling.label.maxVisible) {
fontSize = Number(this.nodeOptions.scaling.label.maxVisible) / this.body.view.scale;
} }
var yLine = this.size.yLine; var yLine = this.size.yLine;
@ -28712,20 +28719,20 @@ return /******/ (function(modules) { // webpackBootstrap
x = _setAlignment22[0]; x = _setAlignment22[0];
yLine = _setAlignment22[1]; yLine = _setAlignment22[1];
ctx.font = (selected && this.options.labelHighlightBold ? 'bold ' : '') + fontSize + "px " + this.options.font.face;
ctx.font = (selected && this.nodeOptions.labelHighlightBold ? 'bold ' : '') + fontSize + "px " + this.fontOptions.face;
ctx.fillStyle = fontColor; ctx.fillStyle = fontColor;
ctx.textAlign = 'center'; ctx.textAlign = 'center';
// set the strokeWidth // set the strokeWidth
if (this.options.font.strokeWidth > 0) {
ctx.lineWidth = this.options.font.strokeWidth;
if (this.fontOptions.strokeWidth > 0) {
ctx.lineWidth = this.fontOptions.strokeWidth;
ctx.strokeStyle = strokeColor; ctx.strokeStyle = strokeColor;
ctx.lineJoin = 'round'; ctx.lineJoin = 'round';
} }
// draw the text // draw the text
for (var i = 0; i < this.lineCount; i++) { for (var i = 0; i < this.lineCount; i++) {
if (this.options.font.strokeWidth > 0) {
if (this.fontOptions.strokeWidth > 0) {
ctx.strokeText(this.lines[i], x, yLine); ctx.strokeText(this.lines[i], x, yLine);
} }
ctx.fillText(this.lines[i], x, yLine); ctx.fillText(this.lines[i], x, yLine);
@ -28737,15 +28744,15 @@ return /******/ (function(modules) { // webpackBootstrap
value: function _setAlignment(ctx, x, yLine, baseline) { value: function _setAlignment(ctx, x, yLine, baseline) {
// check for label alignment (for edges) // check for label alignment (for edges)
// TODO: make alignment for nodes // TODO: make alignment for nodes
if (this.options.font.align !== 'horizontal' && this.pointToSelf === false) {
if (this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) {
x = 0; x = 0;
yLine = 0; yLine = 0;
var lineMargin = 2; var lineMargin = 2;
if (this.options.font.align === 'top') {
if (this.fontOptions.align === 'top') {
ctx.textBaseline = 'alphabetic'; ctx.textBaseline = 'alphabetic';
yLine -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers yLine -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers
} else if (this.options.font.align === 'bottom') {
} else if (this.fontOptions.align === 'bottom') {
ctx.textBaseline = 'hanging'; ctx.textBaseline = 'hanging';
yLine += 2 * lineMargin; // distance from edge, required because we use hanging. Hanging has less difference between browsers yLine += 2 * lineMargin; // distance from edge, required because we use hanging. Hanging has less difference between browsers
} else { } else {
@ -28769,10 +28776,10 @@ return /******/ (function(modules) { // webpackBootstrap
}, { }, {
key: '_getColor', key: '_getColor',
value: function _getColor(viewFontSize) { value: function _getColor(viewFontSize) {
var fontColor = this.options.font.color || '#000000';
var strokeColor = this.options.font.strokeColor || '#ffffff';
if (viewFontSize <= this.options.scaling.label.drawThreshold) {
var opacity = Math.max(0, Math.min(1, 1 - (this.options.scaling.label.drawThreshold - viewFontSize)));
var fontColor = this.fontOptions.color || '#000000';
var strokeColor = this.fontOptions.strokeColor || '#ffffff';
if (viewFontSize <= this.nodeOptions.scaling.label.drawThreshold) {
var opacity = Math.max(0, Math.min(1, 1 - (this.nodeOptions.scaling.label.drawThreshold - viewFontSize)));
fontColor = util.overrideOpacity(fontColor, opacity); fontColor = util.overrideOpacity(fontColor, opacity);
strokeColor = util.overrideOpacity(strokeColor, opacity); strokeColor = util.overrideOpacity(strokeColor, opacity);
} }
@ -28792,7 +28799,7 @@ return /******/ (function(modules) { // webpackBootstrap
var size = { var size = {
width: this._processLabel(ctx, selected), width: this._processLabel(ctx, selected),
height: this.options.font.size * this.lineCount,
height: this.fontOptions.size * this.lineCount,
lineCount: this.lineCount lineCount: this.lineCount
}; };
return size; return size;
@ -28816,12 +28823,12 @@ return /******/ (function(modules) { // webpackBootstrap
if (this.labelDirty === true) { if (this.labelDirty === true) {
this.size.width = this._processLabel(ctx, selected); this.size.width = this._processLabel(ctx, selected);
} }
this.size.height = this.options.font.size * this.lineCount;
this.size.height = this.fontOptions.size * this.lineCount;
this.size.left = x - this.size.width * 0.5; this.size.left = x - this.size.width * 0.5;
this.size.top = y - this.size.height * 0.5; this.size.top = y - this.size.height * 0.5;
this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.options.font.size;
this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
if (baseline === "hanging") { if (baseline === "hanging") {
this.size.top += 0.5 * this.options.font.size;
this.size.top += 0.5 * this.fontOptions.size;
this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers
this.size.yLine += 4; // distance from node this.size.yLine += 4; // distance from node
} }
@ -28842,10 +28849,10 @@ return /******/ (function(modules) { // webpackBootstrap
var width = 0; var width = 0;
var lines = ['']; var lines = [''];
var lineCount = 0; var lineCount = 0;
if (this.options.label !== undefined) {
lines = String(this.options.label).split('\n');
if (this.nodeOptions.label !== undefined) {
lines = String(this.nodeOptions.label).split('\n');
lineCount = lines.length; lineCount = lines.length;
ctx.font = (selected && this.options.labelHighlightBold ? 'bold ' : '') + this.options.font.size + "px " + this.options.font.face;
ctx.font = (selected && this.nodeOptions.labelHighlightBold ? 'bold ' : '') + this.fontOptions.size + "px " + this.fontOptions.face;
width = ctx.measureText(lines[0]).width; width = ctx.measureText(lines[0]).width;
for (var i = 1; i < lineCount; i++) { for (var i = 1; i < lineCount; i++) {
var lineWidth = ctx.measureText(lines[i]).width; var lineWidth = ctx.measureText(lines[i]).width;

+ 1
- 1
lib/network/modules/NodesHandler.js View File

@ -134,7 +134,7 @@ class NodesHandler {
} }
} }
// update the shape size in all nodes
// update the font in all nodes
if (options.font !== undefined) { if (options.font !== undefined) {
Label.parseOptions(this.options.font, options); Label.parseOptions(this.options.font, options);
for (let nodeId in this.body.nodes) { for (let nodeId in this.body.nodes) {

+ 2
- 1
lib/network/modules/components/Node.js View File

@ -147,8 +147,9 @@ class Node {
} }
} }
this.updateShape(currentShape);
this.updateLabelModule(); this.updateLabelModule();
this.updateShape(currentShape);
if (options.hidden !== undefined || options.physics !== undefined) { if (options.hidden !== undefined || options.physics !== undefined) {
return true; return true;

+ 35
- 30
lib/network/modules/components/shared/Label.js View File

@ -6,21 +6,26 @@ class Label {
this.pointToSelf = false; this.pointToSelf = false;
this.baseSize = undefined; this.baseSize = undefined;
this.fontOptions = {};
this.setOptions(options); this.setOptions(options);
this.size = {top: 0, left: 0, width: 0, height: 0, yLine: 0}; // could be cached this.size = {top: 0, left: 0, width: 0, height: 0, yLine: 0}; // could be cached
} }
setOptions(options, allowDeletion = false) { setOptions(options, allowDeletion = false) {
this.options = options;
this.nodeOptions = options;
// We want to keep the font options seperated from the node options.
// The node options have to mirror the globals when they are not overruled.
this.fontOptions = util.deepExtend({},options.font, true);
if (options.label !== undefined) { if (options.label !== undefined) {
this.labelDirty = true; this.labelDirty = true;
} }
if (options.font !== undefined) { if (options.font !== undefined) {
Label.parseOptions(this.options.font, options, allowDeletion);
Label.parseOptions(this.fontOptions, options, allowDeletion);
if (typeof options.font === 'string') { if (typeof options.font === 'string') {
this.baseSize = this.options.font.size;
this.baseSize = this.fontOptions.size;
} }
else if (typeof options.font === 'object') { else if (typeof options.font === 'object') {
if (options.font.size !== undefined) { if (options.font.size !== undefined) {
@ -54,12 +59,12 @@ class Label {
*/ */
draw(ctx, x, y, selected, baseline = 'middle') { draw(ctx, x, y, selected, baseline = 'middle') {
// if no label, return // if no label, return
if (this.options.label === undefined)
if (this.nodeOptions.label === undefined)
return; return;
// check if we have to render the label // check if we have to render the label
let viewFontSize = this.options.font.size * this.body.view.scale;
if (this.options.label && viewFontSize < this.options.scaling.label.drawThreshold - 1)
let viewFontSize = this.fontOptions.size * this.body.view.scale;
if (this.nodeOptions.label && viewFontSize < this.nodeOptions.scaling.label.drawThreshold - 1)
return; return;
// update the size cache if required // update the size cache if required
@ -77,12 +82,12 @@ class Label {
* @private * @private
*/ */
_drawBackground(ctx) { _drawBackground(ctx) {
if (this.options.font.background !== undefined && this.options.font.background !== "none") {
ctx.fillStyle = this.options.font.background;
if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") {
ctx.fillStyle = this.fontOptions.background;
let lineMargin = 2; let lineMargin = 2;
switch (this.options.font.align) {
switch (this.fontOptions.align) {
case 'middle': case 'middle':
ctx.fillRect(-this.size.width * 0.5, -this.size.height * 0.5, this.size.width, this.size.height); ctx.fillRect(-this.size.width * 0.5, -this.size.height * 0.5, this.size.width, this.size.height);
break; break;
@ -108,11 +113,11 @@ class Label {
* @private * @private
*/ */
_drawText(ctx, selected, x, y, baseline = 'middle') { _drawText(ctx, selected, x, y, baseline = 'middle') {
let fontSize = this.options.font.size;
let fontSize = this.fontOptions.size;
let viewFontSize = fontSize * this.body.view.scale; let viewFontSize = fontSize * this.body.view.scale;
// this ensures that there will not be HUGE letters on screen by setting an upper limit on the visible text size (regardless of zoomLevel) // this ensures that there will not be HUGE letters on screen by setting an upper limit on the visible text size (regardless of zoomLevel)
if (viewFontSize >= this.options.scaling.label.maxVisible) {
fontSize = Number(this.options.scaling.label.maxVisible) / this.body.view.scale;
if (viewFontSize >= this.nodeOptions.scaling.label.maxVisible) {
fontSize = Number(this.nodeOptions.scaling.label.maxVisible) / this.body.view.scale;
} }
let yLine = this.size.yLine; let yLine = this.size.yLine;
@ -120,20 +125,20 @@ class Label {
[x, yLine] = this._setAlignment(ctx, x, yLine, baseline); [x, yLine] = this._setAlignment(ctx, x, yLine, baseline);
// configure context for drawing the text // configure context for drawing the text
ctx.font = (selected && this.options.labelHighlightBold ? 'bold ' : '') + fontSize + "px " + this.options.font.face;
ctx.font = (selected && this.nodeOptions.labelHighlightBold ? 'bold ' : '') + fontSize + "px " + this.fontOptions.face;
ctx.fillStyle = fontColor; ctx.fillStyle = fontColor;
ctx.textAlign = 'center'; ctx.textAlign = 'center';
// set the strokeWidth // set the strokeWidth
if (this.options.font.strokeWidth > 0) {
ctx.lineWidth = this.options.font.strokeWidth;
if (this.fontOptions.strokeWidth > 0) {
ctx.lineWidth = this.fontOptions.strokeWidth;
ctx.strokeStyle = strokeColor; ctx.strokeStyle = strokeColor;
ctx.lineJoin = 'round'; ctx.lineJoin = 'round';
} }
// draw the text // draw the text
for (let i = 0; i < this.lineCount; i++) { for (let i = 0; i < this.lineCount; i++) {
if (this.options.font.strokeWidth > 0) {
if (this.fontOptions.strokeWidth > 0) {
ctx.strokeText(this.lines[i], x, yLine); ctx.strokeText(this.lines[i], x, yLine);
} }
ctx.fillText(this.lines[i], x, yLine); ctx.fillText(this.lines[i], x, yLine);
@ -144,16 +149,16 @@ class Label {
_setAlignment(ctx, x, yLine, baseline) { _setAlignment(ctx, x, yLine, baseline) {
// check for label alignment (for edges) // check for label alignment (for edges)
// TODO: make alignment for nodes // TODO: make alignment for nodes
if (this.options.font.align !== 'horizontal' && this.pointToSelf === false) {
if (this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) {
x = 0; x = 0;
yLine = 0; yLine = 0;
let lineMargin = 2; let lineMargin = 2;
if (this.options.font.align === 'top') {
if (this.fontOptions.align === 'top') {
ctx.textBaseline = 'alphabetic'; ctx.textBaseline = 'alphabetic';
yLine -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers yLine -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers
} }
else if (this.options.font.align === 'bottom') {
else if (this.fontOptions.align === 'bottom') {
ctx.textBaseline = 'hanging'; ctx.textBaseline = 'hanging';
yLine += 2 * lineMargin;// distance from edge, required because we use hanging. Hanging has less difference between browsers yLine += 2 * lineMargin;// distance from edge, required because we use hanging. Hanging has less difference between browsers
} }
@ -177,10 +182,10 @@ class Label {
* @private * @private
*/ */
_getColor(viewFontSize) { _getColor(viewFontSize) {
let fontColor = this.options.font.color || '#000000';
let strokeColor = this.options.font.strokeColor || '#ffffff';
if (viewFontSize <= this.options.scaling.label.drawThreshold) {
let opacity = Math.max(0, Math.min(1, 1 - (this.options.scaling.label.drawThreshold - viewFontSize)));
let fontColor = this.fontOptions.color || '#000000';
let strokeColor = this.fontOptions.strokeColor || '#ffffff';
if (viewFontSize <= this.nodeOptions.scaling.label.drawThreshold) {
let opacity = Math.max(0, Math.min(1, 1 - (this.nodeOptions.scaling.label.drawThreshold - viewFontSize)));
fontColor = util.overrideOpacity(fontColor, opacity); fontColor = util.overrideOpacity(fontColor, opacity);
strokeColor = util.overrideOpacity(strokeColor, opacity); strokeColor = util.overrideOpacity(strokeColor, opacity);
} }
@ -197,7 +202,7 @@ class Label {
getTextSize(ctx, selected = false) { getTextSize(ctx, selected = false) {
let size = { let size = {
width: this._processLabel(ctx,selected), width: this._processLabel(ctx,selected),
height: this.options.font.size * this.lineCount,
height: this.fontOptions.size * this.lineCount,
lineCount: this.lineCount lineCount: this.lineCount
}; };
return size; return size;
@ -216,12 +221,12 @@ class Label {
if (this.labelDirty === true) { if (this.labelDirty === true) {
this.size.width = this._processLabel(ctx,selected); this.size.width = this._processLabel(ctx,selected);
} }
this.size.height = this.options.font.size * this.lineCount;
this.size.height = this.fontOptions.size * this.lineCount;
this.size.left = x - this.size.width * 0.5; this.size.left = x - this.size.width * 0.5;
this.size.top = y - this.size.height * 0.5; this.size.top = y - this.size.height * 0.5;
this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.options.font.size;
this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
if (baseline === "hanging") { if (baseline === "hanging") {
this.size.top += 0.5 * this.options.font.size;
this.size.top += 0.5 * this.fontOptions.size;
this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers this.size.top += 4; // distance from node, required because we use hanging. Hanging has less difference between browsers
this.size.yLine += 4; // distance from node this.size.yLine += 4; // distance from node
} }
@ -241,10 +246,10 @@ class Label {
let width = 0; let width = 0;
let lines = ['']; let lines = [''];
let lineCount = 0; let lineCount = 0;
if (this.options.label !== undefined) {
lines = String(this.options.label).split('\n');
if (this.nodeOptions.label !== undefined) {
lines = String(this.nodeOptions.label).split('\n');
lineCount = lines.length; lineCount = lines.length;
ctx.font = (selected && this.options.labelHighlightBold ? 'bold ' : '') + this.options.font.size + "px " + this.options.font.face;
ctx.font = (selected && this.nodeOptions.labelHighlightBold ? 'bold ' : '') + this.fontOptions.size + "px " + this.fontOptions.face;
width = ctx.measureText(lines[0]).width; width = ctx.measureText(lines[0]).width;
for (let i = 1; i < lineCount; i++) { for (let i = 1; i < lineCount; i++) {
let lineWidth = ctx.measureText(lines[i]).width; let lineWidth = ctx.measureText(lines[i]).width;

Loading…
Cancel
Save