From 58e4a0d4226d749b19f729dc06ce4fb94d93a431 Mon Sep 17 00:00:00 2001 From: Max Tarsis <21989873+tarsinzer@users.noreply.github.com> Date: Thu, 28 Mar 2024 06:15:15 +0000 Subject: [PATCH] Feat: align trackScroll with videoPercentage (#91) * feat: add manual scroll feature to synchronise progress of percentage and autoscroll * feat: update implementations * refactor: prevent invoking setScrollPercent when trackScroll=false --- src/ScrollyVideo.js | 24 ++++++++++++++++++++++++ src/ScrollyVideo.jsx | 15 +++++++++++---- src/ScrollyVideo.svelte | 13 +++++++++++-- src/ScrollyVideo.vue | 6 +++++- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/ScrollyVideo.js b/src/ScrollyVideo.js index 2bdba24..cea0b7f 100644 --- a/src/ScrollyVideo.js +++ b/src/ScrollyVideo.js @@ -469,6 +469,30 @@ class ScrollyVideo { this.transitionToTargetTime(options); } + /** + * Simulate trackScroll programmatically (scrolls on page by percentage of video) + * + * @param percentage + */ + setScrollPercent(percentage) { + if (!this.trackScroll) { + console.warn('`setScrollPercent` requires enabled `trackScroll`'); + return; + } + + const parent = this.container.parentNode; + const { top, height } = parent.getBoundingClientRect(); + + // eslint-disable-next-line no-undef + const startPoint = top + window.pageYOffset; + // eslint-disable-next-line no-undef + const containerHeightInViewport = height - window.innerHeight; + const targetPoint = startPoint + containerHeightInViewport * percentage; + + // eslint-disable-next-line no-undef + window.scrollTo({ top: targetPoint }); + } + /** * Call to destroy this ScrollyVideo object */ diff --git a/src/ScrollyVideo.jsx b/src/ScrollyVideo.jsx index 73851c5..91a8414 100644 --- a/src/ScrollyVideo.jsx +++ b/src/ScrollyVideo.jsx @@ -1,9 +1,9 @@ import React, { forwardRef, useEffect, - useImperativeHandle, - useRef, useState, + useRef, + useImperativeHandle, } from 'react'; import ScrollyVideo from './ScrollyVideo'; @@ -75,9 +75,13 @@ const ScrollyVideoComponent = forwardRef(function ScrollyVideoComponent( videoPercentage >= 0 && videoPercentage <= 1 ) { - scrollyVideoRef.current.setTargetTimePercent(videoPercentage); + if (trackScroll) { + scrollyVideoRef.current.setScrollPercent(videoPercentage) + } else { + scrollyVideoRef.current.setTargetTimePercent(videoPercentage); + } } - }, [videoPercentage]); + }, [videoPercentage, trackScroll]); // effect for unmount useEffect( @@ -95,6 +99,9 @@ const ScrollyVideoComponent = forwardRef(function ScrollyVideoComponent( setTargetTimePercent: scrollyVideoRef.current ? scrollyVideoRef.current.setTargetTimePercent.bind(instance) : () => {}, + setScrollPercent: scrollyVideoRef.current + ? scrollyVideoRef.current.setScrollPercent.bind(instance) + : () => {}, }), [instance], ); diff --git a/src/ScrollyVideo.svelte b/src/ScrollyVideo.svelte index 4241961..bd60ae7 100644 --- a/src/ScrollyVideo.svelte +++ b/src/ScrollyVideo.svelte @@ -26,8 +26,17 @@ } // If we need to update the target time percent - if (scrollyVideo && typeof videoPercentage === 'number' && videoPercentage >= 0 && videoPercentage <= 1) { - scrollyVideo.setTargetTimePercent(videoPercentage); + if ( + scrollyVideo && + typeof videoPercentage === 'number' && + videoPercentage >= 0 && + videoPercentage <= 1 + ) { + if (restProps.trackScroll) { + scrollyVideo.setScrollPercent(videoPercentage); + } else { + scrollyVideo.setTargetTimePercent(videoPercentage); + } } } } diff --git a/src/ScrollyVideo.vue b/src/ScrollyVideo.vue index 0693212..29348f5 100644 --- a/src/ScrollyVideo.vue +++ b/src/ScrollyVideo.vue @@ -44,7 +44,11 @@ export default { videoPercentage >= 0 && videoPercentage <= 1 ) { - this.scrollyVideo.setTargetTimePercent(videoPercentage); + if (restProps.trackScroll) { + this.scrollyVideo.setScrollPercent(videoPercentage); + } else { + this.scrollyVideo.setTargetTimePercent(videoPercentage); + } } }, deep: true,