creates type interface ScrollyVideoInstance
This commit is contained in:
parent
df9c4ae29c
commit
dabe1549a0
2 changed files with 77 additions and 13 deletions
|
|
@ -3,9 +3,10 @@
|
|||
import ScrollerBase from '../../ScrollerBase/ScrollerBase.svelte';
|
||||
import Tennis from '../videos/tennis.mp4';
|
||||
import { onDestroy } from 'svelte';
|
||||
import type { ScrollyVideoInstance } from '../ts/ScrollyVideo';
|
||||
|
||||
let progress = $state(0);
|
||||
let scrollyVideo = $state();
|
||||
let scrollyVideo: ScrollyVideoInstance | undefined = $state(undefined);
|
||||
let now;
|
||||
let then = 0;
|
||||
let time = 0;
|
||||
|
|
@ -13,15 +14,22 @@
|
|||
let loopCutoff = 0.35; // value between 0-1 to loop the video by
|
||||
let totalTime = 9 * 1000; // milliseconds
|
||||
|
||||
let animationId;
|
||||
let animationId = $state(0);
|
||||
|
||||
// clamps n value between low and high
|
||||
function constrain(n, low, high) {
|
||||
function constrain(n: number, low: number, high: number) {
|
||||
return Math.max(Math.min(n, high), low);
|
||||
}
|
||||
|
||||
// maps n value between two ranges
|
||||
function map(n, start1, stop1, start2, stop2, withinBounds = true) {
|
||||
function map(
|
||||
n: number,
|
||||
start1: number,
|
||||
stop1: number,
|
||||
start2: number,
|
||||
stop2: number,
|
||||
withinBounds = true
|
||||
) {
|
||||
const newval =
|
||||
((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
|
||||
if (!withinBounds) {
|
||||
|
|
@ -42,17 +50,21 @@
|
|||
|
||||
time += elapsed;
|
||||
currentProgress = map(time, 0, totalTime, 0, 1);
|
||||
scrollyVideo.setVideoPercentage(currentProgress, { jump: true });
|
||||
scrollyVideo?.setVideoPercentage(currentProgress, {
|
||||
jump: true,
|
||||
});
|
||||
|
||||
if (currentProgress > loopCutoff) {
|
||||
currentProgress = 0;
|
||||
time = 0;
|
||||
scrollyVideo.setVideoPercentage(0, { jump: true });
|
||||
scrollyVideo?.setVideoPercentage(0, { jump: true });
|
||||
}
|
||||
|
||||
then = now;
|
||||
} else {
|
||||
scrollyVideo.setVideoPercentage(progress, { jump: true });
|
||||
scrollyVideo?.setVideoPercentage(progress, {
|
||||
jump: true,
|
||||
});
|
||||
}
|
||||
|
||||
animationId = requestAnimationFrame(renderVideo);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ interface ScrollyVideoArgs {
|
|||
onChange?: (percentage?: number) => void;
|
||||
debug?: boolean;
|
||||
autoplay?: boolean;
|
||||
setVideoPercentage?: (
|
||||
percentage: number,
|
||||
options?: TransitionOptions
|
||||
) => void;
|
||||
resize?: () => void;
|
||||
}
|
||||
|
||||
interface TransitionOptions {
|
||||
|
|
@ -197,8 +202,8 @@ class ScrollyVideo {
|
|||
transitionSpeed = 8,
|
||||
frameThreshold = 0.1,
|
||||
useWebCodecs = true,
|
||||
onReady = () => {},
|
||||
onChange = (_percentage?: number) => {},
|
||||
onReady = () => { },
|
||||
onChange = (_percentage?: number) => { },
|
||||
debug = false,
|
||||
autoplay = false,
|
||||
}: ScrollyVideoArgs) {
|
||||
|
|
@ -464,7 +469,7 @@ class ScrollyVideo {
|
|||
setVideoPercentage(
|
||||
percentage: number,
|
||||
options: TransitionOptions = { jump: false, transitionSpeed: 8 }
|
||||
): void {
|
||||
) {
|
||||
// Early termination if the video percentage is already at the percentage that is intended.
|
||||
if (this.videoPercentage === percentage) return;
|
||||
|
||||
|
|
@ -736,7 +741,7 @@ class ScrollyVideo {
|
|||
const hasPassedThreshold =
|
||||
isForwardTransition ?
|
||||
this.currentTime >= this.targetTime
|
||||
: this.currentTime <= this.targetTime;
|
||||
: this.currentTime <= this.targetTime;
|
||||
|
||||
if (this.componentState.isAutoPlaying) {
|
||||
this.componentState.autoplayProgress = parseFloat(
|
||||
|
|
@ -775,7 +780,7 @@ class ScrollyVideo {
|
|||
isForwardTransition ?
|
||||
startCurrentTime +
|
||||
easedProgress * Math.abs(distance) * transitionSpeed
|
||||
: startCurrentTime -
|
||||
: startCurrentTime -
|
||||
easedProgress * Math.abs(distance) * transitionSpeed;
|
||||
|
||||
if (this.canvas) {
|
||||
|
|
@ -864,7 +869,7 @@ class ScrollyVideo {
|
|||
const targetDuration =
|
||||
this.frames?.length && this.frameRate ?
|
||||
this.frames.length / this.frameRate
|
||||
: this.video?.duration || 0;
|
||||
: this.video?.duration || 0;
|
||||
// The time we want to transition to
|
||||
this.targetTime = Math.max(Math.min(percentage, 1), 0) * targetDuration;
|
||||
|
||||
|
|
@ -967,3 +972,50 @@ class ScrollyVideo {
|
|||
}
|
||||
}
|
||||
export default ScrollyVideo;
|
||||
|
||||
// Complete ScrollyVideo instance interface
|
||||
export interface ScrollyVideoInstance {
|
||||
// Properties
|
||||
container: HTMLElement | null;
|
||||
scrollyVideoContainer: Element | string | undefined;
|
||||
src: string;
|
||||
transitionSpeed: number;
|
||||
frameThreshold: number;
|
||||
useWebCodecs: boolean;
|
||||
objectFit: string;
|
||||
sticky: boolean;
|
||||
trackScroll: boolean;
|
||||
onReady: () => void;
|
||||
onChange: (percentage?: number) => void;
|
||||
debug: boolean;
|
||||
autoplay: boolean;
|
||||
video: HTMLVideoElement | undefined;
|
||||
videoPercentage: number;
|
||||
isSafari: boolean;
|
||||
currentTime: number;
|
||||
targetTime: number;
|
||||
canvas: HTMLCanvasElement | null;
|
||||
context: CanvasRenderingContext2D | null;
|
||||
frames: ImageBitmap[] | null;
|
||||
frameRate: number;
|
||||
targetScrollPosition: number | null;
|
||||
currentFrame: number;
|
||||
usingWebCodecs: boolean;
|
||||
totalTime: number;
|
||||
transitioningRaf: number | null;
|
||||
componentState: ScrollyVideoState;
|
||||
|
||||
// Methods
|
||||
updateScrollPercentage: ((jump: boolean) => void) | undefined;
|
||||
resize: (() => void) | undefined;
|
||||
setVideoPercentage(percentage: number, options?: TransitionOptions): void;
|
||||
setCoverStyle(el: HTMLElement | HTMLCanvasElement | undefined): void;
|
||||
decodeVideo(): Promise<void>;
|
||||
paintCanvasFrame(frameNum: number): void;
|
||||
transitionToTargetTime(options: TransitionOptions): void;
|
||||
setTargetTimePercent(percentage: number, options?: TransitionOptions): void;
|
||||
setScrollPercent(percentage: number): void;
|
||||
destroy(): void;
|
||||
autoplayScroll(): void;
|
||||
updateDebugInfo(): void;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue