Top Related Projects
💣 A lightweight 3D physics engine written in JavaScript.
Lightweight 3d physics engine for javascript
Direct port of the Bullet physics engine to JavaScript using Emscripten
Physics plugin for Three.js
a 2D rigid body physics engine for the web ▲● ■
Quick Overview
Cannon.js is a lightweight 3D physics engine for the web. It's designed to be used in JavaScript applications, particularly in conjunction with 3D rendering libraries like Three.js. Cannon.js provides a simple API for simulating rigid body dynamics, including collision detection and response.
Pros
- Lightweight and fast, suitable for real-time web applications
- Easy integration with popular 3D libraries like Three.js
- Supports various shapes and constraints for complex simulations
- Active community and ongoing development
Cons
- Limited documentation compared to some other physics engines
- May not be as feature-rich as more comprehensive physics engines
- Performance can degrade with a large number of complex objects
- Occasional stability issues in certain edge cases
Code Examples
Creating a world and adding a sphere:
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
const sphereShape = new CANNON.Sphere(1);
const sphereBody = new CANNON.Body({
mass: 5,
shape: sphereShape
});
sphereBody.position.set(0, 10, 0);
world.addBody(sphereBody);
Adding a ground plane:
const groundShape = new CANNON.Plane();
const groundBody = new CANNON.Body({ mass: 0 });
groundBody.addShape(groundShape);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
world.addBody(groundBody);
Stepping the simulation:
const fixedTimeStep = 1.0 / 60.0;
const maxSubSteps = 3;
function animate(time) {
requestAnimationFrame(animate);
world.step(fixedTimeStep, time, maxSubSteps);
// Update your 3D objects here based on the physics simulation
}
animate();
Getting Started
-
Install Cannon.js using npm:
npm install cannon
-
Import Cannon.js in your project:
import * as CANNON from 'cannon';
-
Create a world and add bodies:
const world = new CANNON.World(); world.gravity.set(0, -9.82, 0); // Add bodies and shapes here function animate() { requestAnimationFrame(animate); world.step(1/60); // Update your 3D objects here } animate();
-
For integration with Three.js, update your Three.js objects' positions and rotations based on the Cannon.js bodies in your animation loop.
Competitor Comparisons
💣 A lightweight 3D physics engine written in JavaScript.
Pros of cannon-es
- Actively maintained with regular updates and bug fixes
- Supports modern JavaScript modules (ES6+) and TypeScript
- Improved performance and optimizations
Cons of cannon-es
- Potential compatibility issues with older projects using cannon.js
- Some features or APIs might differ from the original cannon.js
Code Comparison
cannon.js:
var world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
var shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
var body = new CANNON.Body({ mass: 1 });
body.addShape(shape);
world.addBody(body);
cannon-es:
import { World, Box, Vec3, Body } from 'cannon-es';
const world = new World();
world.gravity.set(0, -9.82, 0);
const shape = new Box(new Vec3(1, 1, 1));
const body = new Body({ mass: 1 });
body.addShape(shape);
world.addBody(body);
The main difference in the code is the import statement and the use of ES6 module syntax in cannon-es, while cannon.js uses the global CANNON object. The API and usage remain largely similar between the two libraries.
Lightweight 3d physics engine for javascript
Pros of Oimo.js
- Smaller file size, making it more lightweight for web applications
- Better performance for simpler physics simulations
- More frequent updates and active development
Cons of Oimo.js
- Less comprehensive documentation compared to Cannon.js
- Fewer features and constraints available for complex simulations
- Smaller community and fewer resources for troubleshooting
Code Comparison
Cannon.js:
var world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
var shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
var body = new CANNON.Body({ mass: 1 });
body.addShape(shape);
world.addBody(body);
Oimo.js:
var world = new OIMO.World({ gravity: [0, -9.82, 0] });
var shape = new OIMO.BoxShape(2, 2, 2);
var body = new OIMO.RigidBody({
shape: shape,
position: [0, 0, 0],
mass: 1
});
world.addRigidBody(body);
Both libraries offer similar functionality for basic physics simulations, but Cannon.js provides more advanced features and constraints. Oimo.js has a simpler API and may be easier to use for beginners or smaller projects. The choice between the two depends on the specific requirements of your project, considering factors such as performance, file size, and complexity of the physics simulations needed.
Direct port of the Bullet physics engine to JavaScript using Emscripten
Pros of Ammo.js
- More comprehensive physics simulation, including soft body dynamics
- Better performance for complex simulations due to C++ core
- Wider adoption and community support
Cons of Ammo.js
- Larger file size and more complex setup
- Steeper learning curve for beginners
- Less straightforward JavaScript API
Code Comparison
Cannon.js:
var world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
var shape = new CANNON.Sphere(1);
var body = new CANNON.Body({ mass: 1, shape: shape });
world.addBody(body);
Ammo.js:
var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
var dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
var overlappingPairCache = new Ammo.btDbvtBroadphase();
var solver = new Ammo.btSequentialImpulseConstraintSolver();
var dynamicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
Both Cannon.js and Ammo.js are popular physics engines for JavaScript, but they cater to different needs. Cannon.js is lightweight and easy to use, making it ideal for simple simulations and quick prototyping. Ammo.js, on the other hand, offers more advanced features and better performance for complex scenarios, but comes with a steeper learning curve and more complex setup. The choice between the two depends on the specific requirements of your project and your familiarity with physics engines.
Physics plugin for Three.js
Pros of Physijs
- Tighter integration with Three.js, making it easier to use for Three.js-based projects
- Simpler API and setup process for basic physics simulations
- Built-in support for common 3D shapes and materials
Cons of Physijs
- Less active development and community support compared to Cannon.js
- Limited customization options for advanced physics simulations
- Dependency on Ammo.js, which can increase project size and complexity
Code Comparison
Physijs example:
var scene = new Physijs.Scene();
var box = new Physijs.BoxMesh(
new THREE.BoxGeometry(5, 5, 5),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
);
scene.add(box);
Cannon.js example:
var world = new CANNON.World();
var shape = new CANNON.Box(new CANNON.Vec3(2.5, 2.5, 2.5));
var body = new CANNON.Body({ mass: 1, shape: shape });
world.addBody(body);
Both libraries provide physics simulation capabilities for web-based 3D applications. Physijs offers easier integration with Three.js and a simpler API, making it suitable for quick prototypes and basic simulations. Cannon.js, on the other hand, provides more flexibility and customization options, making it better suited for complex physics simulations and games. The choice between the two depends on the specific requirements of your project and your familiarity with Three.js.
a 2D rigid body physics engine for the web ▲● ■
Pros of Matter.js
- Easier to use and more beginner-friendly
- Better documentation and examples
- Focuses on 2D physics, making it more efficient for 2D games and simulations
Cons of Matter.js
- Limited to 2D physics, while Cannon.js supports 3D
- Less precise for complex simulations compared to Cannon.js
- Smaller community and fewer third-party plugins
Code Comparison
Matter.js example:
var engine = Matter.Engine.create();
var box = Matter.Bodies.rectangle(200, 200, 80, 80);
Matter.World.add(engine.world, box);
Matter.Engine.run(engine);
Cannon.js example:
var world = new CANNON.World();
var shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
var body = new CANNON.Body({ mass: 1, shape: shape });
world.addBody(body);
world.step(1/60);
Both libraries provide similar functionality for creating physics simulations, but Matter.js has a more straightforward API for 2D physics, while Cannon.js offers more flexibility for 3D simulations. Matter.js is generally easier to get started with, especially for 2D projects, while Cannon.js provides more advanced features and precision for complex 3D physics simulations.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
cannon.js
Lightweight 3D physics for the web
Inspired by three.js and ammo.js, and driven by the fact that the web lacks a physics engine, here comes cannon.js. The rigid body physics engine includes simple collision detection, various body shapes, contacts, friction and constraints.
Demos - Documentation - Rendering hints - NPM package - CDN
Browser install
Just include cannon.js or cannon.min.js in your html and you're done:
<script src="cannon.min.js"></script>
Node.js install
Install the cannon package via NPM:
npm install --save cannon
Alternatively, point to the Github repo directly to get the very latest version:
npm install --save schteppe/cannon.js
Example
The sample code below creates a sphere on a plane, steps the simulation, and prints the sphere simulation to the console. Note that Cannon.js uses SI units (metre, kilogram, second, etc.).
// Setup our world
var world = new CANNON.World();
world.gravity.set(0, 0, -9.82); // m/s²
// Create a sphere
var radius = 1; // m
var sphereBody = new CANNON.Body({
mass: 5, // kg
position: new CANNON.Vec3(0, 0, 10), // m
shape: new CANNON.Sphere(radius)
});
world.addBody(sphereBody);
// Create a plane
var groundBody = new CANNON.Body({
mass: 0 // mass == 0 makes the body static
});
var groundShape = new CANNON.Plane();
groundBody.addShape(groundShape);
world.addBody(groundBody);
var fixedTimeStep = 1.0 / 60.0; // seconds
var maxSubSteps = 3;
// Start the simulation loop
var lastTime;
(function simloop(time){
requestAnimationFrame(simloop);
if(lastTime !== undefined){
var dt = (time - lastTime) / 1000;
world.step(fixedTimeStep, dt, maxSubSteps);
}
console.log("Sphere z position: " + sphereBody.position.z);
lastTime = time;
})();
If you want to know how to use cannon.js with a rendering engine, for example Three.js, see the Examples.
Features
- Rigid body dynamics
- Discrete collision detection
- Contacts, friction and restitution
- Constraints
- PointToPoint (a.k.a. ball/socket joint)
- Distance
- Hinge (with optional motor)
- Lock
- ConeTwist
- Gauss-Seidel constraint solver and an island split algorithm
- Collision filters
- Body sleeping
- Experimental SPH / fluid support
- Various shapes and collision algorithms (see table below)
Sphere | Plane | Box | Convex | Particle | Heightfield | Trimesh | |
---|---|---|---|---|---|---|---|
Sphere | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Plane | - | - | Yes | Yes | Yes | - | Yes |
Box | - | - | Yes | Yes | Yes | Yes | (todo) |
Cylinder | - | - | Yes | Yes | Yes | Yes | (todo) |
Convex | - | - | - | Yes | Yes | Yes | (todo) |
Particle | - | - | - | - | - | (todo) | (todo) |
Heightfield | - | - | - | - | - | - | (todo) |
Trimesh | - | - | - | - | - | - | - |
Todo
The simpler todos are marked with @todo
in the code. Github Issues can and should also be used for todos.
Help
Create an issue if you need help.
Top Related Projects
💣 A lightweight 3D physics engine written in JavaScript.
Lightweight 3d physics engine for javascript
Direct port of the Bullet physics engine to JavaScript using Emscripten
Physics plugin for Three.js
a 2D rigid body physics engine for the web ▲● ■
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot