Skip to content

Instantly share code, notes, and snippets.

@royvn
Last active November 25, 2024 21:29
Show Gist options
  • Save royvn/be09a1d73d918043c30bccd80d4b7c30 to your computer and use it in GitHub Desktop.
Save royvn/be09a1d73d918043c30bccd80d4b7c30 to your computer and use it in GitHub Desktop.
Video observer for Shopify video. Plays when it's in viewport, stops when it's out of viewport.
/**
* Web component to play and stop videos that are in viewport.
* Example usage:
* <video-observer class="block">
{{ section.settings.video | video_tag: preload: "none", muted: true, autoplay: false, loop: true, playsinline: true, controls: false, image_size: '1440x', class: video_class }}
</video-observer>
*/
class VideoObserver extends HTMLElement {
/** @type {HTMLVideoElement | null} */
video = null;
/** @type {IntersectionObserver | null} */
observer = null;
/** @type {{ threshold: number }} */
options = {
threshold: 0.25,
};
connectedCallback() {
const video = this.querySelector('video');
const options = JSON.parse(this.dataset.options || '{}');
this.options = {
...this.options,
...options,
};
if (video) {
this.video = video;
if (this.video && 'IntersectionObserver' in window) {
this.observer = new IntersectionObserver(this.observerCallback, {
threshold: this.options.threshold,
});
this.observer.observe(this.video);
} else if (this.video) {
this.video.play();
}
}
}
disconnectedCallback() {
if (this.observer) this.observer.disconnect();
}
observerCallback = (entries) => {
entries.forEach((entry) => {
const { target: video } = entry;
entry.isIntersecting ? video.play() : video.pause();
});
};
}
customElements.define('video-observer', VideoObserver);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment