The Hook module expands Framer's Layer prototype, and lets you make any numeric Layer property follow another property - either its own or another object's - via a spring or gravity attraction.
Enough chat. Examples:
Example 2: Modulation from one property type to another
The original use case was to layer a spring animation on top of an eased animation to give more control over the timing and feel of a transition, as seen in Example 1. You do not need two layers to achieve this though, as shown in the first code snippet below.
I'm not a developer nor a mathematician, so much of this is improvised, particularly the physics. Please do let me know, or create a pull request, if you have any suggestions for improvements.
For a more detailed documentation, check the comments at the top of Hook.coffee.
myLayer = new Layer
# Make our own custom property for the x property to follow
myLayer.easedX = 0
# Hook x to easedX via a spring
myLayer.hook
property: "x"
targetProperty: "easedX"
type: "spring(150, 15)"
# Animate easedX
myLayer.animate
properties:
easedX: 200
time: 0.15
curve: "cubic-bezier(0.2, 0, 0.4, 1)"
NOTE: To attach both the x and y position, use "pos", "midPos" or "maxPos" as the property/targetProperty.
target = new Layer
hooked = new Layer
hooked.hook
property: "scale"
to: target
type: "spring(150, 15)"
The "hooked" layer's scale will now continuously follow the target layer's scale with a spring animation.
The modulator function allows you to do anything you want with the target property's value before it is applied. As a very basic example, let's say you want to convert one layer's y position into a corresponding scale value for another layer:
target = new Layer
hooked = new Layer
hooked.hook
property: "scale"
to: target
targetProperty: "y"
type: "spring(200,20)"
modulator: (input) -> Utils.modulate(input, [0, 400], [0.5, 1])
A more thorough documentation is included in the comments at the top of Hook.coffee.