如何解决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
的使用范围,以使其更易于使用。我有几个与此事无关的here和here事例。
这是一个使用诺言加载应用于一般问题的图像的示例。同样,我将使用自己的代码,使其可运行和可复制,但是该模式应该易于推断到您的项目中。这个想法是先使用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 举报,一经查实,本站将立刻删除。