Skip to content

Dynamics.applyPendulum()

Simulates a swinging pendulum using physics. The element swings from its CSS transform-origin with realistic momentum.


Basic Usage

The initialAngle property dictates the starting angle in degrees. The friction property applies air resistance, causing the pendulum to decay and naturally come to a rest over time.

Click to release the pendulum.
60 FPS
js
import { Dynamics } from 'animx/dynamics'

Dynamics.applyPendulum('.pendulum', {
  length: 150,       // Radius of the swing
  gravity: 980,      // Downward pull
  friction: 0.99,    // Air friction
  initialAngle: 60   // Release angle (degrees)
});

(Make sure your CSS sets transform-origin: top center; on the swinging element!)


Friction & Decay

The friction property controls how quickly the pendulum loses momentum. Lower friction values (e.g., 0.94) cause the element to snap back and forth rapidly before settling, while a value of 1.0 creates a frictionless pendulum that swings infinitely.

Click the background to ring the bell.
60 FPS
js
Dynamics.applyPendulum('.ui-bell', {
  length: 30, // Short swing radius
  gravity: 1200, // Fast snap
  friction: 0.94, // Settles somewhat quickly
  initialAngle: 45 
});

Length & Momentum

The length property dictates the swing radius. Longer lengths result in slower, wider arcs. Adjusting the length and utilizing higher friction values (e.g., 0.98) simulates heavier, larger objects with sustained momentum.

Click the background to bump the sign.
OPEN
60 FPS
js
Dynamics.applyPendulum('.ui-sign', {
  length: 60, // Distance from pivot to center of sign
  gravity: 980,
  friction: 0.98,
  initialAngle: 25 // A gentle bump
});

Transform Origin

The CSS transform-origin property dictates the pivot point of the pendulum swing. By default, browsers rotate elements around their exact center. Setting transform-origin: top center; ensures the element swings from its top edge.

Change the transform-origin to see how it affects the pivot point!
Pivot Me!
60 FPS

Callbacks

The onUpdate and onComplete callbacks allow synchronization of external UI elements, audio, or game logic with the physical state of the pendulum.

The following demo utilizes these callbacks to drive a digital telemetry readout, exposing the live angle and angular velocity.

Notice how the telemetry updates during the swing and fires onComplete when it stops. Use the replay button to restart.
STATUSSWINGING
Angle--
Velocity--
60 FPS

NOTE

Understanding Rotation Velocity Because web browsers calculate the Y-axis upside down (where Y=0 is the top of the screen), CSS rotation physics behave counter-intuitively:

  • A positive rotation angle pushes a downward-hanging element to the Left.
  • Because it sits on the Left, swinging back to the Right causes the rotation angle to decrease.
  • A decreasing angle means the physics engine must output a negative angularVelocity. To make the readout panel in the demo easier to read, we negate the values so that moving right displays as a positive speed!

Properties & Methods

OptionTypeDefaultDescription
lengthnumber100The distance in pixels from the pivot point (transform-origin) to the center of the element. Longer lengths result in slower swings.
gravitynumber980The downward pulling force. Higher values make the pendulum swing faster.
frictionnumber0.98Air resistance applied every frame. 1.0 means no friction (infinite swing). Lower values slow the pendulum down faster.
initialAnglenumber0The starting angle in degrees before the pendulum is released. 0 means it is hanging straight down.
onUpdatefunctionundefinedA callback that fires every frame while the pendulum is swinging. Receives an object containing the live { rotation, angularVelocity }.
onCompletefunctionundefinedA callback that fires once the pendulum comes to a complete rest (when friction causes it to fully stop).

Return Instance

MethodDescription
kill()Terminates the physics simulation loop.