Search code examples
framerjs

How do I create animations for layers created in a for loop


Consider the two snippets for Collection Grid and Layer with Click Animation. The following will only add an animation listener to the last grid item (the layer at the 3:3 position):

rows = 3
cols = 3

gutter = 16
width  = 96
height = 96

for rowIndex in [0..rows-1]
    for colIndex in [0..cols-1]

        cellLayer = new Layer
            width:  width
            height: height
            x: colIndex * (width + gutter)
            y: rowIndex * (height + gutter)

        Utils.labelLayer cellLayer, "#{rowIndex}:#{colIndex}"

        cellLayer.on Events.Click, ->
            cellLayer.animate
                properties:
                    scale: 1.4
                curve: "spring"

How can I individually name layers in a for loop to apply animations?

Something like cellLayer[rowIndex][colIndex] = new Layer would be ideal, but doesn't work.


Solution

  • tl;dr

    It could be solved simply using do keyword like this:

    do (cellLayer) -> 
      cellLayer.on Events.Click, ->
        cellLayer.animate
          properties: scale: 1.4
          curve: "spring"
    

    When using a JavaScript loop to generate functions, it's common to insert a closure wrapper in order to ensure that loop variables are closed over, and all the generated functions don't just share the final values. CoffeeScript provides the "do" keyword, which immediately invokes a passed function, forwarding any arguments.

    technically you must make each scope of cellLayer because cellLayer is scoped in loop. In CoffeeScript, a syntax sugar is provided do keyword. Just put do in code then make scopes automatically using IIFE. If you know something about JavaScript, transpiled code could help you.