@itk-viewer/element
Version:
Web Component for multi-dimensional viewer
86 lines (73 loc) • 2.12 kB
text/typescript
import { LitElement, css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { ref } from 'lit/directives/ref.js';
import { SelectorController } from 'xstate-lit';
import { ActorRefFrom } from 'xstate';
import { createLogic } from '@itk-viewer/vtkjs/view-2d-vtkjs.js';
import { dispatchSpawn } from './spawn-controller.js';
import { Camera } from '@itk-viewer/viewer/camera.js';
import './itk-camera.js';
type ComponentActor = ActorRefFrom<ReturnType<typeof createLogic>>;
('itk-view-2d-vtkjs')
export class ItkView2dVtkjs extends LitElement {
actor: ComponentActor | undefined;
container: HTMLElement | undefined;
dispatched = false;
cameraActor:
| SelectorController<ComponentActor, Camera | undefined>
| undefined;
getActor(): ComponentActor | undefined {
return this.actor;
}
setActor(actor: ComponentActor) {
this.actor = actor;
this.sendContainer();
this.cameraActor = new SelectorController(
this,
this.actor,
(state) => state.context.camera,
);
}
protected sendContainer() {
if (!this.actor) return;
this.actor.send({ type: 'setContainer', container: this.container });
}
protected onContainer(container: Element | undefined) {
if (container instanceof HTMLElement || container == undefined) {
this.container = container;
this.sendContainer();
}
}
render() {
if (!this.dispatched) {
dispatchSpawn(this, 'renderer', createLogic(), (actor) =>
this.setActor(actor),
);
this.dispatched = true;
}
return html`
<itk-camera .actor=${this.cameraActor?.value} class="container">
<div class="container" ${ref(this.onContainer)}></div>
</itk-camera>
`;
}
static styles = css`
:host {
flex: 1;
display: flex;
flex-direction: column;
}
.container {
flex: 1;
min-height: 0;
overflow: hidden;
display: flex;
flex-direction: column;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
'itk-view-2d-vtkjs': ItkView2dVtkjs;
}
}