Skip to content

Commit 3ceb904

Browse files
authored
Merge pull request #1761 from xeokit/1704-improve-annotations-performance
#1704 Optimize Annotations' position update
2 parents 3689876 + 95bedb4 commit 3ceb904

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

src/plugins/AnnotationsPlugin/Annotation.js

Lines changed: 45 additions & 5 deletions
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,27 +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 markerRect = this._marker.getBoundingClientRect();
219-
const markerWidth = markerRect.width;
220+
const markerWidth = this._curMarkerWidth;
220221
const markerDir = (this._markerAlign === "right") ? -1 : ((this._markerAlign === "center") ? 0 : 1);
221222
const markerCenter = left + markerDir * (markerWidth / 2 - 12);
222223
this._marker.style.left = px(markerCenter - markerWidth / 2);
223224
this._marker.style.top = px(top - 12);
224225
this._marker.style["z-index"] = 90005 + Math.floor(this._viewPos[2]) + 1;
225226

226-
const labelRect = this._label.getBoundingClientRect();
227-
const labelWidth = labelRect.width;
227+
const labelWidth = this._curLabelWidth;
228228
const labelDir = Math.sign(this._labelPosition);
229229
this._label.style.left = px(markerCenter + labelDir * (markerWidth / 2 + Math.abs(this._labelPosition) + labelWidth / 2) - labelWidth / 2);
230230
this._label.style.top = px(top - 17);
231231
this._label.style["z-index"] = 90005 + Math.floor(this._viewPos[2]) + 1;
232232
}
233233

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+
234274
/**
235275
* @private
236276
*/

0 commit comments

Comments
 (0)