javascript - 为什么 MatterJS 物理坐标与 DOM 元素有偏移?
问题描述
我正在通过向物理引擎添加框来运行 MatterJS 物理模拟,同时创建具有相同尺寸的 DOM 元素。
然后,我遍历物理框以获取它们的坐标。然后我使用这些坐标来定位相应的 DOM 元素。这似乎工作正常,除了我的静态“地面”框周围似乎有一个 10 像素的不可见半径?
我的盒子是 40x40 像素。地面为 400 像素。盒子在 350 像素处停止下降。那么为什么会有 10 个像素的差异呢?
编辑:如果我在画布中渲染相同的框,则不存在差异。代码笔画布
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>
推荐阅读
- python - 使用此 for 循环计算体重指数时,为什么我会得到不受支持的操作数类型?
- r - 使用 position_dodge 在条形图上叠加点(和误差线)
- javascript - 计算车轮数据 XY 位置
- python-3.x - Python-Selenium:剪贴板功能(ctrl + c)在 Firefox 无头模式下不起作用
- powershell - 当密码以空格开头时,连接到 Office 365 powershell 失败
- windows - 如何让 Windows 的 Smart Screen 信任我的安装程序?
- python - 使用我想转换为字符串的未初始化变量调用函数
- laravel - 如何在控制器中编写 foreach 循环以及刀片代码?
- sql - 一定时间内的聚合
- c - 死锁条件(科夫曼条件)