Skip to content

Commit 95bedb4

Browse files
#1704 Postpone expensive Annotation's getBoundingClientRect calls
1 parent 44738c1 commit 95bedb4

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

src/plugins/AnnotationsPlugin/Annotation.js

+45-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class Annotation extends Marker {
4040
}
4141

4242
this._htmlDirty = false;
43+
this._curMarkerWidth = undefined;
44+
this._curLabelWidth = 0;
4345

4446
if (cfg.markerElement) {
4547
this._marker = cfg.markerElement;
@@ -210,25 +212,65 @@ class Annotation extends Marker {
210212
/**
211213
* @private
212214
*/
213-
_updatePosition() {
215+
_updateWithCurWidths() {
214216
const px = x => x + "px";
215217
const boundary = this.scene.canvas.boundary;
216218
const left = boundary[0] + this.canvasPos[0];
217219
const top = boundary[1] + this.canvasPos[1];
218-
const markerWidth = this._marker.getBoundingClientRect().width;
220+
const markerWidth = this._curMarkerWidth;
219221
const markerDir = (this._markerAlign === "right") ? -1 : ((this._markerAlign === "center") ? 0 : 1);
220222
const markerCenter = left + markerDir * (markerWidth / 2 - 12);
221223
this._marker.style.left = px(markerCenter - markerWidth / 2);
222224
this._marker.style.top = px(top - 12);
223225
this._marker.style["z-index"] = 90005 + Math.floor(this._viewPos[2]) + 1;
224226

225-
const labelWidth = this._label.getBoundingClientRect().width;
227+
const labelWidth = this._curLabelWidth;
226228
const labelDir = Math.sign(this._labelPosition);
227229
this._label.style.left = px(markerCenter + labelDir * (markerWidth / 2 + Math.abs(this._labelPosition) + labelWidth / 2) - labelWidth / 2);
228230
this._label.style.top = px(top - 17);
229231
this._label.style["z-index"] = 90005 + Math.floor(this._viewPos[2]) + 1;
230232
}
231233

234+
/**
235+
* @private
236+
*/
237+
_updateIfWidthsChanged() {
238+
let needsUpdate = false;
239+
const markerWidth = this._marker.getBoundingClientRect().width;
240+
if (this._curMarkerWidth !== markerWidth) {
241+
this._curMarkerWidth = markerWidth;
242+
needsUpdate = true;
243+
}
244+
const labelDir = Math.sign(this._labelPosition);
245+
// if (labelDir === 1) then don't perform relatively expensive label.getBoundingClientRect call
246+
if (labelDir !== 1) {
247+
const labelWidth = this._label.getBoundingClientRect().width;
248+
if (this._curLabelWidth !== labelWidth) {
249+
this._curLabelWidth = labelWidth;
250+
needsUpdate = true;
251+
}
252+
}
253+
if (needsUpdate) {
254+
this._updateWithCurWidths();
255+
}
256+
}
257+
258+
/**
259+
* @private
260+
*/
261+
_updatePosition() {
262+
if (this._curMarkerWidth === undefined) {
263+
this._updateIfWidthsChanged();
264+
} else {
265+
// Update position with cached width values
266+
// and postpone expensive Annotation's getBoundingClientRect calls
267+
// so they don't interfere with e.g. interactive scene manipulation
268+
this._updateWithCurWidths();
269+
window.clearTimeout(this._widthTimeout);
270+
this._widthTimeout = window.setTimeout(() => this._updateIfWidthsChanged(), 500);
271+
}
272+
}
273+
232274
/**
233275
* @private
234276
*/

0 commit comments

Comments
 (0)