Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions scrollytelling/src/components/debugger/visualizer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,8 @@ export const Visualizer = () => {
<path
d="M10.875 6.00004L6.398 1.52254C6.178 1.30304 5.822 1.30304 5.6025 1.52254L1.125 6.00004M9.75 4.87504V9.93754C9.75 10.248 9.498 10.5 9.1875 10.5H7.125V8.06254C7.125 7.75204 6.873 7.50004 6.5625 7.50004H5.4375C5.127 7.50004 4.875 7.75204 4.875 8.06254V10.5H2.8125C2.502 10.5 2.25 10.248 2.25 9.93754V4.87504M7.875 10.5H3.75"
stroke="white"
stroke-linecap="round"
stroke-linejoin="round"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
SCROLL TO ROOT
Expand All @@ -502,14 +502,14 @@ export const Visualizer = () => {
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M2.43359 8C2.43359 7.72386 2.65745 7.5 2.93359 7.5H13.0669C13.3431 7.5 13.5669 7.72386 13.5669 8C13.5669 8.27614 13.3431 8.5 13.0669 8.5H2.93359C2.65745 8.5 2.43359 8.27614 2.43359 8Z"
fill="white"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M8 2.43311C8.27614 2.43311 8.5 2.65697 8.5 2.93311L8.5 13.0664C8.5 13.3426 8.27614 13.5664 8 13.5664C7.72386 13.5664 7.5 13.3426 7.5 13.0664L7.5 2.93311C7.5 2.65697 7.72386 2.43311 8 2.43311Z"
fill="white"
/>
Expand All @@ -521,8 +521,8 @@ export const Visualizer = () => {
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M2.43359 8C2.43359 7.72386 2.65745 7.5 2.93359 7.5H13.0669C13.3431 7.5 13.5669 7.72386 13.5669 8C13.5669 8.27614 13.3431 8.5 13.0669 8.5H2.93359C2.65745 8.5 2.43359 8.27614 2.43359 8Z"
fill="white"
/>
Expand All @@ -536,8 +536,8 @@ export const Visualizer = () => {
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M12.5402 4.27333C12.7648 4.04878 12.7648 3.68471 12.5402 3.46016C12.3157 3.23561 11.9516 3.23561 11.7271 3.46016L8.00033 7.18691L4.27358 3.46016C4.04903 3.23561 3.68496 3.23561 3.46041 3.46016C3.23585 3.68471 3.23585 4.04878 3.46041 4.27333L7.18715 8.00008L3.46041 11.7268C3.23585 11.9514 3.23585 12.3154 3.46041 12.54C3.68496 12.7646 4.04903 12.7646 4.27358 12.54L8.00033 8.81325L11.7271 12.54C11.9516 12.7646 12.3157 12.7646 12.5402 12.54C12.7648 12.3154 12.7648 11.9514 12.5402 11.7268L8.8135 8.00008L12.5402 4.27333Z"
fill="white"
/>
Expand Down Expand Up @@ -604,14 +604,14 @@ export const Visualizer = () => {
>
<mask id="path-1-inside-1_2793_1632" fill="white">
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M8 0H0V8L4 11L8 8V0Z"
/>
</mask>
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M8 0H0V8L4 11L8 8V0Z"
fill="white"
/>
Expand Down
124 changes: 109 additions & 15 deletions scrollytelling/src/image-sequence-canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,49 @@
import * as React from "react";
import { mergeRefs } from "./util/merge-refs";

/**
* TODO
*
* - array of `images` instead of `getFrameSrc`? not sure...
* - Animation inside this component — receive props for animation.
* - `preload` prop to preload images. undefined | boolean | string[]
* - Slot for `canvas`
* - user doesn't need to useRef or else... let's just do it all
* - we need to figure out image aspect ratio, and draw image quality
*/

/**
* ImageSequenceCanvas
*/

type SupportTable = { supportsWebp: boolean; supportsAvif: boolean };

export type ImageSequenceCanvasController = {
preload: (frameStart: number, frameEnd: number) => Promise<void>;
draw: (frame: number) => Promise<void>;
canvas: HTMLCanvasElement | null;
};

export type ImageSequenceCanvasProps = {
getFrameSrc: (frame: number, supportTable: SupportTable) => string;
controllerRef: React.ForwardedRef<{
preload: (frameStart: number, frameEnd: number) => Promise<void>;
draw: (frame: number) => Promise<void>;
canvas: HTMLCanvasElement | null;
}>;
controllerRef: React.ForwardedRef<ImageSequenceCanvasController>;
ref?: React.ForwardedRef<HTMLCanvasElement>;
/**
* Width and height define the drawing's quality
*/
width: number;
/**
* Width and height define the drawing's quality
*/
height: number;
// /**
// * Width and height define the drawing's quality
// */
// width: number;
// /**
// * Width and height define the drawing's quality
// */
// height: number;
} & JSX.IntrinsicElements["canvas"];

export const ImageSequenceCanvas = React.forwardRef<
HTMLCanvasElement,
ImageSequenceCanvasProps
>(({ controllerRef, getFrameSrc, ...rest }, ref) => {
const canvasRef = React.useRef<HTMLCanvasElement>(null);
const canvasRectRef = React.useRef<DOMRect | null>(null);
const supportTableRef = React.useRef<SupportTable>({
supportsAvif: false,
supportsWebp: false,
Expand Down Expand Up @@ -63,8 +77,19 @@ export const ImageSequenceCanvas = React.forwardRef<
const src = getFrameSrc(frame, supportTableRef.current);
const canvas = canvasRef.current;
const context = canvas?.getContext("2d");
if (!canvas || !context || !src) return;
if (!canvas || !context || !src || !canvasRectRef.current) return;
const img = await loadImage(src);

// Get the DPR and size of the canvas
const dpr = window.devicePixelRatio || 1;

// Set the "actual" size of the canvas
canvas.width = canvasRectRef.current.width * dpr;
canvas.height = canvasRectRef.current.height * dpr;

// Scale the context to ensure correct drawing operations
// context.scale(dpr, dpr);

// thanks https://stackoverflow.com/a/31910088
// @ts-ignore
context.mozImageSmoothingEnabled = false;
Expand All @@ -75,6 +100,35 @@ export const ImageSequenceCanvas = React.forwardRef<
context.imageSmoothingEnabled = false;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);

// const canvasWidth = canvas.width;
// const canvasHeight = canvas.height;
// const imgWidth = img.width;
// const imgHeight = img.height;

// const ratio = Math.min(
// canvasWidth / imgWidth,
// canvasHeight / imgHeight
// );

// const newWidth = imgWidth * ratio;
// const newHeight = imgHeight * ratio;

// const offsetX = (canvasWidth - newWidth) / 2;
// const offsetY = (canvasHeight - newHeight) / 2;

// context.clearRect(0, 0, canvas.width, canvas.height);
// context.drawImage(
// img,
// 0,
// 0,
// imgWidth,
// imgHeight,
// offsetX,
// offsetY,
// newWidth,
// newHeight
// );
},
get canvas() {
return canvasRef.current;
Expand All @@ -84,9 +138,49 @@ export const ImageSequenceCanvas = React.forwardRef<
[getFrameSrc]
);

return <canvas {...rest} ref={mergeRefs([canvasRef, ref])} />;
// get canvas rect into a ref, update with a resize observer
React.useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const resizeObserver = new ResizeObserver((entries) => {
const c = entries[0];
if (!c) return;
canvasRectRef.current = c.contentRect;
console.log("here.");
});
resizeObserver.observe(canvas);
return () => resizeObserver.disconnect();
}, []);

return (
<>
<canvas {...rest} ref={mergeRefs([canvasRef, ref])} />
{/* <Scrollytelling.Animation
tween={{
start: 0,
end: 100,
target: sequence,
to: {
frame: 202,
snap: "frame",
ease: "none",
onUpdate: () => {
console.log(sequence);
ref.current?.draw(sequence.frame);
},
},
}}
/> */}
</>
);
});

export const useImageSequence = (firstFrame = 0) => {
const controllerRef = React.useRef<ImageSequenceCanvasController>(null);
const sequence = { frame: firstFrame };
return { controllerRef, sequence };
};

ImageSequenceCanvas.displayName = "Scrollytelling.ImageSequenceCanvas";

// utils
Expand Down
2 changes: 1 addition & 1 deletion website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"eslint-config-custom": "^0.0.0",
"gsap": "^3.11.5",
"leva": "^0.9.34",
"next": "^13.3.0",
"next": "^13.5.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "^0.32.0",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/public/dance-sequence/dance-frame-173.png
Binary file added website/public/dance-sequence/dance-frame-174.png
Binary file added website/public/dance-sequence/dance-frame-175.png
Binary file added website/public/dance-sequence/dance-frame-176.png
Binary file added website/public/dance-sequence/dance-frame-177.png
Binary file added website/public/dance-sequence/dance-frame-179.png
Binary file added website/public/dance-sequence/dance-frame-180.png
Binary file added website/public/dance-sequence/dance-frame-181.png
Binary file added website/public/dance-sequence/dance-frame-182.png
Binary file added website/public/dance-sequence/dance-frame-183.png
Binary file added website/public/dance-sequence/dance-frame-184.png
Binary file added website/public/dance-sequence/dance-frame-185.png
Binary file added website/public/dance-sequence/dance-frame-186.png
Binary file added website/public/dance-sequence/dance-frame-187.png
Binary file added website/public/dance-sequence/dance-frame-190.png
Binary file added website/public/dance-sequence/dance-frame-191.png
Binary file added website/public/dance-sequence/dance-frame-192.png
Binary file added website/public/dance-sequence/dance-frame-193.png
Binary file added website/public/dance-sequence/dance-frame-195.png
Binary file added website/public/dance-sequence/dance-frame-196.png
Binary file added website/public/dance-sequence/dance-frame-197.png
Binary file added website/public/dance-sequence/dance-frame-201.png
Binary file added website/public/dance-sequence/dance-frame-202.png
2 changes: 2 additions & 0 deletions website/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { HorizontalMarquee } from "./sections/horizontal-marquee";
import { LastParallax } from "./sections/last-parallax";
import { LabIntro } from "./sections/lab-cylinder/intro";
import { LabCylinder } from "./sections/lab-cylinder";
import { ImageSequenceSection } from "./sections/image-sequence";

export default function HomePage() {
return (
<main>
<Hero />
<ImageSequenceSection />
<FallingCaps />
<HorizontalMarquee />
<LabIntro />
Expand Down
8 changes: 7 additions & 1 deletion website/src/app/sections/hero/hero.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
width: max-content;
}

p {
.cta {
font-size: tovw(24px, "desktop-large", 16px);
font-weight: 800;
line-height: 1.2;
Expand All @@ -34,6 +34,12 @@
@media screen and (max-width: 800px) {
display: none;
}

button {
display: flex;
align-items: center;
justify-content: center;
}
}
}

Expand Down
20 changes: 19 additions & 1 deletion website/src/app/sections/hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,25 @@ export const Hero = () => {
</clipPath>
</defs>
</svg>
<p>I got the whole band set up in the basement & we are jamming.</p>
<div className={s["cta"]}>
<button>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.49933 0.25C3.49635 0.25 0.25 3.49593 0.25 7.50024C0.25 10.703 2.32715 13.4206 5.2081 14.3797C5.57084 14.446 5.70302 14.2222 5.70302 14.0299C5.70302 13.8576 5.69679 13.4019 5.69323 12.797C3.67661 13.235 3.25112 11.825 3.25112 11.825C2.92132 10.9874 2.44599 10.7644 2.44599 10.7644C1.78773 10.3149 2.49584 10.3238 2.49584 10.3238C3.22353 10.375 3.60629 11.0711 3.60629 11.0711C4.25298 12.1788 5.30335 11.8588 5.71638 11.6732C5.78225 11.205 5.96962 10.8854 6.17658 10.7043C4.56675 10.5209 2.87415 9.89918 2.87415 7.12104C2.87415 6.32925 3.15677 5.68257 3.62053 5.17563C3.54576 4.99226 3.29697 4.25521 3.69174 3.25691C3.69174 3.25691 4.30015 3.06196 5.68522 3.99973C6.26337 3.83906 6.8838 3.75895 7.50022 3.75583C8.1162 3.75895 8.73619 3.83906 9.31523 3.99973C10.6994 3.06196 11.3069 3.25691 11.3069 3.25691C11.7026 4.25521 11.4538 4.99226 11.3795 5.17563C11.8441 5.68257 12.1245 6.32925 12.1245 7.12104C12.1245 9.9063 10.4292 10.5192 8.81452 10.6985C9.07444 10.9224 9.30633 11.3648 9.30633 12.0413C9.30633 13.0102 9.29742 13.7922 9.29742 14.0299C9.29742 14.2239 9.42828 14.4496 9.79591 14.3788C12.6746 13.4179 14.75 10.7025 14.75 7.50024C14.75 3.49593 11.5036 0.25 7.49933 0.25Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
<span>GitHub</span>
</button>
</div>
</header>

<section className={s["section"]}>
Expand Down
43 changes: 43 additions & 0 deletions website/src/app/sections/image-sequence/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";
import * as Scrollytelling from "@bsmnt/scrollytelling";

export const ImageSequenceSection = () => {
const { controllerRef, sequence } = Scrollytelling.useImageSequence(140);

return (
<Scrollytelling.Root
debug={{ label: "Image Sequence Canvas", markers: true }}
>
<Scrollytelling.Pin childHeight={"100vh"} pinSpacerHeight={"300vh"}>
<section>
<Scrollytelling.ImageSequenceCanvas
controllerRef={controllerRef}
getFrameSrc={(f) => `/dance-sequence/dance-frame-${f}.png`}
// width={500}
// height={500}
style={{
width: "70vw",
height: "100vh",
objectFit: "cover",
}}
/>
<Scrollytelling.Animation
tween={{
start: 0,
end: 100,
target: sequence,
to: {
frame: 202,
snap: "frame",
ease: "none",
onUpdate: () => {
controllerRef.current?.draw(sequence.frame);
},
},
}}
/>
</section>
</Scrollytelling.Pin>
</Scrollytelling.Root>
);
};
Loading