微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 MatterJS 物理坐标与 DOM 元素有偏移?

如何解决为什么 MatterJS 物理坐标与 DOM 元素有偏移?

我通过向物理引擎添加框来运行 MatterJS 物理模拟,同时创建具有相同尺寸的 DOM 元素。

然后,我将遍历物理框以获取它们的坐标。然后我使用这些坐标来定位相应的 DOM 元素。这似乎工作正常,除了我的静态“地面”框似乎有一个 10 像素的不可见半径围绕它?

我的盒子是 40x40 像素。地面为 400 像素。盒子在 350 像素处停止下降。那么为什么会有 10 个像素的差异呢?

Here is an example of the issue in CodePen

编辑:如果我在画布中渲染相同的框,则不存在差异。 Codepen Canvas

class Box {
  constructor(world,x,y,w,h,options) {
    // add Box to physics simulation
    this.physicsBox = Matter.Bodies.rectangle(x,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,320,70,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,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,320,70,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>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。