Gravity.js


Documentation v1.2.0


What is Gravity.js?

Gravity.js is a lightweight physics engine that renders using CSS. Configure physics bodies, collisions, and dynamics entirely through data attributes - no JavaScript required for basic physics interactions.
Using SAT (Separating Axis Theorem) for OBB (Oriented Bounding Box) collision detection, Gravity.js supports true rotation and realistic physics. Bodies can tilt, tumble, and collide at any angle. It integrates seamlessly with State.js for game state management and Keys.js for player input.
Perfect for creating browser-based games, interactive experiences, and physics simulations without the overhead of canvas rendering. Native DOM elements become physics bodies!

Demo 1: Falling Boxes

Dynamic Bodies with Gravity
Boxes fall under gravity and bounce on the ground. Different masses and restitution values create varied behaviors.

Demo 2: Tower of Boxes

Stack Physics & Projectile
A tower of stacked boxes with a projectile that knocks them down! Watch the boxes rotate and tumble using SAT (Separating Axis Theorem) for OBB collision detection. High friction keeps boxes stable until impact.

Demo 3: Platforms

Static Platform Bodies & Slopes
Static platforms with rotation create slopes! Watch the dynamic box slide down angled platforms and bounce between them. OBB collision allows platforms to be rotated at any angle. Use data-gravity-fixed-rotation="true" on dynamic bodies to prevent rotation.

Demo 4: Keys.js Integration

Use WASD or Arrow Keys to Move
Keys.js sets CSS variables (--key-d, --key-a, etc.) and Gravity.js reads them via comma-separated CSS variable names. Example: data-gravity-force-right="--key-d, --key-right" combines both D and Right Arrow keys. Fully declarative!

Demo 5: Tearable Cloth

Move your cursor to interact with the cloth!
A grid of particles connected by distance constraints. Grab and pull the cloth to tear it! The constraint system uses position-based dynamics with break forces. Each particle is a physics body connected to its neighbors.

How To Install?

Add the gravity.js file into your project and include it in your HTML head tags:

                        <script src="https://cdn.jsdelivr.net/npm/@idevgames/gravity-js/src/gravity.js"></script>
                    

Or use npm:

                        npm i @idevgames/gravity-js
                    

How To Use?

Add the data attribute "data-gravity" or class "enable-gravity" to your HTML element to make it a physics body:

                        <div data-gravity data-gravity-type="dynamic"></div>
                    

The element will automatically become a physics body and respond to gravity and collisions!


Physics Body Types

Three body types are available via data-gravity-type:

dynamic - Moves and collides (default)
static - Never moves (ground, walls, platforms)
kinematic - Moves but infinite mass (moving platforms)

Shape Types

Set collision shape with data-gravity-shape:

box - Rectangle collision (default, uses element dimensions)

Physics Properties

Customize physics behavior with these data attributes:

data-gravity-mass="1" - Body mass (affects momentum)
data-gravity-restitution="0.3" - Bounciness (0-1)
data-gravity-friction="0.5" - Surface friction (0-1)
data-gravity-density="1" - Material density
data-gravity-fixed-rotation="true" - Prevent rotation

Initial Velocity & Forces

Initial Velocity (Static):

data-gravity-velocity-x="10" - Initial horizontal velocity (accepts CSS variables like --cursor-x)
data-gravity-velocity-y="-5" - Initial vertical velocity (accepts CSS variables like --cursor-y)

Initial Velocity (Directional):

data-gravity-velocity-right="300" - Initial rightward velocity (accepts CSS variables)
data-gravity-velocity-left="100" - Initial leftward velocity (accepts CSS variables)
data-gravity-velocity-up="200" - Initial upward velocity (jumps! accepts CSS variables)
data-gravity-velocity-down="50" - Initial downward velocity (accepts CSS variables)

Directional velocities are combined: (right - left) for horizontal, (down - up) for vertical. All velocity attributes accept CSS variables (e.g., --cursor-x from Cursor.js). Perfect for State.js to spawn projectiles dynamically!

Container Bounds:

data-gravity-container - Add to parent element to create invisible walls/ceiling/floor

Dynamic bodies will bounce off container edges. Perfect for keeping objects in view with cursor/mouse interaction!

Continuous Forces (Static):

data-gravity-force-x="2" - Continuous horizontal force
data-gravity-force-y="0" - Continuous vertical force

Dynamic Forces (CSS Variables):

data-gravity-force-right="--key-d, --key-right" - Rightward force from CSS variable(s)
data-gravity-force-left="--key-a, --key-left" - Leftward force from CSS variable(s)
data-gravity-force-up="--key-w, --key-up" - Upward force from CSS variable(s)
data-gravity-force-down="--key-s, --key-down" - Downward force from CSS variable(s)
data-gravity-force-multiplier="80" - Scales directional force values

Perfect for Keys.js integration! Accepts comma-separated CSS variable names (values are summed). Forces are combined: (right - left) for horizontal, (down - up) for vertical.


CSS Variables

Gravity.js exposes physics state as CSS variables:

--gravity-x, --gravity-y
--gravity-rotation
--gravity-velocity-x, --gravity-velocity-y
--gravity-speed
--gravity-collision (1 when colliding)

Use these in your CSS for dynamic effects based on physics state!


Collision Detection

Collisions are detected automatically and trigger:

CSS class .gravity-colliding added during collision
CSS class .gravity-collision-[id] for specific collisions
Custom event gravitycollision on collision start
Custom event gravityexit on collision end
Data attribute data-collision-with updated with colliding element ID

Collision Sensors (Triggers)

Create trigger zones with data-gravity-sensor="true":

                        <div data-gravity data-gravity-type="static" data-gravity-sensor="true"></div>
                    

Sensors detect collisions but don't create physical responses. Perfect for trigger zones, checkpoints, and event areas!


Constraints & Joints (v1.2.0)

Connect bodies together with distance constraints using JavaScript:

const constraint = gravity.addConstraint(elementIdA, elementIdB, {
    length: 100,        // Distance to maintain (defaults to current distance)
    stiffness: 0.9,     // How strongly constraint pulls (0-1, default 0.5)
    breakForce: 50      // Tension threshold for breaking (0 = unbreakable, default 0)
});
                    

Constraint Parameters:

length - Target distance between bodies in pixels (optional, defaults to current distance)
stiffness - Constraint strength from 0 to 1 (higher = more rigid)
breakForce - Maximum tension before breaking (0 = unbreakable)

Constraint Breaking Event:

element.addEventListener('constraintbreak', (event) => {
    console.log('Constraint broke!', event.detail.constraint);
});
                    

Perfect for ropes, chains, cloth simulation, and destructible structures! See Demo 5 for a tearable cloth example.


Collision Groups

Filter collisions with data-gravity-group:

                        <div data-gravity data-gravity-group="player"></div>
                        <div data-gravity data-gravity-group="enemy"></div>
                    

Bodies only collide with others in the same group or the default group.


World Settings

Configure global physics on the body element:

data-gravity-world-gravity="9.8" - Global gravity strength
data-gravity-world-gravity-x="0" - Horizontal gravity
data-gravity-world-gravity-y="9.8" - Vertical gravity
data-gravity-damping="0.99" - Velocity damping
data-gravity-angular-damping="0.99" - Rotation damping

JavaScript API

Optional JavaScript methods for advanced control:

                        gravity.applyForce(elementId, x, y)
                        gravity.applyImpulse(elementId, x, y)
                        gravity.setVelocity(elementId, x, y)
                        gravity.getBody(elementId)
                        gravity.pauseSimulation()
                        gravity.resumeSimulation()
                    

Integration with State.js

Gravity.js works seamlessly with State.js for game state management:

                        <div id="player" data-gravity data-state data-state-watch="collision-with"></div>
                        <div id="coin" data-gravity data-gravity-sensor="true"></div>
                    

Collision events update data attributes that State.js can watch and react to. Use collision sensors to trigger state changes!


Integration with Keys.js

Combine with Keys.js for player input:

                        document.addEventListener('keydown', (e) => {
                            if (keys.isKeyDown('space')) {
                                gravity.applyImpulse('player', 0, -300);
                            }
                            if (keys.isKeyDown('right')) {
                                gravity.applyForce('player', 50, 0);
                            }
                        });
                    

Create fully interactive games with physics, input, and state management!


BUILD PHYSICS GAMES
WITH PURE CSS RENDERING

Gravity.js + State.js + Keys.js = Complete Browser Game Engine


Check out the companion libraries: