Cannon.js — популярная библиотека физики для браузера, широко использовавшаяся в сочетании с WebGL и Three.js. Однако её развитие остановилось, а современная альтернатива — Cannon-es — представляет собой модульную версию Cannon.js с поддержкой ES6 и улучшенной совместимостью с современными сборщиками. Переход на Cannon-es позволяет использовать импорт через модули, улучшает поддержку TypeScript и делает код более структурированным.
В Cannon.js обычно использовался глобальный объект
CANNON. В Cannon-es применяется модульная структура
ES6:
// Cannon.js
<script src="cannon.js"></script>
var world = new CANNON.World();
// Cannon-es
import * as CANNON from 'cannon-es';
const world = new CANNON.World();
Ключевые изменения:
В Cannon.js создание мира выглядело так:
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
В Cannon-es синтаксис практически идентичен:
import { World, NaiveBroadphase, Vec3 } from 'cannon-es';
const world = new World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new NaiveBroadphase();
world.solver.iterations = 10;
Особенности:
Vec3) теперь
импортируются отдельно.addBody и removeBody остаются без
изменений.Cannon-es полностью сохраняет структуру классов Body,
Shape, Box, Sphere, но изменяет
способ импорта:
import { Body, Box, Sphere, Vec3 } from 'cannon-es';
// Создание тела с кубической формой
const boxShape = new Box(new Vec3(1, 1, 1));
const boxBody = new Body({
mass: 5,
position: new Vec3(0, 10, 0),
shape: boxShape
});
world.addBody(boxBody);
// Создание сферического тела
const sphereShape = new Sphere(1);
const sphereBody = new Body({
mass: 2,
position: new Vec3(2, 10, 0),
shape: sphereShape
});
world.addBody(sphereBody);
Изменения по сравнению с Cannon.js:
class CustomBody extends Body {
constructor(options) {
super(options);
// дополнительные свойства
}
}
В Cannon-es полностью сохранён функционал материалов и контактных свойств:
import { Material, ContactMaterial } from 'cannon-es';
const groundMaterial = new Material('ground');
const boxMaterial = new Material('box');
const contactMaterial = new ContactMaterial(groundMaterial, boxMaterial, {
friction: 0.4,
restitution: 0.3
});
world.addContactMaterial(contactMaterial);
Особенности:
addContactMaterial и
removeContactMaterial работают как и раньше.Шаг времени в Cannon-es аналогичен Cannon.js, но рекомендуется использовать фиксированный шаг с переменной дельтой для более стабильной симуляции:
const timeStep = 1.0 / 60.0; // 60 FPS
function update(deltaTime) {
world.step(timeStep, deltaTime);
}
Изменения:
deltaTime) для плавного движения.function animate(time) {
requestAnimationFrame(animate);
const deltaTime = (time - lastTime) / 1000;
world.step(timeStep, deltaTime);
lastTime = time;
// обновление визуализации
}
let lastTime = performance.now();
animate(lastTime);
Cannon-es поддерживает события collide,
collideBegin, collideEnd:
boxBody.addEventListener('collide', (event) => {
console.log('Box столкнулся с', event.body);
});
Отличия от Cannon.js:
addEventListener, аналогичный DOM.event.contact предоставляет доступ к объекту контакта с
подробными данными (позиция, нормаль, сила).Cannon-es идеально интегрируется с Three.js. Основная схема синхронизации:
mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);
Vec3 и Quaternion Cannon-es легко
конвертируются в объекты Three.js (THREE.Vector3,
THREE.Quaternion) через методы copy.CANNON.CANNON.* и заменить на
импортируемые классы..addEventListener.Переход на Cannon-es позволяет сохранить весь функционал Cannon.js, при этом использовать современные возможности JavaScript, улучшенную модульность и совместимость с современными инструментами разработки.