This is a read-only archive of the Framer Community on Facebook.

What is Framer? Join the Community
Return to index
Johannes Eckert
Posted May 18 - Read on Facebook

I am trying one of the examples with dynamic state properties…

layer.states.add
__one:
____x: -> layerA.maxX
__two:
____x: -> layerB.maxX

seems to accept functions as properties, but I could not get this work with animationOptions (I created a looping animation with next() and I would like to change the animationOptions with each cycle)

layer.states.animationOptions =
__curve: "spring"
__curveOptions:
____tension: -> variableA
____friction: -> variableB
____velocity: -> variableC

does not throw an error, but the console shows that the state from where it originates is NaN:

Animation.start
____x: NaN -> 635

15 Comments

Johannes Eckert

it works with any non-function values, and I tested it with bezier curves/linear by changing time with a function, with the same NaN-result

Tisho Georgiev

IMO we should support functions as properties in all parts of the framework that could be reevaluated, not just the state definitions.

Koen Bok

Sorry I don't have an example yet. Summer just started in Adam. I like what Tisho proposes and will see if I can whip that up for animations.

Koen Bok

My midi controller is coming Monday :-)

Thomas Aylott

Easy, use a literal getter instead:

layer.states.add({
one: {
get x(){
return layerA.maxX
},
},
});

Or use valueOf:

layer.states.add({
one: {
x: { valueOf: function(){
return layerA.maxX
} },
},
});

I don't know how to write a literal getter in CoffeeScript (you probly can't)

Tisho Georgiev

Johannes, you try building from this branch: https://github.com/tisho/Framer/tree/tisho/function-properties. It supports passing in a function to animationOptions that accepts the previous and next states as arguments, which will let you do what you want (vary properties on each cycle):

layer.states.animationOptions = (stateA, stateB) ->
if stateA is 'default'
return { curve: 'linear' }
else
return { curve: 'spring(200,20,0)' }

I haven't really tested this extensively (although what tests we have *do* pass), so consider it WIP.

Koen Bok

Shouldn't we just make this into a function like:
layer.states.addAnimationOptions(stateA, stateB, options)

Tisho Georgiev

That could work, too, but it does sacrifice flexibility. If you have an addAnimationOptions function, you have to know what the options are ahead of time and you need to define them up front. You're also somewhat bound to a transition between just two states, which doesn't need to be the case (I could be interested in having a certain transition when a layer exits a certain state regardless of what the target state is). With a function that is always evaluated at state change, you can vary the options based on the state of the world at the time the state change occurred. Now whether we need this kind of flexibility is, of course, debatable, which is why I kind of want to gather a bunch of examples and then adjust accordingly.

Johannes Eckert

Thanks Tisho! The last things you said sound right for the thing demo I am working on (new animationOptions with each state change). I'm will work on it after breakfast and want to try exactly that!

Johannes Eckert

hm, I think I lost you there somewhere. I couldn't get it to work like you said. What I was originally trying to do is attached here.

I was able to change layer.states.animationOptions with the midi-change event, but it convolutes the code and I would like to write it right into the state properties, but that throws the original error.

in my case, the properties do not depend on the state, but on the current values of my midi object when the state is changing

Johannes Eckert

since I am running the looping state-change on my own with next() and the StateDidSwitch event, I am going to use the StateWillSwitch event to update the animationOptions — and it works for me!

Wouldn't that be a nice place to run a 'switch' function to have different animationOptions, Tisho Georgiev?

This is what I have right now and this is good-enough workaround for me, but maybe there's a way that doesn't involve the event?

Koen Bok

Ah, you seem to be smarter then us :-)

Koen Bok

Yeah I mean, it's actually a pretty good spot to do this I think. Pretty much where events were built for.

But maybe still a reason to go with Tishos implementation would be trying to allow all properties to be dynamic throughout the framework. I think that principle makes a lot of sense.

Johannes Eckert

sounds like a good principle! and it's so super handy in coffeescript

Tisho Georgiev

Johannes , sorry for the confusion, i didn't match your proposed syntax perfectly, although I was heading in that direction. With the way things are, you can make animationOptions a function that returns curve and curveOptions and it will be evaluated on every state switch. No need for the individual friction/tension/velocity to be functions, too. It's a little more general purpose, but I'm in favor of supporting both approaches since the general principle applies to both.

Read the entire post on Facebook