UNPKG

@glair/web-components

Version:
175 lines (174 loc) 6.57 kB
import { t as e } from "./decorate-9sBcXH5_.js"; import { t } from "./tailwind.element-C1twz-cO.js"; import { html as n } from "lit"; import { customElement as r, property as i, query as a, state as o } from "lit/decorators.js"; //#region src/assets/images/corner_overlay.png var s = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAABBklEQVR4Ae3TUQ2EQBTAwH2XE4wvdKFj8UBI6MeMhaaz974Wn/stEoSIECJCiAghIoSIECJCiAghIoSIECJCiIj/euaYmXPxGkdECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQEUJECBEhRIQQETcExQXG6zjxjAAAAABJRU5ErkJggg=="; //#endregion //#region src/utils/camera.ts function c(e) { let t = l(e); return t && t.toDataURL("image/jpeg", .92); } function l(e) { let { ref: t, width: n = 480, height: r = 480, mirrored: i = !1, screenshotArea: a } = e, o = n * a.width / 100, s = r * a.height / 100, c = document.createElement("canvas"); c.width = o, c.height = s; let l = c.getContext("2d"); if (l && c) { i && (l.translate(c.width, 0), l.scale(-1, 1)); let { takeWidth: e, takeHeight: u, translateX: d, translateY: f } = (() => { let e, o, s, c, l = n / r; l > t.videoWidth / t.videoHeight ? (e = t.videoWidth, o = t.videoWidth * (1 / l), s = 0, c = (t.videoHeight - o) / 2) : (e = t.videoHeight * l, o = t.videoHeight, s = (t.videoWidth - e) / 2, c = 0); let u = () => (s += Math.round(a.x / 100 * e), c += Math.round(a.y / 100 * o), e = e * a.width / 100, o = o * a.height / 100, i && (s = t.videoWidth - (s + e)), { takeWidth: e, takeHeight: o, translateX: s, translateY: c }); return {takeWidth: e, takeHeight: o, translateX: s, translateY: c} = u(), { takeWidth: e, takeHeight: o, translateX: s, translateY: c }; })(); l.drawImage(t, d, f, e, u, 0, 0, o, s), i && (l.scale(-1, 1), l.translate(-c.width, 0)); } return c; } //#endregion //#region src/components/webcam.ts var u = class extends t { constructor(...e) { super(...e), this.width = 480, this.height = 480, this.facingMode = "user", this.mirrored = !1, this.screenshotArea = JSON.stringify({ x: 0, y: 0, width: 100, height: 100, enableOverlay: !1 }), this._isUserMedia = !1, this._stream = null, this._screenshotAreaObj = { x: 0, y: 0, width: 100, height: 100, enableOverlay: !1 }, this._isMounted = !0; } async connectedCallback() { super.connectedCallback(), await this.requestUserMedia(), this._screenshotAreaObj = this.preProcessScreenshotArea(); } async disconnectedCallback() { super.disconnectedCallback(), this._isMounted = !1, this.stopStream(); } async requestUserMedia() { try { let e = await navigator.mediaDevices.getUserMedia({ video: { facingMode: this.facingMode } }); this._stream = e, this.videoEl.srcObject = e, this._isUserMedia = !0, this._isMounted || this.stopStream(); } catch (e) { console.log("Error occured", e); } } preProcessScreenshotArea() { let e = JSON.parse(this.screenshotArea); function t(e, t) { return e + t > 100; } return t(e.x, e.width) && (e.width = 100 - e.x), t(e.y, e.height) && (e.height = 100 - e.y), e; } stopStream() { this._stream?.getTracks().forEach((e) => { this._stream?.removeTrack(e), e.stop(); }); } async screenshot() { return c({ ref: this.videoEl, width: this.width, height: this.height, mirrored: this.mirrored, screenshotArea: this._screenshotAreaObj }); } render() { return n` <div class="relative bg-gray-200"> <video autoplay muted playsinline class="object-cover" style="width: ${this.width}px; height: ${this.height}px; transform: scaleX(${this.mirrored ? "-1" : "1"});" ></video> ${this.userMediaError()} ${this.userMedia()} ${this.screenshotOverlay()} </div> `; } userMediaError() { return n` <div style="${this._isUserMedia ? "display: none" : "display: revert"}"> <slot name="user-media-error"> <div class="absolute top-[50%] left-[50%] flex w-[300px] translate-y-[-50%] translate-x-[-50%] flex-col rounded-sm border bg-white py-4 px-8" > <p class="text-[20px]">Camera blocked</p> <p class="my-4"> Please allow camera access in your browser settings and try again. </p> <div class="flex flex-col items-end"> <button type="button" class="text-md text-[#009CDE]" .onclick=${() => location.reload()} > Try Again </button> </div> </div> </slot> </div> `; } userMedia() { return n` <div style="${this._isUserMedia ? "display: revert" : "display: none"}"> <slot name="user-media"> <img src=${s} alt="overlay" width="50" class="absolute top-12 left-12" /> <img src=${s} alt="overlay" width="50" class="absolute bottom-12 left-12 -rotate-90" /> <img src=${s} alt="overlay" width="50" class="absolute top-12 right-12 rotate-90" /> <img src=${s} alt="overlay" width="50" class="absolute bottom-12 right-12 rotate-180" /> </slot> </div> `; } screenshotOverlay() { return this._screenshotAreaObj?.enableOverlay ? n` <div class="absolute border border-dashed border-red-500" style="top: ${this._screenshotAreaObj?.y}%; left: ${this._screenshotAreaObj?.x}%; width: ${this._screenshotAreaObj?.width}%; height: ${this._screenshotAreaObj?.height}%" ></div> ` : n``; } }; e([a("video")], u.prototype, "videoEl", void 0), e([i({ type: Number })], u.prototype, "width", void 0), e([i({ type: Number })], u.prototype, "height", void 0), e([i({ type: String })], u.prototype, "facingMode", void 0), e([i({ type: Boolean })], u.prototype, "mirrored", void 0), e([i({ type: String })], u.prototype, "screenshotArea", void 0), e([o()], u.prototype, "_isUserMedia", void 0), e([o()], u.prototype, "_stream", void 0), e([o()], u.prototype, "_screenshotAreaObj", void 0), e([o()], u.prototype, "_isMounted", void 0), u = e([r("glair-webcam")], u); //#endregion export { u as Webcam };