A module for Framer that lets you easily hook one property onto another via spring or gravity.
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.