Skip to content

Commit

Permalink
feat: 🎸 integrate dynamic scroll POC
Browse files Browse the repository at this point in the history
  • Loading branch information
devonChurch committed Jan 19, 2020
1 parent 12a6f1e commit 7f39bf5
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { createGlobalStyle } from "styled-components";
import { Swatches, UserSwatch, AppendSwatch } from "./Swatch";
import { Compositions, UserComposition, AppendComposition } from "./Composition";
import { Header } from "./Header";
import { Scroll } from "./Scroll";
import {
SWATCH_WIDTH,
BLACK,
Expand Down Expand Up @@ -324,6 +325,7 @@ const App = () => {
<>
<GlobalStyle />
<Header {...{ isDeleting, handleDeleteToggle }} />
{isUserDragging && <Scroll />}
<TransitionGroup component={Swatches}>
{[...swatches].map(([swatchId, hex], swatchIndex) => (
<CSSTransition key={swatchId} timeout={SPEED_700} classNames="swatch">
Expand Down
72 changes: 72 additions & 0 deletions src/Scroll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { useEffect, useRef } from "react";
import throttle from "lodash.throttle";

export const Scroll = () => {
const offset = useRef();
const throttledScroll = useRef();

useEffect(() => {
const setScroll = () => {
const { innerHeight, scrollY } = window;
const nextScroll = scrollY + offset.current;
const isTooHigh = nextScroll < 0;
const isTooLow = nextScroll > document.body.clientHeight - innerHeight;
const shouldScroll = !isTooHigh && !isTooLow;

if (shouldScroll) {
window.scroll(0, nextScroll);
throttledScroll.current = requestAnimationFrame(setScroll);
} else {
throttledScroll.current = null;
}
};

const checkScenario = event => {
const viewPortHeight = window.innerHeight;
const viewPortQuarter = viewPortHeight / 4;
const pointerPosition = event.clientY;
const isOverTopQuarter = pointerPosition < viewPortQuarter;
const isOverBottomQuarter = pointerPosition > viewPortQuarter * 3;
const maxScrollOffset = viewPortQuarter;
const shouldUpdateScroll =
!throttledScroll.current && (isOverTopQuarter || isOverBottomQuarter);
const shouldStopScroll =
throttledScroll.current && !(isOverTopQuarter || isOverBottomQuarter);

if (isOverTopQuarter) {
const percentageOffset = (viewPortQuarter - pointerPosition) / viewPortQuarter;
const pixelOffset = maxScrollOffset * percentageOffset;
offset.current = -pixelOffset;
}

if (isOverBottomQuarter) {
const percentageOffset = (pointerPosition - viewPortQuarter * 3) / viewPortQuarter;
const pixelOffset = maxScrollOffset * percentageOffset;
offset.current = pixelOffset;
}

if (shouldUpdateScroll) {
throttledScroll.current = requestAnimationFrame(setScroll);
}

if (shouldStopScroll) {
throttledScroll.current = null;
}
};

const handlePointerMove = event => {
checkScenario(event);
};

const throttledDrag = throttle(handlePointerMove, 250, { trailing: false });

window.addEventListener("dragover", throttledDrag);

return function cleanUp() {
throttledScroll.current = null;
window.removeEventListener("dragover", handlePointerMove);
};
}, []);

return null;
};

0 comments on commit 7f39bf5

Please sign in to comment.