Skip to content

Instantly share code, notes, and snippets.

@Retozi
Created May 22, 2014 14:08
Show Gist options
  • Save Retozi/f4ffa5b1be8d31d3a633 to your computer and use it in GitHub Desktop.
Save Retozi/f4ffa5b1be8d31d3a633 to your computer and use it in GitHub Desktop.
react slider
Slider = React.createClass({
getInitialState: ->
{xStart: null, xEnd: null, dragPos: null}
getXs: ->
node = @refs.slider.getDOMNode()
if node?
rect = node.getBoundingClientRect()
@setState({xStart: rect.left, xEnd: rect.right})
# get the position every time the component recieves props, in case
# the visibility changes
componentWillReceiveProps: -> @getXs()
jumpSize: ->
return (@state.xEnd - @state.xStart) / (@props.range.length - 1)
getValueGivenPixel: (x) ->
if not @state.xStart?
return null
distanceInJumps = (x - @state.xStart) / @jumpSize()
potentialRangeIndex = Math.round(distanceInJumps)
if potentialRangeIndex <= 0
return @props.range[0]
if potentialRangeIndex >= @props.range.length
return @props.range[@props.range.length - 1]
else
return @props.range[potentialRangeIndex]
getSliderPosition: ->
if not @state.xStart?
return 0
if @state.dragPos?
return @state.dragPos - @state.xStart
indexOfValue = @props.range.indexOf(@props.position)
if not indexOfValue?
throw Error('value not in Range of Slider')
return indexOfValue * @jumpSize()
setDragPos: (x) ->
if x?
@setState({dragPos: Math.min(Math.max(x, @state.xStart), @state.xEnd)})
else
@setState({dragPos: null})
drag: (e) ->
e.preventDefault()
xPosition = e.clientX ? e.touches[0].clientX
if @state.dragPos? and Math.abs(xPosition - @state.dragPos) > 1
@setDragPos(xPosition)
startDragging: (e) ->
e.preventDefault()
@setDragPos(e.clientX ? e.touches[0].clientX)
stopDragging: (e) ->
e.preventDefault()
if @state.dragPos?
@props.setPosition(@getValueGivenPixel(@state.dragPos))
@setDragPos(null)
makePositionStyle: ->
return {left: @getSliderPosition().toString() + 'px'}
makeCaption: ->
if @state.dragPos?
return @props.makeCaption(@getValueGivenPixel(@state.dragPos))
else
return @props.makeCaption(@props.position)
render: ->
R.div {
className: 'sb-level2-row-variable',
onMouseDown: @startDragging
onMouseUp: @stopDragging
onMouseMove: @drag
onMouseLeave: @stopDragging
onTouchStart: @startDragging
onTouchMove: @drag
onTouchEnd: @stopDragging
},
R.div {className: 'year-month-slider'},
R.div {className: 'slider-title'},
@props.header
R.div {className: 'slider-element'},
R.span {className: 'slider-position-caption', style: @makePositionStyle()},
@makeCaption()
R.div {className: 'slider-line', ref: 'slider'}
R.div {className: 'slider-button', style: @makePositionStyle()}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment