Skip to content

Commit

Permalink
✨ finished up scroll speed feature
Browse files Browse the repository at this point in the history
  • Loading branch information
nickmcmillan committed Mar 7, 2019
1 parent c5f405e commit 27cdbca
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ yarn-debug.log*
yarn-error.log*

imgs
2017
2017
_export
8 changes: 5 additions & 3 deletions src/components/Tile/Tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const Tile = React.memo(function Tile({

return (
<animated.button
// id={item.id.replace('/', '-')} // replace slashes just in case, because we use the id as an anchor
className={`${styles.pigBtn}${isExpanded ? ` ${styles.pigBtnActive}` : ''}`}
onClick={() => handleClick(item)}
style={{
Expand All @@ -49,14 +48,16 @@ const Tile = React.memo(function Tile({
transform: transform.interpolate(t => t)
}}
>
{(scrollSpeed === 0 || scrollSpeed === 1) &&
{scrollSpeed === 'medium' &&
// LQIP
<img
className={`${styles.pigImg} ${styles.pigThumbnail}${isFullSizeLoaded ? ` ${styles.pigThumbnailLoaded}` : ''}`}
src={getUrl(item.url, settings.thumbnailSize)}
alt=""
/>
}
{(scrollSpeed === 0 || scrollSpeed === 1) &&
{(scrollSpeed === 'slow' || scrollSpeed === 'medium') &&
// grid image
<img
className={`${styles.pigImg} ${styles.pigFull}${isFullSizeLoaded ? ` ${styles.pigFullLoaded}` : ''}`}
src={getUrl(item.url, getImageHeight(containerWidth))}
Expand All @@ -66,6 +67,7 @@ const Tile = React.memo(function Tile({
}

{isExpanded && (
// full size expanded image
<img
className={styles.pigImg}
src={getUrl(item.url, settings.expandedSize)}
Expand Down
22 changes: 7 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default class Pig extends React.Component {

this.state = {
renderedItems: [],
scrollSpeed: 0,
scrollSpeed: 'slow',
activeTileUrl: null
}

Expand Down Expand Up @@ -95,26 +95,18 @@ export default class Pig extends React.Component {
}

onScroll = () => {
// Compute the scroll direction using the latestYOffset and the previousYOffset
this.previousYOffset = this.latestYOffset || window.pageYOffset
this.latestYOffset = window.pageYOffset
this.scrollDirection = (this.latestYOffset > this.previousYOffset) ? 'down' : 'up'

window.requestAnimationFrame(() => {
this.setRenderedItems(this.imageData)
const scrollSpeed = getScrollSpeed(this.latestYOffset, this.scrollThrottleMs)
if (scrollSpeed < 800) {
this.setState({ scrollSpeed: 0 })
} else if (scrollSpeed < 2000) {
this.setState({ scrollSpeed: 1 })
} else {
this.setState({ scrollSpeed: 2 })
}
console.log(this.state.scrollSpeed)


// slow < 800
// too fast > 1500

// measure users scrolling speed and set it to state, used for conditional tile rendering
const scrollSpeed = getScrollSpeed(this.latestYOffset, this.scrollThrottleMs, scrollSpeed => {
this.setState({ scrollSpeed }) // scroll idle callback
})
this.setState({ scrollSpeed })

// dismiss any active Tile
if (this.state.activeTileUrl) this.setState({ activeTileUrl: null })
Expand Down
34 changes: 22 additions & 12 deletions src/utils/getScrollSpeed.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
// https://stackoverflow.com/a/22599173/2255980
let scrollSpeed = ''
let lastPos = 0
let newPos = 0
let delta = 0
let timer = null
let timeout = null

function clear() {
lastPos = 0
}

// TODO: need to indicate when scrolling has stopped

export default function (latestYOffset, scrollThrottleMs) {
export default function (latestYOffset, scrollThrottleMs, idleCallback) {
newPos = latestYOffset

if (lastPos !== 0) delta = newPos - lastPos
if (lastPos !== 0) delta = Math.abs(newPos - lastPos)

lastPos = newPos
timer && clearTimeout(timer)
timer = setTimeout(clear, scrollThrottleMs * 2.5)
return Math.abs(delta)

if (delta < 1000) {
scrollSpeed = 'slow'
} else if (delta < 3000) {
scrollSpeed = 'medium'
} else {
scrollSpeed = 'fast' // only really happens when user grabs the scrollbar
}

// kind of like a reversed debounce,
// if this function hasn't been called in a little while, fire the idleCallback function
clearTimeout(timeout)
timeout = setTimeout(() => {
timeout = null
idleCallback('slow')
}, scrollThrottleMs * 2)

return scrollSpeed
}

0 comments on commit 27cdbca

Please sign in to comment.