0

I've been working on this problem for a while now, but can't seem to find a way around it.

I am trying to build a horizontal scroll wheel module (made up of "layers" array) with a "selector" layer in the middle of the screen that selects the layer within said array that landed on it, displays said layer's name and the page that is associated with it. In other words, once "beige layer" lands on "selector", this.name is displayed below this.layer, "beige page".x=0

Right now the problem is that the wheel only moves onDrag, so you have to keep dragging it for it to move as opposed to onScroll. I've tried playing around with reading the x position of layers in the "layers" array relative to "selector" and fire off commands, and I also tried playing around with .parent properties for the pages, but it doesn't work the way it should.

Here's a framer link if that helps, http://share.framerjs.com/psbqx3dvqtz9/

Any help would be appreciated, guys.

Thanks in advance!

Alex

layerCount=8
circleCenterZ=0
circleCenterX= Screen.width / 2
circleRadius= 500
scrollSensitivity= 50
depthOfField= 25
divide= layerCount/Math.PI/1.6
allPosZ=[]
layers=[]
savX = 0
sX = 0
newCat=[]
colors=["green","red","blue","white","pink","purple","beige","orange","yellow","brown"]


select=new PageComponent
    x: 5
    y: 636
    backgroundColor: null
    borderWidth: 5
    clip:false
    scrollVertical:false

scroll = new ScrollComponent # invisible proxy ScrollComponent
    width: Screen.width, y:500
    scrollVertical: false
    height: 306

scroll.content.opacity = 0


colors.forEach (cat,i) ->
    posZ= allPosZ[i]= circleCenterZ+(circleRadius/2)*Math.cos(i/divide)
    posX= circleCenterX+(circleRadius/2)*Math.sin(i/divide)

    layer=layers[i]= new Layer
        width:109
        height:109
        parent:select.content
        y: select.height/5
        borderRadius: 100
        name: colors[i]
        midX: posX
        z: posZ

layers[0].onClick ->
    print this.name

maxDepth = Math.max.apply @, allPosZ
minDepth = Math.min.apply @, allPosZ


for layer,i in layers

    darken = Utils.modulate(layer.z,[maxDepth,minDepth],[0,1], true)
    layer.blur = Utils.modulate(layer.z,[maxDepth/3,minDepth],[0,depthOfField], true)


scroll.content.onDrag ->

    sX = (@.x + savX) / scrollSensitivity



    for layer,i in layers

        posZ= allPosZ[i]= circleCenterZ+(circleRadius/2)*Math.cos((i+sX)/divide)
        posX= circleCenterX+(circleRadius/2)*Math.sin((i+sX)/divide)

        layer.z = posZ
        layer.midX = posX
        darken = Utils.modulate(posZ,[maxDepth,minDepth],[0,1], true)
        layer.blur = Utils.modulate(posZ,[maxDepth/3,minDepth],[0,depthOfField], true)


scroll.content.onDragEnd ->
    savX = sX * scrollSensitivity
    @.x = 0


for i in [0...layerCount]
    category=newCat[i]=new Layer
        backgroundColor: colors[i]
        width: Screen.width
        x: Screen.width*i
        name: colors[i]+" "+"page"

1 Answers1

0

I think what you're trying to do can be achieved by using onMove instead of onDrag. This will fire during dragging and animations, so you get the velocity of the scrolling as well.

Because you're scrolling in a circle, the scrolling should be infinite. This can be achieved by setting the x on every move to modulo the width of the scroll component. An example of this can be found here.

To apply this to your code you need a couple of changes:

  • Add a layer to the content of your proxy scroll component with a large width to increase the content size
  • Set the starting scroll offset to midway through the content
  • use onMove instead of onDrag
  • Modify the @x in onMove like this: @x = start + @x % scroll.width
  • Remove the onDragEnd code

This results in the following code:

layerCount=8
circleCenterZ=0
circleCenterX= Screen.width / 2
circleRadius= 500
scrollSensitivity= 50
depthOfField= 25
divide= layerCount/Math.PI/1.6
allPosZ=[]
layers=[]
savX = 0
sX = 0
newCat=[]
colors=["green","red","blue","white","pink","purple","beige","orange","yellow","brown"]


select=new PageComponent
    x: 5
    y: 636
    backgroundColor: null
    borderWidth: 5
    clip:false
    scrollVertical:false

scroll = new ScrollComponent # invisible proxy ScrollComponent
    width: Screen.width, y:500
    scrollVertical: false
    height: 306

scroll.content.opacity = 0
count = 40
l = new Layer
    width: count * scroll.width
    height: scroll.content.height
    parent: scroll.content
start = -count/2 * scroll.width
scroll.content.x = start


colors.forEach (cat,i) ->
    posZ= allPosZ[i]= circleCenterZ+(circleRadius/2)*Math.cos(i/divide)
    posX= circleCenterX+(circleRadius/2)*Math.sin(i/divide)

    layer=layers[i]= new Layer
        width:109
        height:109
        parent:select.content
        y: select.height/5
        borderRadius: 100
        name: colors[i]
        midX: posX
        z: posZ

layers[0].onClick ->
    print this.name

maxDepth = Math.max.apply @, allPosZ
minDepth = Math.min.apply @, allPosZ


for layer,i in layers

    darken = Utils.modulate(layer.z,[maxDepth,minDepth],[0,1], true)
    layer.blur = Utils.modulate(layer.z,[maxDepth/3,minDepth],[0,depthOfField], true)


scroll.onMove ->

    @x = start + @x % scroll.width

    sX = @x / scrollSensitivity

    for layer,i in layers

        posZ= allPosZ[i]= circleCenterZ+(circleRadius/2)*Math.cos((i+sX)/divide)
        posX= circleCenterX+(circleRadius/2)*Math.sin((i+sX)/divide)

        layer.z = posZ
        layer.midX = posX
        darken = Utils.modulate(posZ,[maxDepth,minDepth],[0,1], true)
        layer.blur = Utils.modulate(posZ,[maxDepth/3,minDepth],[0,depthOfField], true)

for i in [0...layerCount]
    category=newCat[i]=new Layer
        backgroundColor: colors[i]
        width: Screen.width
        x: Screen.width*i
        name: colors[i]+" "+"page"

Working example is here: http://share.framerjs.com/qc7jdyfyw7f6/

Niels
  • 771
  • 5
  • 5