diff --git a/.storybook/src/utils/elements.ts b/.storybook/src/utils/elements.ts index 80afea63..7b2d7e18 100644 --- a/.storybook/src/utils/elements.ts +++ b/.storybook/src/utils/elements.ts @@ -11,7 +11,7 @@ export const createRootContainer = (width: number) => { export const createLayerContainer = (width: number, height: number) => { const container = document.createElement('div'); - container.className = 'layer-container'; + container.className = 'story-layer-container'; container.setAttribute('style', `height: ${height}px; width: ${width}px;background-color: #eee;`); container.setAttribute('height', `${height}`); container.setAttribute('width', `${width}`); diff --git a/src/control/LayerManager.ts b/src/control/LayerManager.ts index 0f9a6491..33161ee5 100644 --- a/src/control/LayerManager.ts +++ b/src/control/LayerManager.ts @@ -89,19 +89,30 @@ export class LayerManager { } /** - * Remove layer from manager, and unmounts it + * Remove and unmount layer from manager * @param layerId name of layer */ removeLayer(layerId: string): LayerManager { - const idx = this.layers.findIndex((l) => l.id === layerId); - if (idx !== -1) { - this.layers[idx].onUnmount(); - this.layers.splice(idx, 1); + const layer = this.layers.find((l) => l.id === layerId); + if (layer) { + layer.onUnmount(); + this.layers = this.layers.filter((l) => l.id !== layerId); } return this; } + /** + * Remove and unmount all layers from manager + */ + removeAllLayers(): LayerManager { + const { layers } = this; + layers.forEach((layer) => { + this.removeLayer(layer.id); + }); + return this; + } + getLayer(layerId: string): Layer { return this.layers.find((l) => l.id === layerId); } @@ -225,6 +236,20 @@ export class LayerManager { return this; } + destroy(): LayerManager { + this.clearAllData(true); + this.removeAllLayers(); + this.layerContainer.remove(); + this.layerContainer = undefined; + this.container = undefined; + this.layers = undefined; + this._zoomPanHandler = undefined; + this._axis = undefined; + this._svgContainer = undefined; + + return this; + } + get zoomPanHandler(): ZoomPanHandler { return this._zoomPanHandler; } diff --git a/src/control/MainController.ts b/src/control/MainController.ts index 189a3b7d..697b71ed 100644 --- a/src/control/MainController.ts +++ b/src/control/MainController.ts @@ -86,7 +86,7 @@ export class Controller { } /** - * Remove layer from list + * Remove and unmount layer from list * @param layerId string id */ removeLayer(layerId: string): Controller { @@ -94,6 +94,14 @@ export class Controller { return this; } + /** + * Remove and unmount all layers from list + */ + removeAllLayers(): Controller { + this.layerManager.removeAllLayers(); + return this; + } + /** * Find first layer with given id, returns undefined if none are found * @param layerId string id @@ -243,6 +251,19 @@ export class Controller { return this; } + /** + * Destroy Controller + * Convenience method for removing from DOM and clearing references + */ + destroy(): Controller { + this.layerManager.destroy(); + this._overlay.destroy(); + this._referenceSystem = undefined; + this.layerManager = undefined; + this._overlay = undefined; + return this; + } + private getHighestZIndex(layers: Layer[]): number { const highestZIndex = layers.length > 0 ? layers.reduce((max, layers) => (max.order > layers.order ? max : layers)).order : 1; return highestZIndex; diff --git a/src/control/overlay.ts b/src/control/overlay.ts index d99b5461..391d018a 100644 --- a/src/control/overlay.ts +++ b/src/control/overlay.ts @@ -109,6 +109,10 @@ class Overlay { setZIndex(zIndex: number): void { this.elm.style('z-index', zIndex); } + + destroy(): void { + this.source.remove(); + } } const overlay = (caller: any, container: HTMLElement): Overlay => new Overlay(caller, container); diff --git a/src/layers/CasingLayer.ts b/src/layers/CasingLayer.ts index c75b832e..0e053029 100644 --- a/src/layers/CasingLayer.ts +++ b/src/layers/CasingLayer.ts @@ -57,7 +57,7 @@ export class CasingLayer extends WellboreBaseComponentLayer { const casingWallWidth = Math.abs(casing.diameter - casing.innerDiameter); // Pixi.js-legacy handles SimpleRope and advanced render methods poorly - if (this.renderType === RENDERER_TYPE.CANVAS) { + if (this.renderType() === RENDERER_TYPE.CANVAS) { this.drawBigPolygon(polygon, solidColor); } else { this.drawRope( diff --git a/src/layers/CementLayer.ts b/src/layers/CementLayer.ts index faa9e308..f3384dbb 100644 --- a/src/layers/CementLayer.ts +++ b/src/layers/CementLayer.ts @@ -48,7 +48,7 @@ export class CementLayer extends WellboreBaseComponentLayer { const texture: Texture = this.createTexture(); cementShapes.forEach((cementShape: CementShape) => { - if (this.renderType === RENDERER_TYPE.CANVAS) { + if (this.renderType() === RENDERER_TYPE.CANVAS) { this.drawBigTexturedPolygon(cementShape.leftPolygon, texture); this.drawBigTexturedPolygon(cementShape.rightPolygon, texture); } else { diff --git a/src/layers/HoleSizeLayer.ts b/src/layers/HoleSizeLayer.ts index dd820895..29f06db1 100644 --- a/src/layers/HoleSizeLayer.ts +++ b/src/layers/HoleSizeLayer.ts @@ -62,7 +62,7 @@ export class HoleSizeLayer extends WellboreBaseComponentLayer { } const polygonCoords = makeTubularPolygon(leftPath, rightPath); - if (this.renderType === RENDERER_TYPE.CANVAS) { + if (this.renderType() === RENDERER_TYPE.CANVAS) { this.drawBigPolygon(polygonCoords, firstColor); } else { this.drawRope( diff --git a/src/layers/base/PixiLayer.ts b/src/layers/base/PixiLayer.ts index 4121157f..a647256b 100644 --- a/src/layers/base/PixiLayer.ts +++ b/src/layers/base/PixiLayer.ts @@ -41,6 +41,8 @@ export abstract class PixiLayer extends Layer { onUnmount(event?: OnUnmountEvent): void { super.onUnmount(event); + // Get renderType and clContext before we destroy the renderer + const renderType = this.renderType(); const glContext = this.ctx.renderer?.gl; this.ctx.stop(); @@ -52,7 +54,7 @@ export abstract class PixiLayer extends Layer { * * Cleaning up our self since it still seems to work and fix issue with lingering contexts */ - if (this.renderType === RENDERER_TYPE.WEBGL) { + if (renderType === RENDERER_TYPE.WEBGL) { glContext?.getExtension('WEBGL_lose_context')?.loseContext(); } @@ -114,7 +116,7 @@ export abstract class PixiLayer extends Layer { } } - get renderType(): RENDERER_TYPE { + renderType(): RENDERER_TYPE { return this.ctx.renderer.type; } }