UNPKG

@teipublisher/pb-components

Version:
109 lines (96 loc) 2.66 kB
import { LitElement, html, css } from 'lit-element'; import '@lrnwebcomponents/es-global-bridge'; import { pbMixin } from './pb-mixin.js'; /** * Show an SVG image with zoom and pan functionality. The image URL may * either be specified via the `url` property or an `pb-show-annotation` event * sent to this component. A relative URL will be resolved against the current API context. * * @fires pb-show-annotation - When received, loads the image from the URL passed in property `file` * within the event * @cssprop --pb-svg-height - Height of the SVG element * @cssprop --pb-svg-width - Width of the SVG element */ export class PbSvg extends pbMixin(LitElement) { static get properties() { return { ...super.properties, /** * The URL to load the SVG from. */ url: { type: String, }, }; } constructor() { super(); this._pan = null; } connectedCallback() { super.connectedCallback(); window.ESGlobalBridge.requestAvailability(); window.ESGlobalBridge.instance.load( 'svg-pan-zoom', `https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js`, ); this.subscribeTo('pb-show-annotation', ev => { if (this.url === ev.detail.file) { return; } this.url = ev.detail.file; }); } firstUpdated() { super.firstUpdated(); this.container = this.shadowRoot.getElementById('image'); } updated(changed) { if (changed.has('url') && this.url && this.url !== changed.get('url')) { this.load(); } } load() { if (!this.url) { return; } const uri = this.toAbsoluteURL(this.url); console.log('<pb-svg> Loading %s', uri); if (this._pan) { this._pan.destroy(); this._pan = null; this.container.innerHTML = ''; } fetch(uri) .then(response => response.text()) .then(data => { if (!window.svgPanZoom) { console.error('<pb-svg> svgPanZoom not available'); return; } const doc = new DOMParser().parseFromString(data, 'image/svg+xml'); const svg = doc.documentElement; this.container.appendChild(svg); this._pan = window.svgPanZoom(svg, { controlIconsEnabled: true, fit: true, center: true, }); }); } render() { return html`<div id="image"></div>`; } static get styles() { return css` :host { display: block; } #image svg { height: var(--pb-svg-height, 100%); width: var(--pb-svg-width, 100%); } `; } } customElements.define('pb-svg', PbSvg);