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

Matter.js —如何获取图像尺寸以设置实体大小?

如何解决Matter.js —如何获取图像尺寸以设置实体大小?

我正在尝试以编程方式在something.js中设置链式实体的宽度和高度。不幸的是,我只得到0作为值,我不确定为什么。我的猜测是图像加载速度不足以提供这些值。如何在加载图像之前加载这些尺寸?

代码

  • Array中的几个主体
  • 获取数组中每个图像的宽度和高度
  • 使用此值设置实体尺寸

代码

var playA = Composites.stack(
  percentX(25) - assetSize / 2,percentY(25),1,6,5,function (x,y) {
    iA++;

    var imgWidth;
    var imgHeight;

    var img = new Image();
    img.src = String(design[iA]);

    var imgWidth = 0;
    var imgHeight = 0;

    img.onload = function a() {
      imgWidth = img.naturalWidth;
      imgHeight = img.naturalHeight;

      console.log(String(design[iA]),imgWidth,imgHeight);
    };
    console.log(String(design[iA]),imgHeight,imgWidth); // I can't access the values here.

    return Bodies.rectangle(x,y,{
      // collisionFilter: { group: group },friction: 1,render: {
        sprite: {
          texture: design[iA],xScale: (assetSize / 100) * 0.46,yScale: (assetSize / 100) * 0.46
        }
      }
    });
  }
);

Composites.chain(playA,0.3,-0.5,{
  stiffness: 1,length: 10,render: { type: "line",visible: false }
});

解决方法

如果您知道尺寸并可以事先填充数组,则解决方案非常简单,因为Matter.js干净地加载给定URL字符串的图像。这是一个最小的完整示例,该示例遍历数组中的宽度/高度对并将这些属性传递到rectangle调用中,我将在与您的用例匹配的示例中使用垫脚石。

var engine = Matter.Engine.create();
var render = Matter.Render.create({
  element: document.body,engine: engine,options: {
    width: 450,height: 250,wireframes: false,// required!
  }
});
Matter.Render.run(render);

var runner = Matter.Runner.create();
Matter.Runner.run(runner,engine);

var imgSizes = [[56,48],[45,50],[35,[60,63]];
var stack = Matter.Composites.stack(
  // xx,yy,columns,rows,columnGap,rowGap,cb
  150,50,4,1,function (x,y,i) {
    var w = imgSizes[i][0];
    var h = imgSizes[i][1];
    return Matter.Bodies.rectangle(x,w,h,{
      render: {
        sprite: {
          texture: "http://placekitten.com/" + w + "/" + h 
        }
      }
    });
  }
);
Matter.Composites.chain(stack,0.5,-0.5,{
  stiffness: 0.75,length: 10,render: {type: "line",visible: true}
});

Matter.World.add(engine.world,[
  stack,Matter.Bodies.rectangle(225,450,25,{
    isStatic: true
  }),Matter.Bodies.rectangle(450,150,300,Matter.Bodies.rectangle(0,250,{
    isStatic: true
  })
]);

var mouse = Matter.Mouse.create(render.canvas);
var mouseConstraint = Matter.MouseConstraint.create(engine,{
  mouse: mouse,constraint: {
    stiffness: 0.2,render: {visible: true}
  }
});
Matter.World.add(engine.world,mouseConstraint);
render.mouse = mouse;
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js" integrity="sha512-pi0tSRZdlNRZeANPwdAIHRAYg6gZZV6QlAiyHXn5TYqLzBKE9jlttO/QgYLMhISD6oNv2kPsVelx+n5nw0FqKA==" crossorigin="anonymous"></script>

现在,如果您需要使用onload加载图像并使用其尺寸,则需要使用promises或将取决于这些图像的 all 代码放入{{ 1}}回调,如规范How do I return the response from an asynchronous call?中所述。

失败的模式是:

onload

解决方法是:

const getSomethingAsync = cb => setTimeout(() => cb("something"),0);

let data = null;
getSomethingAsync(result => {
  data = result;
  console.log("this runs last");
});
console.log(data); // guaranteed to be null,not "something"
// more logic that is supposed to depend on data

由于您要同时处理多个const getSomethingAsync = cb => setTimeout(() => cb("something"),0); getSomethingAsync(data => { console.log(data); // logic that depends on the data from `getSomethingAsync` }); console.log("this will run first"); // logic that doesn't depend on data from `getSomethingAsync`,因此可以简化onload的使用范围,以使其更易于使用。我有几个与此事无关的herehere事例。

这是一个使用诺言加载应用于一般问题的图像的示例。同样,我将使用自己的代码,使其可运行和可复制,但是该模式应该易于推断到您的项目中。这个想法是先使用onload处理程序触发时解决的一系列promise加载图像,然后使用onload链接Promise.all,仅当所有图像都运行MJS初始化程序回调时,已加载。然后您的what.js代码即可访问宽度和高度。

then
var initializeMJS = function (images) {
  var engine = Matter.Engine.create();
  var render = Matter.Render.create({
    element: document.body,options: {
      width: 450,// required!
    }
  });
  Matter.Render.run(render);

  var runner = Matter.Runner.create();
  Matter.Runner.run(runner,engine);

  var stack = Matter.Composites.stack(
    // xx,cb
    150,i) {
      var w = images[i].width;
      var h = images[i].height;
      return Matter.Bodies.rectangle(x,{
        render: {
          sprite: {
            // a bit silly; MJS reloads image but it
            // seems like you have another design
            // so this is just a stub
            texture: images[i].src
          }
        }
      });
    }
  );
  Matter.Composites.chain(stack,{
    stiffness: 0.75,visible: true}
  });

  Matter.World.add(engine.world,[
    stack,{
      isStatic: true
    }),{
      isStatic: true
    })
  ]);

  var mouse = Matter.Mouse.create(render.canvas);
  var mouseConstraint = Matter.MouseConstraint.create(engine,{
    mouse: mouse,constraint: {
      stiffness: 0.2,render: {visible: true}
    }
  });
  Matter.World.add(engine.world,mouseConstraint);
  render.mouse = mouse;
};

var imageSizes = [[56,63]];
var imageURLs = imageSizes.map(function (e) {
  return "http://placekitten.com/" + e[0] + "/" + e[1];
});

Promise.all(imageURLs.map(function (e) {
  return new Promise(function (resolve,reject) {
    var img = new Image();
    img.onload = function () {
      resolve(this);
    };
    img.onerror = reject;
    img.src = e;
  })
})).then(initializeMJS);

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