Skip to content

Instantly share code, notes, and snippets.

@inscapist
Last active August 29, 2015 14:05
Show Gist options
  • Save inscapist/b1201c270dc0ccf5d988 to your computer and use it in GitHub Desktop.
Save inscapist/b1201c270dc0ccf5d988 to your computer and use it in GitHub Desktop.
Famous EasyScrollView (pagination, supports X/Y direction, and ScrollBar!)
Famous.EasyScrollview = class EasyScrollview extends Famous.CView
@DEFAULT_OPTIONS:
containerSize: [300,300]
itemSize: [300,300]
direction: 0
paginate: true
scrollBarThickness: 26
@DIRECTION_X: 0
@DIRECTION_Y: 1
constructor: (options)->
super options
@container = new Famous.CContainer
size: [@options.containerSize[0], @options.containerSize[1]]
properties:
overflow: 'hidden'
init.call(this)
@addToCenter @container
init = ->
@halfX = (@options.itemSize[0]/2)
@halfY = (@options.itemSize[1]/2)
registerSyncs.call(this)
@itemContainer = new Famous.SequentialLayout
direction: @options.direction
@content.add @itemContainer
@container.add(@positionModifier).add @content
registerSyncs = ->
@position = new Famous.Transitionable([0, 0])
@sync = new Famous.GenericSync
mouse: {}
touch: {}
scroll:
scale: .3
@positionModifier = new Famous.Modifier
transform: =>
currentPosition = @position.get()
Famous.Transform.translate currentPosition[0], currentPosition[1], 0
@scrollbarPositionModifier = new Famous.Modifier
transform: =>
currentPosition = @position.get()
if @options.direction == 0
scrollPos = currentPosition[0] / @maxScroll
barPosition = -scrollPos * (@windowSize - @scrollbarSize)
Famous.Transform.translate barPosition, 0, 0
else
scrollPos = currentPosition[1] / @maxScroll
barPosition = -scrollPos * (@windowSize - @scrollbarSize)
Famous.Transform.translate 0, barPosition, 0
@content = new Famous.CContainer()
@content.pipe @sync
@sync.on 'update', (data) =>
currentPosition = @position.get()
newPosX = currentPosition[0] + data.delta[0]
newPosY = currentPosition[1] + data.delta[1]
newPosX = Math.max(@minPosX, newPosX)
newPosX = Math.min(@maxPosX, newPosX)
newPosY = Math.max(@minPosY, newPosY)
newPosY = Math.min(@maxPosY, newPosY)
@position.set [
newPosX
newPosY
]
@sync.on 'end', (data) =>
currentPosition = @position.get()
newPosX = currentPosition[0] + data.delta[0]
newPosY = currentPosition[1] + data.delta[1]
if @options.paginate
diffX = newPosX % @options.itemSize[0]
diffY = newPosY % @options.itemSize[1]
if diffX < -@halfX
newPosX += (-@options.itemSize[0] - diffX)
else
newPosX -= diffX
if diffY < -@halfY
newPosY += (-@options.itemSize[1] - diffY)
else
newPosY -= diffY
@position.set [newPosX,newPosY],
method: 'spring'
period: 150
addItems: (@items) ->
@itemContainer.sequenceFrom @items
@maxPosX = 0
@maxPosY = 0
if @options.direction == 0
@minPosX = @options.containerSize[0] - (@items.length * @options.itemSize[0])
@minPosY = 0
else
@minPosX = 0
@minPosY = @options.containerSize[1] - (@items.length * @options.itemSize[1])
createScrollbar.call this
createScrollbar = ->
@windowSize = @options.containerSize[@options.direction]
@contentSize = @items.length * @options.itemSize[@options.direction]
windowToContentRatio = (@windowSize / @contentSize)
@scrollbarSize = @windowSize * windowToContentRatio
@maxScroll = @contentSize - @windowSize
radius = @options.scrollBarThickness * 0.5
radius = "#{radius}px"
if @options.direction == 0
@scrollbar = new Famous.Surface
size: [@scrollbarSize, @options.scrollBarThickness]
properties:
backgroundColor: '#000'
borderTopLeftRadius: radius
borderTopRightRadius: radius
borderBottomLeftRadius: radius
borderBottomRightRadius: radius
pointerEvents: 'auto'
@scrollBarContainer = new Famous.CContainer
size: [@windowSize, @options.scrollBarThickness]
else
@scrollbar = new Famous.Surface
size: [@options.scrollBarThickness, @scrollbarSize]
properties:
backgroundColor: '#000'
borderTopLeftRadius: radius
borderTopRightRadius: radius
borderBottomLeftRadius: radius
borderBottomRightRadius: radius
pointerEvents: 'auto'
@scrollBarContainer = new Famous.CContainer
size: [@options.scrollBarThickness, @windowSize]
scrollBarContainerBackground = new Famous.Surface
properties:
backgroundColor: '#000'
borderTopLeftRadius: radius
borderTopRightRadius: radius
borderBottomLeftRadius: radius
borderBottomRightRadius: radius
pointerEvents: 'none'
@scrollBarContainer.add(Famous.opaqueBy(0.1)).add scrollBarContainerBackground
@scrollBarContainer.add(Famous.opaqueBy(0.1)).add(@scrollbarPositionModifier).add @scrollbar
getScrollbar: ->
@scrollbar
getScrollbarContainer: ->
@scrollBarContainer
@pictures = []
i = 0
while i < 5
picture = new Fam.Surface
content: i
size: [300, 300]
properties:
backgroundColor: 'hsl('+ (i * 360 / 20) + ', 100%,50%)'
picture.index = i
picture.clickHandler = ->
alert "picture #{@index} clicked!"
picture.on 'click', picture.clickHandler.bind(picture)
@pictures.push picture
i++
el = new Fam.EasyScrollview()
el.addItems @pictures
@container.addToTop el.getScrollbarContainer()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment