Last active
November 25, 2024 21:29
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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