Browse Source

IE performance improvements #3425 (#3489)

* Label performance improvements

* Label cleanup

* Fix drag performance in IE

* Fixed broken images still trying to draw

* Fixed merge and lint issues
jittering-top
justinharrell 7 years ago
committed by Yotam Berkowitz
parent
commit
3cac6144be
2 changed files with 42 additions and 42 deletions
  1. +1
    -1
      lib/network/modules/InteractionHandler.js
  2. +41
    -41
      lib/network/modules/components/shared/Label.js

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

@ -393,7 +393,7 @@ class InteractionHandler {
let diffY = pointer.y - this.drag.pointer.y; let diffY = pointer.y - this.drag.pointer.y;
this.body.view.translation = {x:this.drag.translation.x + diffX, y:this.drag.translation.y + diffY}; this.body.view.translation = {x:this.drag.translation.x + diffX, y:this.drag.translation.y + diffY};
this.body.emitter.emit('_redraw');
this.body.emitter.emit('_requestRedraw');
} }
} }
} }

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

@ -338,20 +338,27 @@ class Label {
if (this.elementOptions.label && viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) if (this.elementOptions.label && viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1)
return; return;
// 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.elementOptions.scaling.label.maxVisible) {
viewFontSize = Number(this.elementOptions.scaling.label.maxVisible) / this.body.view.scale;
}
// update the size cache if required // update the size cache if required
this.calculateLabelSize(ctx, selected, hover, x, y, baseline); this.calculateLabelSize(ctx, selected, hover, x, y, baseline);
this._drawBackground(ctx, this.size.left, this.size.top);
this._drawText(ctx, x, this.size.yLine, baseline, viewFontSize);
this._drawBackground(ctx); // create the fontfill background
this._drawText(ctx, selected, hover, x, y, baseline);
} }
/** /**
* Draws the label background * Draws the label background
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {number} x
* @param {number} y
* @private * @private
*/ */
_drawBackground(ctx) {
_drawBackground(ctx, x, y) {
if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") { if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") {
ctx.fillStyle = this.fontOptions.background; ctx.fillStyle = this.fontOptions.background;
@ -369,11 +376,11 @@ class Label {
ctx.fillRect(-this.size.width * 0.5, lineMargin, this.size.width, this.size.height); ctx.fillRect(-this.size.width * 0.5, lineMargin, this.size.width, this.size.height);
break; break;
default: default:
ctx.fillRect(this.size.left, this.size.top - 0.5*lineMargin, this.size.width, this.size.height);
ctx.fillRect(x, y - 0.5*lineMargin, this.size.width, this.size.height);
break; break;
} }
} else { } else {
ctx.fillRect(this.size.left, this.size.top - 0.5*lineMargin, this.size.width, this.size.height);
ctx.fillRect(x, y - 0.5*lineMargin, this.size.width, this.size.height);
} }
} }
} }
@ -382,49 +389,39 @@ class Label {
/** /**
* *
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {boolean} selected
* @param {boolean} hover
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @param {string} [baseline='middle'] * @param {string} [baseline='middle']
* @param {number} viewFontSize
* @private * @private
*/ */
_drawText(ctx, selected, hover, x, y, baseline = 'middle') {
let fontSize = this.fontOptions.size;
let viewFontSize = fontSize * this.body.view.scale;
_drawText(ctx, x, y, baseline = 'middle', viewFontSize) {
// 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.elementOptions.scaling.label.maxVisible) {
// TODO: Does this actually do anything?
fontSize = Number(this.elementOptions.scaling.label.maxVisible) / this.body.view.scale;
}
let yLine = this.size.yLine;
[x, yLine] = this._setAlignment(ctx, x, yLine, baseline);
[x, y] = this._setAlignment(ctx, x, y, baseline);
ctx.textAlign = 'left'; ctx.textAlign = 'left';
x = x - this.size.width / 2; // Shift label 1/2-distance to the left x = x - this.size.width / 2; // Shift label 1/2-distance to the left
if ((this.fontOptions.valign) && (this.size.height > this.size.labelHeight)) { if ((this.fontOptions.valign) && (this.size.height > this.size.labelHeight)) {
if (this.fontOptions.valign === 'top') { if (this.fontOptions.valign === 'top') {
yLine -= (this.size.height - this.size.labelHeight) / 2;
y -= (this.size.height - this.size.labelHeight) / 2;
} }
if (this.fontOptions.valign === 'bottom') { if (this.fontOptions.valign === 'bottom') {
yLine += (this.size.height - this.size.labelHeight) / 2;
y += (this.size.height - this.size.labelHeight) / 2;
} }
} }
// draw the text // draw the text
for (let i = 0; i < this.lineCount; i++) { for (let i = 0; i < this.lineCount; i++) {
if (this.lines[i] && this.lines[i].blocks) {
let line = this.lines[i];
if (line && line.blocks) {
let width = 0; let width = 0;
if (this.isEdgeLabel || this.fontOptions.align === 'center') { if (this.isEdgeLabel || this.fontOptions.align === 'center') {
width += (this.size.width - this.lines[i].width) / 2
width += (this.size.width - line.width) / 2
} else if (this.fontOptions.align === 'right') { } else if (this.fontOptions.align === 'right') {
width += (this.size.width - this.lines[i].width)
width += (this.size.width - line.width)
} }
for (let j = 0; j < this.lines[i].blocks.length; j++) {
let block = this.lines[i].blocks[j];
for (let j = 0; j < line.blocks.length; j++) {
let block = line.blocks[j];
ctx.font = block.font; ctx.font = block.font;
let [fontColor, strokeColor] = this._getColor(block.color, viewFontSize, block.strokeColor); let [fontColor, strokeColor] = this._getColor(block.color, viewFontSize, block.strokeColor);
if (block.strokeWidth > 0) { if (block.strokeWidth > 0) {
@ -435,12 +432,12 @@ class Label {
ctx.fillStyle = fontColor; ctx.fillStyle = fontColor;
if (block.strokeWidth > 0) { if (block.strokeWidth > 0) {
ctx.strokeText(block.text, x + width, yLine + block.vadjust);
ctx.strokeText(block.text, x + width, y + block.vadjust);
} }
ctx.fillText(block.text, x + width, yLine + block.vadjust);
ctx.fillText(block.text, x + width, y + block.vadjust);
width += block.width; width += block.width;
} }
yLine += this.lines[i].height;
y += line.height;
} }
} }
} }
@ -449,26 +446,26 @@ class Label {
* *
* @param {CanvasRenderingContext2D} ctx * @param {CanvasRenderingContext2D} ctx
* @param {number} x * @param {number} x
* @param {number} yLine
* @param {number} y
* @param {string} baseline * @param {string} baseline
* @returns {Array.<number>} * @returns {Array.<number>}
* @private * @private
*/ */
_setAlignment(ctx, x, yLine, baseline) {
_setAlignment(ctx, x, y, 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.isEdgeLabel && this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) { if (this.isEdgeLabel && this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) {
x = 0; x = 0;
yLine = 0;
y = 0;
let lineMargin = 2; let lineMargin = 2;
if (this.fontOptions.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
y -= 2 * lineMargin; // distance from edge, required because we use alphabetic. Alphabetic has less difference between browsers
} }
else if (this.fontOptions.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
y += 2 * lineMargin;// distance from edge, required because we use hanging. Hanging has less difference between browsers
} }
else { else {
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
@ -477,7 +474,7 @@ class Label {
else { else {
ctx.textBaseline = baseline; ctx.textBaseline = baseline;
} }
return [x,yLine];
return [x,y];
} }
/** /**
@ -528,9 +525,7 @@ class Label {
* @param {'middle'|'hanging'} [baseline='middle'] * @param {'middle'|'hanging'} [baseline='middle']
*/ */
calculateLabelSize(ctx, selected, hover, x = 0, y = 0, baseline = 'middle') { calculateLabelSize(ctx, selected, hover, x = 0, y = 0, baseline = 'middle') {
if (this.labelDirty === true) {
this._processLabel(ctx, selected, hover);
}
this._processLabel(ctx, selected, hover);
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.fontOptions.size; this.size.yLine = y + (1 - this.lineCount) * 0.5 * this.fontOptions.size;
@ -539,7 +534,6 @@ class Label {
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
} }
this.labelDirty = false;
} }
@ -598,7 +592,7 @@ class Label {
* @returns {boolean} * @returns {boolean}
*/ */
differentState(selected, hover) { differentState(selected, hover) {
return ((selected !== this.fontOptions.selectedState) && (hover !== this.fontOptions.hoverState));
return ((selected !== this.selectedState) || (hover !== this.hoverState));
} }
@ -626,6 +620,10 @@ class Label {
* @private * @private
*/ */
_processLabel(ctx, selected, hover) { _processLabel(ctx, selected, hover) {
if(this.labelDirty === false && !this.differentState(selected,hover))
return;
let state = this._processLabelText(ctx, selected, hover, this.elementOptions.label); let state = this._processLabelText(ctx, selected, hover, this.elementOptions.label);
if ((this.fontOptions.minWdt > 0) && (state.width < this.fontOptions.minWdt)) { if ((this.fontOptions.minWdt > 0) && (state.width < this.fontOptions.minWdt)) {
@ -643,6 +641,8 @@ class Label {
this.size.height = state.height; this.size.height = state.height;
this.selectedState = selected; this.selectedState = selected;
this.hoverState = hover; this.hoverState = hover;
this.labelDirty = false;
} }
} }

Loading…
Cancel
Save