Skip to content

Commit fef4e53

Browse files
committed
use element.animate for horizontal
1 parent 21024fb commit fef4e53

File tree

6 files changed

+113
-19
lines changed

6 files changed

+113
-19
lines changed

.storybook/preview.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
Title,
55
Subtitle,
66
Description,
7-
Primary,
7+
Primary,
88
ArgTypes,
99
} from "@storybook/blocks";
1010

@@ -17,6 +17,7 @@ const preview: Preview = {
1717
date: /Date$/,
1818
},
1919
},
20+
layout: "fullscreen",
2021
docs: {
2122
page: () => (
2223
<>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-scrolly-telling",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"description": "Create scrolly-telling animations in React with ease.",
55
"type": "module",
66
"keywords": [

src/components/ScrollyHorizontalElement.tsx

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export interface ScrollyHorizontalElementProps {
1010
children: React.ReactNode;
1111
preChildren?: React.ReactNode;
1212
postChildren?: React.ReactNode;
13-
precision?: number;
1413

1514
style?: React.CSSProperties;
1615
}
@@ -51,20 +50,22 @@ const ScrollyHorizontalElement = forwardRef<
5150
children,
5251
preChildren,
5352
postChildren,
54-
precision,
5553
...rest
5654
} = props;
5755

5856
const containerRef = useRef<HTMLDivElement>(null);
5957
const contentRef = useRef<HTMLDivElement>(null);
6058
const scrollyValues = useScrollyHorizontalElementLayout(
6159
containerRef,
62-
contentRef,
63-
precision
60+
contentRef
6461
);
6562

6663
return (
67-
<div className="scrolly-horizontal-container" style={styles.container}>
64+
<div
65+
ref={containerRef}
66+
className="scrolly-horizontal-container"
67+
style={styles.container}
68+
>
6869
<div className="scrolly-horizontal-sticky" style={styles.sticky}>
6970
<ScrollyElementContext.Provider value={scrollyValues}>
7071
{preChildren}
@@ -88,13 +89,11 @@ export default ScrollyHorizontalElement;
8889

8990
function useScrollyHorizontalElementLayout(
9091
containerRef: React.RefObject<HTMLDivElement>,
91-
contentRef: React.RefObject<HTMLDivElement>,
92-
precision?: number
92+
contentRef: React.RefObject<HTMLDivElement>
9393
) {
94-
const scrollyValues = useScrolly(contentRef, {
95-
precision,
96-
startAtEntryRatio: 1,
97-
stopAtExitRatio: 0,
94+
const timeRef = useRef(0);
95+
const scrollyValues = useScrolly(containerRef, {
96+
precision: 3,
9897
});
9998
const { windowWidth, windowHeight, scrollRatio } = scrollyValues;
10099

@@ -111,10 +110,22 @@ function useScrollyHorizontalElementLayout(
111110
targetEnd: scrollDistance,
112111
}).toFixed(0);
113112

114-
contentRef.current?.style.setProperty(
115-
"transform",
116-
`translateX(-${translateValue}px)`
117-
);
113+
const frame = window.requestAnimationFrame((time) => {
114+
const delta = time - timeRef.current;
115+
timeRef.current = time;
116+
117+
contentRef.current?.animate(
118+
{ transform: `translateX(-${translateValue}px)` },
119+
{
120+
fill: "forwards",
121+
easing: "ease-in-out",
122+
duration: 100,
123+
playbackRate: 1 + delta / 100,
124+
}
125+
);
126+
});
127+
128+
return () => window.cancelAnimationFrame(frame);
118129
}, [windowHeight, windowWidth, scrollRatio, contentRef, containerRef]);
119130

120131
return scrollyValues;

src/element.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ export type ScrollyElementProps<T extends React.ElementType> = {
2020
* A component that can be used to create a scrolly-telling element.
2121
*/
2222
const ScrollyElement = forwardRef<HTMLDivElement, ScrollyElementProps<"div">>(
23-
(props, ref): JSX.Element | null => {
24-
if (!props.horizontal) {
23+
({ horizontal, ...props }, ref): JSX.Element | null => {
24+
if (!horizontal) {
2525
return <ScrollyVerticalElement {...props} ref={ref} />;
2626
}
2727

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
3+
import {
4+
scrollSpacerDecorator,
5+
scrollyContextDecorator,
6+
} from "./decorators.jsx";
7+
import ScrollyElement from "../element.jsx";
8+
9+
const component = ScrollyElement;
10+
type ComponentType = typeof component;
11+
12+
export default {
13+
title: "ScrollyElement",
14+
component,
15+
tags: ["autodocs"],
16+
decorators: [scrollyContextDecorator, scrollSpacerDecorator],
17+
parameters: {
18+
layout: "fullscreen",
19+
},
20+
} satisfies Meta<ComponentType>;
21+
22+
export const Horizontal: StoryObj<ComponentType> = {
23+
args: {
24+
horizontal: true,
25+
style: { gap: "1rem", padding: "1rem" },
26+
children: Array(5)
27+
.fill(null)
28+
.map((_, i) => {
29+
const key = `slide-${i}`;
30+
return <App index={i} key={key} />;
31+
}),
32+
},
33+
};
34+
35+
function App({ index }: { index: number }) {
36+
return (
37+
<div
38+
style={{
39+
minWidth: "80vw",
40+
height: "100%",
41+
backgroundColor: "lightcyan",
42+
border: "1px solid lightblue",
43+
borderRadius: "0.5rem",
44+
display: "flex",
45+
justifyContent: "center",
46+
alignItems: "center",
47+
color: "black",
48+
}}
49+
>
50+
This is slide {index + 1}.
51+
</div>
52+
);
53+
}

src/stories/decorators.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,32 @@ export const scrollyContextDecorator: Decorator<unknown> = (Story) => (
66
<Story />
77
</ScrollyProvider>
88
);
9+
10+
function ScrollSpacer(style: React.CSSProperties) {
11+
return (
12+
<div
13+
style={{
14+
height: "100vh",
15+
display: "flex",
16+
justifyContent: "center",
17+
alignItems: "center",
18+
background: "lightgray",
19+
color: "black",
20+
font: "2rem",
21+
...style,
22+
}}
23+
>
24+
Scroll to see the component
25+
</div>
26+
);
27+
}
28+
29+
export const scrollSpacerDecorator: Decorator<unknown> = (Story) => {
30+
return (
31+
<>
32+
<ScrollSpacer />
33+
<Story />
34+
<ScrollSpacer />
35+
</>
36+
);
37+
};

0 commit comments

Comments
 (0)