Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ type CanvasCacheModuleConfig = {

const DEFAULT_CONFIG: CanvasCacheModuleConfig = {
imageNameCacheSize: 1000,
imageDataCacheSize: 32,
imageDataCacheSize: 64,
transparencyCalculationCacheSize: 1000,
canvasElementCacheSize: 32,
canvasElementCacheSize: 128,
generationModeCacheSize: 100,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ export abstract class CanvasEntityAdapterBase<T extends CanvasEntityState, U ext
*/
selectPosition = createSelector(this.selectState, (entity) => entity?.position);

syncIsOnscreen = () => {
syncIsOnscreen = rafThrottle(() => {
const stageRect = this.manager.stage.getScaledStageRect();
const isOnScreen = this.checkIntersection(stageRect);
const prevIsOnScreen = this.$isOnScreen.get();
Expand All @@ -334,17 +334,17 @@ export abstract class CanvasEntityAdapterBase<T extends CanvasEntityState, U ext
this.log.trace(`Moved ${isOnScreen ? 'on-screen' : 'off-screen'}`);
}
this.syncVisibility();
};
});

syncIntersectsBbox = () => {
syncIntersectsBbox = rafThrottle(() => {
const bboxRect = this.manager.stateApi.getBbox().rect;
const intersectsBbox = this.checkIntersection(bboxRect);
const prevIntersectsBbox = this.$intersectsBbox.get();
this.$intersectsBbox.set(intersectsBbox);
if (prevIntersectsBbox !== intersectsBbox) {
this.log.trace(`Moved ${intersectsBbox ? 'into bbox' : 'out of bbox'}`);
}
};
});

checkIntersection = (rect: Rect): boolean => {
const entityRect = this.transformer.$pixelRect.get();
Expand Down Expand Up @@ -526,8 +526,13 @@ export abstract class CanvasEntityAdapterBase<T extends CanvasEntityState, U ext
return;
}
this.log.trace(isVisible ? 'Showing' : 'Hiding');
this.konva.layer.visible(isVisible);
if (isVisible) {
// Re-attach the layer to the stage before making it visible. The layer was detached from the DOM when hidden
// to free browser compositing resources (each Konva.Layer is a separate <canvas> element).
if (!this.konva.layer.getParent()) {
this.manager.stage.addLayer(this.konva.layer);
}
this.konva.layer.visible(true);
/**
* When a layer is created and initially not visible, its compositing rect won't be set up properly. Then, when
* we show it in this method, it the layer will not render as it should.
Expand All @@ -542,6 +547,13 @@ export abstract class CanvasEntityAdapterBase<T extends CanvasEntityState, U ext
this.renderer.updateCompositingRectSize();
this.renderer.updateCompositingRectPosition();
this.renderer.updateCompositingRectFill();
// Restore correct z-order after re-attaching
this.manager.entityRenderer.arrangeEntities(this.manager.stateApi.runSelector(selectCanvasSlice), null);
} else {
this.konva.layer.visible(false);
// Detach the layer from the stage to remove its <canvas> element from the DOM. This frees browser compositing
// resources. The layer object is kept alive and can be re-attached when shown again.
this.konva.layer.remove();
}
this.renderer.syncKonvaCache();
};
Expand Down