scrolly-video
Advanced tools
Comparing version 0.0.20 to 0.0.21
@@ -14,3 +14,3 @@ export default ScrollyVideo; | ||
declare class ScrollyVideo { | ||
constructor({ src, scrollyVideoContainer, cover, sticky, full, trackScroll, transitionSpeed, frameThreshold, useWebCodecs, onReady, debug, }: { | ||
constructor({ src, scrollyVideoContainer, cover, sticky, full, trackScroll, lockScroll, transitionSpeed, frameThreshold, useWebCodecs, onReady, onChange, debug, }: { | ||
src: any; | ||
@@ -22,2 +22,3 @@ scrollyVideoContainer: any; | ||
trackScroll?: boolean; | ||
lockScroll?: boolean; | ||
transitionSpeed?: number; | ||
@@ -27,2 +28,3 @@ frameThreshold?: number; | ||
onReady?: () => void; | ||
onChange?: () => void; | ||
debug?: boolean; | ||
@@ -39,2 +41,3 @@ }); | ||
onReady: () => void; | ||
onChange: () => void; | ||
debug: boolean; | ||
@@ -50,4 +53,16 @@ video: HTMLVideoElement; | ||
updateScrollPercentage: (jump: any) => void; | ||
targetScrollPosition: any; | ||
resize: () => void; | ||
/** | ||
* Sets the currentTime of the video as a specified percentage of its total duration. | ||
* | ||
* @param percentage - The percentage of the video duration to set as the current time. | ||
* @param options - Configuration options for adjusting the video playback. | ||
* - jump: boolean - If true, the video currentTime will jump directly to the specified percentage. If false, the change will be animated over time. | ||
* - transitionSpeed: number - Defines the speed of the transition when `jump` is false. Represents the duration of the transition in milliseconds. Default is 8. | ||
* - easing: (progress: number) => number - A function that defines the easing curve for the transition. It takes the progress ratio (a number between 0 and 1) as an argument and returns the eased value, affecting the playback speed during the transition. | ||
*/ | ||
setVideoPercentage(percentage: any, options?: {}): void; | ||
videoPercentage: any; | ||
/** | ||
* Sets the style of the video or canvas to "cover" it's container | ||
@@ -85,3 +100,3 @@ * | ||
* | ||
* @param setPercentage - The percentage of the video duration to set as the current time. | ||
* @param percentage - The percentage of the video duration to set as the current time. | ||
* @param options - Configuration options for adjusting the video playback. | ||
@@ -92,3 +107,3 @@ * - jump: boolean - If true, the video currentTime will jump directly to the specified percentage. If false, the change will be animated over time. | ||
*/ | ||
setTargetTimePercent(setPercentage: any, options?: {}): void; | ||
setTargetTimePercent(percentage: any, options?: {}): void; | ||
/** | ||
@@ -95,0 +110,0 @@ * Simulate trackScroll programmatically (scrolls on page by percentage of video) |
import UAParser from 'ua-parser-js'; | ||
import videoDecoder from './videoDecoder'; | ||
import { debounce, isScrollPositionAtTarget } from './utils'; | ||
@@ -23,2 +24,3 @@ /** | ||
trackScroll = true, // Whether this object should automatically respond to scroll | ||
lockScroll = true, // Whether it ignores human scroll while it runs `setVideoPercentage` with enabled `trackScroll` | ||
transitionSpeed = 8, // How fast the video transitions between points | ||
@@ -28,2 +30,3 @@ frameThreshold = 0.1, // When to stop the video animation, in seconds | ||
onReady = () => {}, // A callback that invokes on video decode | ||
onChange = () => {}, // A callback that invokes on video percentage change | ||
debug = false, // Whether to print debug stats to the console | ||
@@ -70,2 +73,3 @@ }) { | ||
this.onReady = onReady; | ||
this.onChange = onChange; | ||
this.debug = debug; | ||
@@ -120,2 +124,9 @@ | ||
const debouncedScroll = debounce(() => { | ||
// eslint-disable-next-line no-undef | ||
window.requestAnimationFrame(() => { | ||
this.setScrollPercent(this.videoPercentage); | ||
}); | ||
}, 100); | ||
// Add scroll listener for responding to scroll position | ||
@@ -133,6 +144,14 @@ this.updateScrollPercentage = (jump) => { | ||
if (this.debug) console.info('ScrollyVideo scrolled to', scrollPercent); | ||
if (this.debug) { | ||
console.info('ScrollyVideo scrolled to', scrollPercent); | ||
} | ||
// Set the target time percent | ||
this.setTargetTimePercent(scrollPercent, { jump }); | ||
if (this.targetScrollPosition == null) { | ||
this.setTargetTimePercent(scrollPercent, { jump }); | ||
this.onChange(scrollPercent); | ||
} else if (isScrollPositionAtTarget(this.targetScrollPosition)) { | ||
this.targetScrollPosition = null; | ||
} else if (lockScroll && this.targetScrollPosition != null) { | ||
debouncedScroll(); | ||
} | ||
}; | ||
@@ -177,2 +196,28 @@ | ||
/** | ||
* Sets the currentTime of the video as a specified percentage of its total duration. | ||
* | ||
* @param percentage - The percentage of the video duration to set as the current time. | ||
* @param options - Configuration options for adjusting the video playback. | ||
* - jump: boolean - If true, the video currentTime will jump directly to the specified percentage. If false, the change will be animated over time. | ||
* - transitionSpeed: number - Defines the speed of the transition when `jump` is false. Represents the duration of the transition in milliseconds. Default is 8. | ||
* - easing: (progress: number) => number - A function that defines the easing curve for the transition. It takes the progress ratio (a number between 0 and 1) as an argument and returns the eased value, affecting the playback speed during the transition. | ||
*/ | ||
setVideoPercentage(percentage, options = {}) { | ||
if (this.transitioningRaf) { | ||
// eslint-disable-next-line no-undef | ||
window.cancelAnimationFrame(this.transitioningRaf); | ||
} | ||
this.videoPercentage = percentage; | ||
this.onChange(percentage); | ||
if (this.trackScroll) { | ||
this.setScrollPercent(percentage); | ||
} | ||
this.setTargetTimePercent(percentage, options); | ||
} | ||
/** | ||
* Sets the style of the video or canvas to "cover" it's container | ||
@@ -290,31 +335,28 @@ * | ||
paintCanvasFrame(frameNum) { | ||
if (this.canvas) { | ||
// Get the frame and paint it to the canvas | ||
const currFrame = this.frames[frameNum]; | ||
if (currFrame) { | ||
if (this.debug) console.info('Painting frame', frameNum); | ||
// Get the frame and paint it to the canvas | ||
const currFrame = this.frames[frameNum]; | ||
// Make sure the canvas is scaled properly, similar to setCoverStyle | ||
this.canvas.width = currFrame.width; | ||
this.canvas.height = currFrame.height; | ||
const { width, height } = this.container.getBoundingClientRect(); | ||
if (!this.canvas || !currFrame) { | ||
return; | ||
} | ||
if (width / height > currFrame.width / currFrame.height) { | ||
this.canvas.style.width = '100%'; | ||
this.canvas.style.height = 'auto'; | ||
} else { | ||
this.canvas.style.height = '100%'; | ||
this.canvas.style.width = 'auto'; | ||
} | ||
if (this.debug) { | ||
console.info('Painting frame', frameNum); | ||
} | ||
// Draw the frame to the canvas context | ||
this.context.drawImage( | ||
currFrame, | ||
0, | ||
0, | ||
currFrame.width, | ||
currFrame.height, | ||
); | ||
} | ||
// Make sure the canvas is scaled properly, similar to setCoverStyle | ||
this.canvas.width = currFrame.width; | ||
this.canvas.height = currFrame.height; | ||
const { width, height } = this.container.getBoundingClientRect(); | ||
if (width / height > currFrame.width / currFrame.height) { | ||
this.canvas.style.width = '100%'; | ||
this.canvas.style.height = 'auto'; | ||
} else { | ||
this.canvas.style.height = '100%'; | ||
this.canvas.style.width = 'auto'; | ||
} | ||
// Draw the frame to the canvas context | ||
this.context.drawImage(currFrame, 0, 0, currFrame.width, currFrame.height); | ||
} | ||
@@ -467,3 +509,3 @@ | ||
* | ||
* @param setPercentage - The percentage of the video duration to set as the current time. | ||
* @param percentage - The percentage of the video duration to set as the current time. | ||
* @param options - Configuration options for adjusting the video playback. | ||
@@ -474,10 +516,9 @@ * - jump: boolean - If true, the video currentTime will jump directly to the specified percentage. If false, the change will be animated over time. | ||
*/ | ||
setTargetTimePercent(setPercentage, options = {}) { | ||
// eslint-disable-next-line | ||
setTargetTimePercent(percentage, options = {}) { | ||
const targetDuration = | ||
this.frames.length && this.frameRate | ||
? this.frames.length / this.frameRate | ||
: this.video.duration; | ||
// The time we want to transition to | ||
this.targetTime = | ||
Math.max(Math.min(setPercentage, 1), 0) * | ||
(this.frames.length && this.frameRate | ||
? this.frames.length / this.frameRate | ||
: this.video.duration); | ||
this.targetTime = Math.max(Math.min(percentage, 1), 0) * targetDuration; | ||
@@ -515,6 +556,11 @@ // If we are close enough, return early | ||
const containerHeightInViewport = height - window.innerHeight; | ||
const targetPoint = startPoint + containerHeightInViewport * percentage; | ||
const targetPosition = startPoint + containerHeightInViewport * percentage; | ||
// eslint-disable-next-line no-undef | ||
window.scrollTo({ top: targetPoint, behavior: 'smooth' }); | ||
if (isScrollPositionAtTarget(targetPosition)) { | ||
this.targetScrollPosition = null; | ||
} else { | ||
// eslint-disable-next-line no-undef | ||
window.scrollTo({ top: targetPosition, behavior: 'smooth' }); | ||
this.targetScrollPosition = targetPosition; | ||
} | ||
} | ||
@@ -521,0 +567,0 @@ |
{ | ||
"name": "scrolly-video", | ||
"version": "0.0.20", | ||
"version": "0.0.21", | ||
"description": "A component for scroll-based (or other externally controlled) playback.", | ||
@@ -5,0 +5,0 @@ "main": "dist/scrolly-video.js", |
@@ -86,5 +86,7 @@ # ScrollyVideo.js | ||
| trackScroll | Whether this object should automatically respond to scroll | Boolean | true | | ||
| lockScroll | Whether it ignores human scroll while it runs `setVideoPercentage` with enabled `trackScroll` | Boolean | true | | ||
| useWebCodecs | Whether the library should use the webcodecs method, see below | Boolean | true | | ||
| videoPercentage | Manually specify the position of the video between 0..1, only used for react, vue, and svelte components | Number | | | ||
| onReady | The callback when it's ready to scroll | VoidFunction | | | ||
| onChange | The callback for video percentage change | VoidFunction | | | ||
| debug | Whether to log debug information | Boolean | false | | ||
@@ -95,21 +97,11 @@ | ||
***setTargetTimePercent*** | ||
***setVideoPercentage*** | ||
Description: A way to set currentTime manually. Pass a progress in between of 0 and 1 that specifies the percentage position of the video. | ||
Description: A way to set currentTime manually. Pass a progress in between of 0 and 1 that specifies the percentage position of the video. If `trackScroll` enabled - it performs scroll automatically. | ||
Signature: `(percentage: number, options: { transitionSpeed: number, (progress: number) => number }) => void` | ||
Example: `scrollyVideo.setTargetTimePercent(0.5, { transitionSpeed: 12, easing: d3.easeLinear })` | ||
Example: `scrollyVideo.setVideoPercentage(0.5, { transitionSpeed: 12, easing: d3.easeLinear })` | ||
<br/> | ||
***setScrollPercent*** | ||
Description: A way to set video currentTime manually based on `trackScroll` i.e. pass a progress in between of 0 and 1 that specifies the percentage position of the video and it will scroll smoothly. Make sure to have `trackScroll` enabled. | ||
Signature: `(percentage: number) => void` | ||
Example: `scrollyVideo.setScrollPercent(0.5)` | ||
## Technical Details and Cross Browser Differences | ||
@@ -116,0 +108,0 @@ To make this library perform optimally in all browsers, three different approaches are taken to animating the video. |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
15647152
28
30454
130