UNPKG

@aidenlx/player

Version:

Headless web components that make integrating media on the a web a breeze.

140 lines (137 loc) 3.74 kB
import { __decorateClass } from "../../chunks/chunk.LNH2V2XS.js"; import { createIntersectionController, isUndefined, preconnect } from "@vidstack/foundation"; import { css, html, LitElement } from "lit"; import { property, state } from "lit/decorators.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { MediaRemoteControl, mediaStoreSubscription } from "../../media"; const didPreconnect = /* @__PURE__ */ new Set(); class PosterElement extends LitElement { constructor() { super(); this.__canLoad = false; this._mediaRemoteControl = new MediaRemoteControl(this); mediaStoreSubscription(this, "currentPoster", ($poster) => { window.requestAnimationFrame(() => { if (!this.__canLoad && !didPreconnect.has($poster)) { preconnect($poster, "prefetch"); didPreconnect.add($poster); } }); this.__src = $poster; if (this.__canLoad) { this._setImgLoadingAttr(); } }); mediaStoreSubscription(this, "canLoad", ($canLoad) => { if (isUndefined(this.loading)) { this._handleCanLoadChange($canLoad); } }); const intersectionController = createIntersectionController(this, { threshold: 0 }, (entries) => { if (this.loading !== "lazy") { intersectionController.hostDisconnected(); return; } if (entries[0]?.isIntersecting) { this._handleCanLoadChange(true); intersectionController.hostDisconnected(); } }); } static get styles() { return [ css` :host { display: block; contain: content; pointer-events: none; object-fit: cover; box-sizing: border-box; } :host([hidden]) { display: none; } img { display: block; width: 100%; height: 100%; pointer-events: none; object-fit: inherit; object-position: inherit; user-select: none; -webkit-user-select: none; box-sizing: border-box; } ` ]; } get src() { return this.__src; } connectedCallback() { super.connectedCallback(); if (this.loading === "eager") { this._handleCanLoadChange(true); } this._mediaRemoteControl.hidePoster(); } disconnectedCallback() { this._mediaRemoteControl.showPoster(); super.disconnectedCallback(); this.__src = void 0; this._handleCanLoadChange(false); } render() { return html` <img part="img" src=${ifDefined(this.__canLoad ? this.src : null)} alt=${ifDefined(this.alt)} @load=${this._handleImgLoad} @error=${this._handleImgError} /> `; } _setImgLoadingAttr() { this.removeAttribute("img-error"); this.removeAttribute("img-loaded"); if (this.__canLoad && this.src) { this.setAttribute("img-loading", ""); } } _handleImgLoad() { this.removeAttribute("img-loading"); this.setAttribute("img-loaded", ""); } _handleImgError() { this.removeAttribute("img-loading"); this.setAttribute("img-error", ""); } _handleCanLoadChange(canLoad) { if (canLoad) { this._setImgLoadingAttr(); } else { this.removeAttribute("img-error"); this.removeAttribute("img-loaded"); this.removeAttribute("img-loading"); } this.__canLoad = canLoad; } } __decorateClass([ state() ], PosterElement.prototype, "__src", 2); __decorateClass([ state() ], PosterElement.prototype, "__canLoad", 2); __decorateClass([ property() ], PosterElement.prototype, "loading", 2); __decorateClass([ property() ], PosterElement.prototype, "alt", 2); export { PosterElement };