diff --git a/lib/network/modules/InteractionHandler.js b/lib/network/modules/InteractionHandler.js index 75cd0f1d..c8caf412 100644 --- a/lib/network/modules/InteractionHandler.js +++ b/lib/network/modules/InteractionHandler.js @@ -393,7 +393,7 @@ class InteractionHandler { 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.emitter.emit('_redraw'); + this.body.emitter.emit('_requestRedraw'); } } } diff --git a/lib/network/modules/components/shared/Label.js b/lib/network/modules/components/shared/Label.js index 16865500..d214058e 100644 --- a/lib/network/modules/components/shared/Label.js +++ b/lib/network/modules/components/shared/Label.js @@ -338,20 +338,27 @@ class Label { if (this.elementOptions.label && viewFontSize < this.elementOptions.scaling.label.drawThreshold - 1) 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 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 * @param {CanvasRenderingContext2D} ctx + * @param {number} x + * @param {number} y * @private */ - _drawBackground(ctx) { + _drawBackground(ctx, x, y) { if (this.fontOptions.background !== undefined && this.fontOptions.background !== "none") { 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); break; 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; } } 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 {boolean} selected - * @param {boolean} hover * @param {number} x * @param {number} y * @param {string} [baseline='middle'] + * @param {number} viewFontSize * @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'; 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 === 'top') { - yLine -= (this.size.height - this.size.labelHeight) / 2; + y -= (this.size.height - this.size.labelHeight) / 2; } if (this.fontOptions.valign === 'bottom') { - yLine += (this.size.height - this.size.labelHeight) / 2; + y += (this.size.height - this.size.labelHeight) / 2; } } // draw the text 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; 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') { - 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; let [fontColor, strokeColor] = this._getColor(block.color, viewFontSize, block.strokeColor); if (block.strokeWidth > 0) { @@ -435,12 +432,12 @@ class Label { ctx.fillStyle = fontColor; 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; } - yLine += this.lines[i].height; + y += line.height; } } } @@ -449,26 +446,26 @@ class Label { * * @param {CanvasRenderingContext2D} ctx * @param {number} x - * @param {number} yLine + * @param {number} y * @param {string} baseline * @returns {Array.} * @private */ - _setAlignment(ctx, x, yLine, baseline) { + _setAlignment(ctx, x, y, baseline) { // check for label alignment (for edges) // TODO: make alignment for nodes if (this.isEdgeLabel && this.fontOptions.align !== 'horizontal' && this.pointToSelf === false) { x = 0; - yLine = 0; + y = 0; let lineMargin = 2; if (this.fontOptions.align === 'top') { 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') { 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 { ctx.textBaseline = 'middle'; @@ -477,7 +474,7 @@ class Label { else { ctx.textBaseline = baseline; } - return [x,yLine]; + return [x,y]; } /** @@ -528,9 +525,7 @@ class Label { * @param {'middle'|'hanging'} [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.top = y - this.size.height * 0.5; 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.yLine += 4; // distance from node } - this.labelDirty = false; } @@ -598,7 +592,7 @@ class Label { * @returns {boolean} */ 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 */ _processLabel(ctx, selected, hover) { + + if(this.labelDirty === false && !this.differentState(selected,hover)) + return; + let state = this._processLabelText(ctx, selected, hover, this.elementOptions.label); if ((this.fontOptions.minWdt > 0) && (state.width < this.fontOptions.minWdt)) { @@ -643,6 +641,8 @@ class Label { this.size.height = state.height; this.selectedState = selected; this.hoverState = hover; + + this.labelDirty = false; } }