Skip to content

Commit 3604b21

Browse files
authored
Merge pull request #40 from zJaaal/dev
Dev
2 parents 866143e + 5cea029 commit 3604b21

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+628
-266
lines changed

README.md

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ React Scroll Utilities is a Lightweight library to track scroll events like, pro
88

99
[Want to see a demo?](https://react-scroll-utilities.netlify.app)
1010

11+
## Index
12+
13+
1. [Installation](#installation)
14+
2. [ScrollWatcher Component](#scrollwatcher-component)
15+
3. [useProximity Hook](#useproximity-hook)
16+
4. [useDynamicColor Hook](#usedynamiccolor-hook)
17+
5. [useLinearValue Hook](#uselinearvalue-hook)
18+
6. [useDirection Hook](#usedirection-hook)
19+
7. [Linear Values Options](#linear-values-options)
20+
8. [Circle Component](#circle-component)
21+
9. [Rectangle Component](#rectangle-component)
22+
23+
1124
## Installation
1225

1326
You will need React ++16.8 to make this library work, since it use hooks as it's main construction.
@@ -127,11 +140,7 @@ This hook returns an RGB color that changes with the scroll, using an startColor
127140

128141
This hook takes an object with 3 properties, "startColor" and "endColor" that are arrays of number with a length of 3. Each value in the array is a color representing RGB, so each value should be between 0 and 255. That means that each array should be like: [123, 2, 215] or [0, 0, 0] or [255, 255, 255 ]. The third property is "elementRef" that is an HTML Reference that you can get using the useRef hook.
129142

130-
Also it accepts an options object, to modify the behavior of the hook, options for now has just one property: anchor
131-
132-
anchor property is a string that can only be: "top", "middle" and "bottom". Its default value is "middle".
133-
134-
This represents which edge of the component will use the hook to calculate the current color. My recomendations are that you test it by yourself to see how it works. But I can tell you that if you have a component that is at the very top of your page, use anchor: "top" and if you have a component at the very bottom of your page, something like a footer, use anchor: "bottom".
143+
Also it accepts an options object. Refer to [Linear Values Options](#linear-values-options) for more information.
135144

136145
It returns and string as: ```"rgb(123, 0, 43)"```
137146

@@ -154,11 +163,6 @@ const DynamicBackground = ({
154163
startColor: [123, 0, 24], //The color will vary from here
155164
endColor: [45, 34, 12], // To here
156165
elementRef: elementRef, //Using the height and the position of this element
157-
158-
// Neither options or anchor are needed in this case because it will always have middle as default value, I just use it for example purposes
159-
options: {
160-
anchor: "middle" // Because this will cover all the app, since is a background
161-
}
162166
}
163167

164168
const colorWithExternalObject = useDynamicColor(colorObj);
@@ -185,11 +189,7 @@ This hook returns a value that changes on scroll, using an startValue and an end
185189

186190
This hook takes an object with 3 properties, "startValue" and "endValue" that are numbers. The third property is "elementRef" that is an HTML Reference that you can get using the useRef hook.
187191

188-
Also it accepts an options object, to modify the behavior of the hook, options for now has just one property: anchor
189-
190-
anchor property is a string that can only be: "top", "middle" and "bottom". Its default value is "middle".
191-
192-
This represents which edge of the component will use the hook to calculate the current color. My recomendations are that you test it by yourself to see how it works. But I can tell you that if you have a component that is at the very top of your page, use anchor: "top" and if you have a component at the very bottom of your page, something like a footer, use anchor: "bottom".
192+
Also it accepts an options object. Refer to [Linear Values Options](#linear-values-options) for more information.
193193

194194
It returns the current value as number.
195195

@@ -289,7 +289,52 @@ function Example() {
289289

290290
This lib provides an enum for TypeScript users, it just has four properties at the moment: Directions.up, Directions.down, Directions.right and Directions.left that returns the value of "UP", "DOWN" "RIGHT" and "LEFT", you can use it as helper for useDirection hook.
291291

292-
# Animations Components
292+
293+
## Linear Values Options
294+
295+
This options let you modify the behavior of the animations, is an object that useDynamicColor and useLinearValues use in their "options" property, it has 3 properties: "anchor", "delay" and "duration".
296+
297+
### Anchor property
298+
299+
It accepts 3 possible values as strings: "top", "middle" and "bottom". This refers to the edge of where the hook should make the calculations.
300+
301+
For example:
302+
303+
- top: Refers to the top edge of your component, the animation will last until the bottom of your component touches the top of the viewport, so this anchor is perfect for header components that are at the very top of your app. This anchor takes the component height as reference.
304+
305+
- middle: Refers to the exact middle of your component, the animation will last until the center of the component is out of the viewport, so this anchor is perfect for components that are floating near the center of some parent component. This anchor takes the viewport height as reference if the component height is less than viewport height.
306+
307+
- bottom: Refers to the bottom edge of your component, the animation will last until the bottom of your component aligns to the bottom of the viewport, so this anchor is perfect for footer compoennts that are at the very bottom of your app. This anchor takes the component height as reference.
308+
309+
### Delay property
310+
311+
It accepts a number, that should be between 0 and 100, it refers to percentage. If you pass values that are out of range it will be clamped to 0 or 100.
312+
313+
This means that, if you pass 50 the animation will delay to the 50% of the height of the component or viewport (depends on the anchor you use and the height of your component).
314+
315+
So, let's say we are using a component of 1000px height as reference and we set delay as 30% and anchor as "middle".
316+
317+
The animation won't start until the center of the screen (middle anchor) is at 300px (30% of 1000px) of the center of the component.
318+
319+
320+
### Duration property
321+
322+
It accepts a number, that should be between 0 and 100, it refers to percentage. If you pass values that are out of range it will be clamped to 0 or 100.
323+
324+
This means that, if you pass 50 the animation will last long to the 50% of the total distance it should execute.
325+
326+
You can use delay and duration at the same time, if you set delay to 50% and set the animation to 50%, it will start at the half of the component and will last half of the time it should last. That means, if you set a delay, duration will use the total distance between the delay and the end of the component as reference.
327+
328+
So, let's say we are using a component of 1000px, middle as anchor and we set duration and delay as 50.
329+
330+
The animation won't start until the center of the screen (middle anchor) is at the center of the component (500px). So the total distance from delay to the end of the component is 500px. We also setted a duration at half, so the animation should last as half of the total distance, at 250px of the end of the component the animation will finish.
331+
332+
### Recommendations
333+
334+
If you struggle trying to understand that. I mean it could be hard to understand with all those numbers and calculations.
335+
336+
I recommend to experiment with those values. Just go and mess around with it, maybe you'll understand it better if you see how it behaves.
337+
293338
294339
## Circle Component
295340

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-scroll-utilities",
33
"private": false,
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"license": "MIT",
66
"type": "module",
77
"main": "src/lib/index.ts",

src/TestEnvironment.tsx

Lines changed: 192 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,230 @@
11
import React, { useRef } from "react";
22
import { Circle, useDynamicColor, useLinearValue } from "./lib";
3+
import { LinearValueOptions } from "./lib/types";
34

45
const TestEnvironment = () => {
56
const ref = useRef(null);
7+
const delayRef1 = useRef(null);
8+
const delayRef2 = useRef(null);
9+
const delayRef3 = useRef(null);
10+
11+
const options: LinearValueOptions = {
12+
anchor: "middle",
13+
delay: 0,
14+
duration: 100,
15+
};
16+
17+
const optionsDelay1: LinearValueOptions = {
18+
anchor: "middle",
19+
delay: 0,
20+
duration: 50,
21+
};
22+
const optionsDelay2: LinearValueOptions = {
23+
anchor: "middle",
24+
delay: 0,
25+
duration: 75,
26+
};
27+
const optionsDelay3: LinearValueOptions = {
28+
anchor: "middle",
29+
delay: 0,
30+
duration: 100,
31+
};
32+
633
const color = useDynamicColor({
734
startColor: [67, 206, 162],
835
endColor: [24, 90, 157],
936
elementRef: ref,
37+
options,
1038
});
1139

1240
const height = useLinearValue({
13-
startValue: 100,
14-
endValue: 500,
41+
startValue: 10,
42+
endValue: 100,
1543
elementRef: ref,
44+
options,
1645
});
1746
const width = useLinearValue({
18-
startValue: 100,
19-
endValue: 500,
47+
startValue: 10,
48+
endValue: 100,
2049
elementRef: ref,
50+
options,
2151
});
2252
const deg = useLinearValue({
2353
startValue: 0,
2454
endValue: 90,
2555
elementRef: ref,
56+
options,
57+
});
58+
const delayColor1 = useDynamicColor({
59+
startColor: [67, 206, 162],
60+
endColor: [24, 90, 157],
61+
elementRef: delayRef1,
62+
options: optionsDelay1,
63+
});
64+
65+
const delayHeight1 = useLinearValue({
66+
startValue: 10,
67+
endValue: 100,
68+
elementRef: delayRef1,
69+
options: optionsDelay1,
70+
});
71+
const delayWidth1 = useLinearValue({
72+
startValue: 10,
73+
endValue: 100,
74+
elementRef: delayRef1,
75+
options: optionsDelay1,
76+
});
77+
const delayDeg1 = useLinearValue({
78+
startValue: 0,
79+
endValue: 90,
80+
elementRef: delayRef1,
81+
options: optionsDelay1,
82+
});
83+
const delayColor2 = useDynamicColor({
84+
startColor: [67, 206, 162],
85+
endColor: [24, 90, 157],
86+
elementRef: delayRef2,
87+
options: optionsDelay2,
88+
});
89+
90+
const delayHeight2 = useLinearValue({
91+
startValue: 10,
92+
endValue: 100,
93+
elementRef: delayRef2,
94+
options: optionsDelay2,
95+
});
96+
const delayWidth2 = useLinearValue({
97+
startValue: 10,
98+
endValue: 100,
99+
elementRef: delayRef2,
100+
options: optionsDelay2,
101+
});
102+
const delayDeg2 = useLinearValue({
103+
startValue: 0,
104+
endValue: 90,
105+
elementRef: delayRef2,
106+
options: optionsDelay2,
107+
});
108+
const delayColor3 = useDynamicColor({
109+
startColor: [67, 206, 162],
110+
endColor: [24, 90, 157],
111+
elementRef: delayRef3,
112+
options: optionsDelay3,
113+
});
114+
115+
const delayHeight3 = useLinearValue({
116+
startValue: 10,
117+
endValue: 100,
118+
elementRef: delayRef3,
119+
options: optionsDelay3,
120+
});
121+
const delayWidth3 = useLinearValue({
122+
startValue: 10,
123+
endValue: 100,
124+
elementRef: delayRef3,
125+
options: optionsDelay3,
126+
});
127+
const delayDeg3 = useLinearValue({
128+
startValue: 0,
129+
endValue: 90,
130+
elementRef: delayRef3,
131+
options: optionsDelay3,
26132
});
27133

28134
return (
29135
<div>
30136
<div
31137
style={{
32-
height: 4000,
138+
height: "4000px",
33139
display: "flex",
140+
flexDirection: "column",
34141
justifyContent: "center",
35142
alignItems: "center",
143+
gap: 20,
36144
}}
37145
>
38146
<div
147+
ref={ref}
39148
style={{
40-
height,
41-
width,
42-
backgroundColor: color,
43-
color: "black",
44-
transform: `rotate(${deg}deg)`,
45-
borderRadius: "10px",
149+
display: "flex",
150+
justifyContent: "center",
151+
alignItems: "center",
152+
gap: 20,
46153
}}
47-
ref={ref}
48-
></div>
49-
</div>
50-
<div style={{ height: 400 }}>
51-
<Circle radius="40vh" stroke={2}></Circle>
154+
>
155+
<div
156+
style={{
157+
height,
158+
width,
159+
backgroundColor: color,
160+
color: "black",
161+
transform: `rotate(${deg}deg)`,
162+
borderRadius: "10px",
163+
}}
164+
></div>
165+
<div
166+
style={{
167+
height,
168+
width,
169+
backgroundColor: color,
170+
color: "black",
171+
transform: `rotate(${deg}deg)`,
172+
borderRadius: "10px",
173+
}}
174+
></div>
175+
<div
176+
style={{
177+
height,
178+
width,
179+
backgroundColor: color,
180+
color: "black",
181+
transform: `rotate(${deg}deg)`,
182+
borderRadius: "10px",
183+
}}
184+
></div>
185+
</div>
186+
<div
187+
style={{
188+
display: "flex",
189+
justifyContent: "center",
190+
alignItems: "center",
191+
gap: 20,
192+
}}
193+
>
194+
<div
195+
style={{
196+
height: delayHeight1,
197+
width: delayWidth1,
198+
backgroundColor: delayColor1,
199+
color: "black",
200+
transform: `rotate(${delayDeg1}deg)`,
201+
borderRadius: "10px",
202+
}}
203+
ref={delayRef1}
204+
></div>
205+
<div
206+
style={{
207+
height: delayHeight2,
208+
width: delayWidth2,
209+
backgroundColor: delayColor2,
210+
color: "black",
211+
transform: `rotate(${delayDeg2}deg)`,
212+
borderRadius: "10px",
213+
}}
214+
ref={delayRef2}
215+
></div>
216+
<div
217+
style={{
218+
height: delayHeight3,
219+
width: delayWidth3,
220+
backgroundColor: delayColor3,
221+
color: "black",
222+
transform: `rotate(${delayDeg3}deg)`,
223+
borderRadius: "10px",
224+
}}
225+
ref={delayRef3}
226+
></div>
227+
</div>
52228
</div>
53229
</div>
54230
);

src/__test__/Circle.test.tsx renamed to src/__test__/components/Circle.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { cleanup, fireEvent, render } from "@testing-library/react";
22
import { afterEach, beforeAll, describe, it, expect } from "vitest";
3-
import { ScrollWatcher } from "../lib";
4-
import Circle from "../lib/components/circle/Circle";
5-
import getBoundingClientRectMock from "./mock/getBoundingClientRectMock";
6-
import matchMediaMock from "./mock/matchMediaMock";
3+
import { ScrollWatcher } from "../../lib";
4+
import Circle from "../../lib/components/circle/Circle";
5+
import getBoundingClientRectMock from "../mock/getBoundingClientRectMock";
6+
import matchMediaMock from "../mock/matchMediaMock";
77

88
describe("Circle Component", () => {
99
afterEach(cleanup);

0 commit comments

Comments
 (0)