我正在通过向物理引擎添加盒子来运行 MatterJS 物理模拟,同时创建具有相同尺寸的 DOM 元素。
然后,我循环遍历物理框以获取它们的坐标。然后我使用这些坐标来定位相应的 DOM 元素。这似乎工作正常,除了我的静态“地面”框周围似乎有一个 10 像素的不可见半径?
我的盒子是 40x40 像素。地面为 400 像素。盒子在 350 像素处停止下落。那么为什么会有 10 像素的差异呢?
Here is an example of the issue in CodePen
编辑:如果我在 Canvas 中渲染相同的框,则不存在差异。 Codepen Canvas
class Box {
constructor(world, x, y, w, h, options) {
// add box to physics simulation
this.physicsBox = Matter.Bodies.rectangle(x, y, w, h, options);
Matter.Composite.add(world, this.physicsBox);
// add DOM box at the same coordinates
this.div = document.createElement("box");
document.body.appendChild(this.div);
this.div.style.width = w + "px";
this.div.style.height = h + "px";
this.update();
}
update() {
let pos = this.physicsBox.position;
let angle = this.physicsBox.angle;
let degrees = angle * (180 / Math.PI);
this.div.style.transform = `translate(${pos.x}px, ${pos.y}px) rotate(${degrees}deg)`;
}
}
let engine;
let boxes = [];
setupMatter();
addObjects();
gameLoop();
function setupMatter() {
engine = Matter.Engine.create();
}
function addObjects() {
boxes.push(
new Box(engine.world, 250, 20, 40, 40),
new Box(engine.world, 300, 350, 40, 40),
new Box(engine.world, 320, 70, 40, 40),
new Box(engine.world, 0, 400, 800, 60, { isStatic: true })
);
}
function gameLoop() {
// update the physics world
Matter.Engine.update(engine, 1000 / 60);
// update the DOM world
for (let b of boxes) {
b.update();
}
requestAnimationFrame(() => this.gameLoop());
}
html,
body {
background-color: #4b4b4b;
color: white;
margin: 0px;
padding: 0px;
}
box {
margin: 0px;
padding: 0px;
box-sizing: border-box;
position: absolute;
display: block;
background-color: rgba(45, 188, 232, 0.687);
transform-origin: 20px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
最佳答案
问题是当你设置盒子的 x,y 位置时,你没有考虑高度。所以显示的位置与实际位置不符。
我真正改变的唯一一行是 this.div.style.transform = `translate(${pos.x}px, ${pos.y}px)rotate(${ Degrees}deg) `;
.
造成 10 像素差异的原因是 60 像素深的底座显示太低 30 像素(深度的一半),而 40 像素深的框显示太低 20 像素 - 底座上方净 10 像素。当我尝试将高度设置为 1px 时,一切看起来都不错,这就是我发现该错误的原因。
class Box {
constructor(world, x, y, w, h, options) {
// add box to physics simulation
this.physicsBox = Matter.Bodies.rectangle(x, y, w, h, options);
Matter.Composite.add(world, this.physicsBox);
// add DOM box at the same coordinates
this.div = document.createElement("box");
document.body.appendChild(this.div);
this.div.style.width = w + "px";
this.div.style.height = h + "px";
this.width = w;
this.height = h;
this.update();
}
update() {
let pos = this.physicsBox.position;
let angle = this.physicsBox.angle;
let degrees = angle * (180 / Math.PI);
this.div.style.transform = `translate(${pos.x - (this.width/2)}px, ${pos.y-(this.height/2)}px) rotate(${degrees}deg)`;
}
}
let engine;
let boxes = [];
setupMatter();
addObjects();
gameLoop();
function setupMatter() {
engine = Matter.Engine.create();
}
function addObjects() {
boxes.push(
new Box(engine.world, 250, 20, 40, 40),
new Box(engine.world, 300, 350, 40, 40),
new Box(engine.world, 320, 70, 40, 40),
new Box(engine.world, 0, 400, 800, 60, { isStatic: true })
);
}
function gameLoop() {
// update the physics world
Matter.Engine.update(engine, 1000 / 60);
// update the DOM world
for (let b of boxes) {
b.update();
}
requestAnimationFrame(() => this.gameLoop());
}
html,
body {
background-color: #4b4b4b;
color: white;
margin: 0px;
padding: 0px;
}
box {
margin: 0px;
padding: 0px;
box-sizing: border-box;
position: absolute;
display: block;
background-color: rgba(45, 188, 232, 0.687);
transform-origin: 20px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
关于javascript - 为什么 MatterJS 物理坐标与 DOM 元素有偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67604421/