Cannon.js — это легковесная физическая библиотека на JavaScript для работы с динамическими объектами в 3D-пространстве. Она позволяет моделировать твердые тела, столкновения, гравитацию и контакты между объектами с минимальной нагрузкой на браузер. Основные компоненты библиотеки включают:
Простейший пример создания физического мира:
import * as CANNON from 'cannon-es';
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // Земная гравитация по оси Y
const groundBody = new CANNON.Body({
mass: 0, // неподвижное тело
shape: new CANNON.Plane(),
});
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0);
world.addBody(groundBody);
const sphereBody = new CANNON.Body({
mass: 5,
shape: new CANNON.Sphere(1),
position: new CANNON.Vec3(0, 10, 0),
});
world.addBody(sphereBody);
function simulate(deltaTime) {
world.step(deltaTime);
}
Cannon-es — это форк оригинальной Cannon.js с поддержкой ES-модулей, улучшенной совместимостью с современными сборщиками (Webpack, Vite, Rollup) и активным сопровождением. Отличия и преимущества:
import { World, Body, Box } from 'cannon-es').Пример инициализации Cannon-es:
import { World, Body, Sphere, Plane, Vec3 } from 'cannon-es';
const world = new World();
world.gravity.set(0, -9.82, 0);
const ground = new Body({
mass: 0,
shape: new Plane(),
});
ground.quaternion.setFromEuler(-Math.PI / 2, 0, 0);
world.addBody(ground);
const ball = new Body({
mass: 1,
shape: new Sphere(1),
position: new Vec3(0, 5, 0),
});
world.addBody(ball);
function update(deltaTime) {
world.step(deltaTime);
}
| Характеристика | Cannon.js | Cannon-es |
|---|---|---|
| Статус разработки | Стагнирует, мало обновлений | Активный форк, исправления багов |
| Модули | CommonJS или глобальные объекты | ES-модули |
| Совместимость с сборщиками | Ограничена | Полная (Webpack, Vite, Rollup) |
| Tree Shaking | Нет | Да |
| Поддержка современных браузеров | Частичная | Полная |
Вывод по выбору версии: Для современных проектов предпочтительнее использовать Cannon-es из-за модульности, исправленных багов и совместимости с инструментами сборки. Оригинальная Cannon.js актуальна только для старых проектов или когда необходима минимальная зависимость без сборщиков.
Одна из сильных сторон Cannon.js и Cannon-es — точная настройка материалов и взаимодействий. Пример с разными коэффициентами трения и упругости:
import { Material, ContactMaterial } from 'cannon-es';
const iceMaterial = new Material('ice');
const rubberMaterial = new Material('rubber');
const iceRubberContact = new ContactMaterial(
iceMaterial,
rubberMaterial,
{
friction: 0.1, // низкое трение
restitution: 0.9, // высокая упругость
}
);
world.addContactMaterial(iceRubberContact);
Для отслеживания столкновений объектов используется событие
collide на телах:
sphereBody.addEventListener('collide', (event) => {
console.log('Сфера столкнулась с телом:', event.body);
});
Эта возможность позволяет реализовать физические реакции, звук столкновения или игровую логику на основе физики.
Метод world.step(timeStep) поддерживает точность и
стабильность физики:
const fixedTimeStep = 1 / 60;
const maxSubSteps = 3;
world.step(fixedTimeStep, deltaTime, maxSubSteps);
Чаще всего Cannon-es используется совместно с Three.js для визуализации. При этом физические объекты создаются в Cannon-es, а визуальные — в Three.js. Их позиции и ориентации синхронизируются на каждом кадре:
sphereMesh.position.copy(sphereBody.position);
sphereMesh.quaternion.copy(sphereBody.quaternion);
Это обеспечивает реалистичное движение с полной поддержкой физики и визуализации.
Cannon-es поддерживает:
Для сложных объектов важно учитывать производительность и стабильность симуляции, используя ConvexPolyhedron, когда это возможно.
Cannon.js и Cannon-es предоставляют полный набор инструментов для создания физики в 3D-пространстве. Основное различие заключается в модульности, исправлениях багов и совместимости с современными инструментами — именно эти факторы делают выбор между версиями критичным при разработке современных приложений.