This repository was archived by the owner on Jul 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
58 lines (43 loc) · 1.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import React from "react";
function syncScroll(target, others, TopLeft, WidthHeight) {
const percentage =
target[`scroll${TopLeft}`] /
(target[`scroll${WidthHeight}`] - target[`offset${WidthHeight}`]);
window.requestAnimationFrame(() => {
others.forEach(el => {
el[`scroll${TopLeft}`] = Math.round(
percentage * (el[`scroll${WidthHeight}`] - el[`offset${WidthHeight}`])
);
});
});
}
function syncVerticalScroll(target, others) {
syncScroll(target, others, "Top", "Height");
}
function syncHorizontalScroll(target, others) {
syncScroll(target, others, "Left", "Width");
}
function useSyncScroll({ vertical, horizontal }) {
const refsRef = React.useRef([]);
const locksRef = React.useRef(0);
React.useEffect(() => {
if (refsRef.current.length < 2) return;
function handleScroll({ target }) {
if (locksRef.current > 0) {
locksRef.current -= 1; // Release lock by 1
return;
}
locksRef.current = refsRef.current.length - 1; // Acquire lock
const others = refsRef.current.filter(ref => ref !== target);
if (vertical) syncVerticalScroll(target, others);
if (horizontal) syncHorizontalScroll(target, others);
}
const elements = refsRef.current;
elements.forEach(el => el.addEventListener("scroll", handleScroll));
return () => {
elements.forEach(el => el.removeEventListener("scroll", handleScroll));
};
}, [refsRef, vertical, horizontal, locksRef]);
return (ref) => refsRef.current.push(ref);
}
export default useSyncScroll;