Spring animation
Bind a spring directly to anchoredPosition, color, sizeDelta or other native settings of its matching type. Put spring creation in an owned renderer and update its target source. Runnable counter. Motion example.
Follow the target and animated value
In the example below, onRight selects a target of -180 or 180 on the horizontal axis. target derives that position, and position follows it through the spring. Clicking Move right or Move left changes the target immediately; the image's position approaches it over time without rebuilding the image.
The example uses a period of 0.45 and a damping ratio of 0.75. Bind position directly to anchoredPosition so the native image follows the spring. Replacing that binding with a literal target moves immediately, while capturing the spring's value into a literal only uses one instant.
For an application's reduced-motion setting, P.ReducedMotion.Value = true snaps spring targets. Disposing the owning scope stops its animation observers. Use the spring reference when animating a custom value type or advancing springs manually. The browser preview demonstrates the motion model; the downloaded files build the native Unity interface.
Spring motion
Target: left
Try the controls. This browser demo models the example’s behavior; Unity renders the native UI. Download matching Unity source ↗
Run the example
Import both files into Assets/Examples. Keep one App.cs entry. These use the native API; the browser preview models the state changes above.
Download PineSpring.cs · Download App.cs
using Pine;
using UnityEngine;
namespace PineDocs.Examples
{
public static class PineSpring
{
public static View Create()
{
var onRight = P.Source(false);
var target = P.Derive(() => new Vector2(onRight.Value ? 180 : -180, 0));
var position = P.Spring(() => target.Value, period: .45, dampingRatio: .75);
return P.Vertical(
spacing: 8,
childControlWidth: true,
childControlHeight: true,
childForceExpandHeight: false,
sizeDelta: new Vector2(520, 240)
)
.With(
P.Text("Spring motion").With(P.LayoutElement(preferredHeight: 40)),
P.Frame()
.With(
P.LayoutElement(preferredHeight: 80),
P.Image(
color: Color.green,
anchoredPosition: position,
sizeDelta: new Vector2(24, 24)
)
),
P.Text(() => $"Target: {(onRight.Value ? "right" : "left")}")
.With(P.LayoutElement(preferredHeight: 40)),
P.Button(
() => onRight.Value ? "Move left" : "Move right",
onClick: () => onRight.Value = !onRight.Value
)
.With(P.LayoutElement(preferredHeight: 40))
);
}
}
}
