UNPKG

@panoramax/web-viewer

Version:

Panoramax web viewer for geolocated pictures

156 lines (138 loc) 4.66 kB
import { LitElement, html, css, nothing } from "lit"; import { faSvg, iconify } from "../styles"; import { fa, moreIcons } from "../../utils/widgets"; import { faChevronRight } from "@fortawesome/free-solid-svg-icons/faChevronRight"; import { faArrowLeft } from "@fortawesome/free-solid-svg-icons/faArrowLeft"; import { onceParentAvailable } from "../../utils/widgets"; import "iconify-icon"; /** * Annotations list shows listing of tagged picture areas. * It uses the parent component currently selected picture. * * @class Panoramax.components.menus.AnnotationsList * @element pnx-annotations-list * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/) * @example * ```html * <pnx-annotations-list _parent=${viewer} /> * ``` */ export default class AnnotationsList extends LitElement { /** @private */ static styles = [ faSvg, iconify, css` .annotation { background: var(--white); } ` ]; /** @private */ static properties = { _meta: {state: true}, _selectedAnnotation: {state: true}, _presets: {state: true}, }; constructor() { super(); this._selectedAnnotation = null; this._presets = {}; moreIcons(); } /** @private */ connectedCallback() { super.connectedCallback(); this._onPicChange(); onceParentAvailable(this).then(() => { this._parent.psv?.addEventListener("picture-loaded", this._onPicChange.bind(this)); this._parent.psv?.addEventListener("annotation-click", e => { const aPos = this._meta.properties?.annotations?.findIndex(a => a.id === e.detail.annotationId); if(aPos >= 0) { this._onListItemClick(Object.assign({nb: aPos+1}, this._meta.properties.annotations[aPos])); } }); this._parent.psv?.addEventListener("annotations-unfocused", () => { this._onListItemClick(null); }); }); } /** @private */ _onPicChange() { this._meta = this._parent?.psv?.getPictureMetadata(); delete this._prevPsvView; this._selectedAnnotation = null; // Load presets for annotations if(this._meta && this._parent?.presetsManager) { this._presets = {}; if(this._meta.properties?.annotations?.length > 0) { this._meta.properties.annotations.map(a => this._parent.presetsManager.getPreset(a).then(p => { this._presets[a.id] = p; this.requestUpdate(); })); } } } /** @private */ _onListItemHover(a) { if(a) { // Save position before hover to allow reset after if(!this._prevPsvView) { this._prevPsvView = [this._parent.psv.getZoomLevel(), this._parent.psv.getPosition()]; } this._parent.psv.focusOnAnnotation(a.id); } else { this._parent.psv.unfocusAnnotation(); // Restore previous PSV position if(this._prevPsvView) { this._parent.psv.zoom(this._prevPsvView[0]); this._parent.psv.rotate(this._prevPsvView[1]); delete this._prevPsvView; } } } /** @private */ _onListItemClick(a) { this._selectedAnnotation = a; this._onListItemHover(a); } /** @private */ render() { /* eslint-disable indent */ if(!this._meta) { return nothing; } return this._selectedAnnotation === null ? html`<div class="list"> ${this._meta.properties.annotations.map((a,i) => html` <pnx-list-item title=${ this._presets[a.id]?.name || this._parent?._t.pnx.semantics_features_default_title.replace("{nb}", i+1) } subtitle=${this._parent?._t.pnx.semantics_features_subtitle.replace("{nb}", a.semantics.length)} @click=${() => this._onListItemClick(Object.assign({nb: i+1}, a))} @mouseover=${() => this._onListItemHover(Object.assign({nb: i+1}, a))} @mouseout=${() => this._onListItemHover(null)} > <iconify-icon slot="icon" icon=${this._presets[a.id]?.iconify || "fa6-solid:cube"} style="font-size: 1.5em" ></iconify-icon> ${fa(faChevronRight, {transform: {size: 24}, attributes: {slot: "action"}})} </pnx-list-item> `)} </div>` : html`<div class="annotation"> <pnx-list-item title=${ this._presets[this._selectedAnnotation.id]?.name || this._parent?._t.pnx.semantics_features_default_title.replace("{nb}", this._selectedAnnotation.nb) } @click=${() => this._onListItemClick(null)} > ${fa(faArrowLeft, {transform: {size: 24}, attributes: {slot: "icon"}})} <iconify-icon slot="icon" icon=${this._presets[this._selectedAnnotation.id]?.iconify || "fa6-solid:cube"} style="font-size: 1.5em" ></iconify-icon> </pnx-list-item> <pnx-semantics-table ._t=${this._parent?._t} .source=${this._selectedAnnotation} /> </div>`; } } customElements.define("pnx-annotations-list", AnnotationsList);