@glair/web-components
Version:
A collection of GLAIR's web components
175 lines (174 loc) • 6.57 kB
JavaScript
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 };