Skip to content

Instantly share code, notes, and snippets.

@gtwalford
Created October 20, 2016 16:35
Show Gist options
  • Save gtwalford/df5d6078f332bc67d07d072fd36331ab to your computer and use it in GitHub Desktop.
Save gtwalford/df5d6078f332bc67d07d072fd36331ab to your computer and use it in GitHub Desktop.
import React, { PropTypes } from 'react'
import { isBrowser } from 'environment'
import { partial as _partial } from 'lodash'
import { VelocityComponent } from 'velocity-react'
if (isBrowser()) {
require('./_ScrollTo.scss')
}
function onRefAnimationComponent (componentInstance, component) {
componentInstance._animationComponent = component
}
function finishAnimation (componentInstance) {
// Only stop the animation if we have a component and an animation is in progress.
if (componentInstance._scrollAnimating && componentInstance._animationComponent) {
onAnimationComplete(componentInstance)
componentInstance._animationComponent._finishAnimation()
}
}
function onAnimationBegin (componentInstance) {
// Only add listeners once
if (componentInstance._scrollAnimating) {
return
}
componentInstance._scrollAnimating = true
componentInstance._onWindowClick = _partial(finishAnimation, componentInstance)
componentInstance._onWindowWheel = _partial(finishAnimation, componentInstance)
if (isBrowser()) {
window.addEventListener('click', componentInstance._onWindowClick)
window.addEventListener('wheel', componentInstance._onWindowWheel)
}
}
function onAnimationComplete (componentInstance) {
componentInstance._scrollAnimating = false
if (isBrowser() && componentInstance._onWindowClick) {
window.removeEventListener('click', componentInstance._onWindowClick)
}
if (isBrowser() && componentInstance._onWindowWheel) {
window.removeEventListener('wheel', componentInstance._onWindowWheel)
}
if (typeof componentInstance.props.finish === 'function') {
componentInstance.props.finish()
}
}
class ScrollTo extends React.Component {
runAnimation (options) {
if (isBrowser() && this._animationComponent) {
this._animationComponent.runAnimation(options)
}
}
render () {
const props = this.props
return (
<VelocityComponent
ref={ _partial(onRefAnimationComponent, this) }
begin={ _partial(onAnimationBegin, this) }
complete={ _partial(onAnimationComplete, this) }
animation={ props.disabled ? null : 'scroll' }
runOnMount={ props.runOnMount }
duration={ props.duration }
offset={ props.offset }
delay={ props.delay }
easing={ props.easing }>
<div className='scroll-to' aria-hidden='true' />
</VelocityComponent>
)
}
}
ScrollTo.propTypes = {
disabled: PropTypes.bool,
runOnMount: PropTypes.bool,
duration: PropTypes.number.isRequired,
offset: PropTypes.number.isRequired,
delay: PropTypes.number,
easing: PropTypes.string,
finish: PropTypes.func
}
export default ScrollTo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment