如何解决Matter.js中的自定义元素 反应
Kinda坚持使用Matter.js,希望能获得一些帮助。
我想在Matter.js中将自定义html元素呈现为实体
(我在React中使用它会增加一些复杂性,但这与我的问题无关)
我进行了很多搜索,发现的唯一示例是this one here。似乎是将查询选择器用于HTML代码中的那些元素,然后以某种方式在矩形形状中使用它们。
似乎可以完成工作的部分如下:
var bodiesDom = document.querySelectorAll('.block');
var bodies = [];
for (var i = 0,l = bodiesDom.length; i < l; i++) {
var body = Bodies.rectangle(
VIEW.centerX,20,VIEW.width*bodiesDom[i].offsetWidth/window.innerWidth,VIEW.height*bodiesDom[i].offsetHeight/window.innerHeight
);
bodiesDom[i].id = body.id;
bodies.push(body);
}
World.add(engine.world,bodies);
(VIEW变量定义形状时可能只是随机数)
但是,我无法理解如何像上面的示例一样在Bodies矩形内传递HTML元素。
理想情况下,我想让复杂的HTML元素与物理世界互动(例如带有按钮等的小盒子)
关于如何实现此目标的任何想法?还是至少可以理解在示例中使用的似乎可以管理它的方法?
解决方法
但是,我无法理解如何像上面的示例一样在Bodies矩形内传递HTML元素。
这与示例的功能完全不同。当无头运行时,Matter.js会处理物理,但不知道其渲染方式。对于每个动画帧,您可以使用MJS主体的当前位置并重新放置元素(或在画布上绘制等)以反映MJS的世界观。
为MJS提供根元素似乎确实打破了单向数据流,但这仅是为了向MJS通知诸如鼠标位置和点击之类的事件-请勿与渲染混淆。
下面是一个最小的示例,希望可以使它变得更清楚:
const engine = Matter.Engine.create();
const box = {
body: Matter.Bodies.rectangle(150,40,40),elem: document.querySelector("#box"),render: function () {
const {x,y} = this.body.position;
this.elem.style.top = `${y - 20}px`;
this.elem.style.left = `${x - 20}px`;
this.elem.style.transform = `rotate(${this.body.angle}rad)`;
},};
const ground = Matter.Bodies.rectangle(
200,200,400,120,{isStatic: true}
);
const mouseConstraint = Matter.MouseConstraint.create(
engine,{element: document.body}
);
Matter.World.add(
engine.world,[box.body,ground,mouseConstraint]
);
(function rerender() {
box.render();
Matter.Engine.update(engine);
requestAnimationFrame(rerender);
})();
#box {
position: absolute;
background: #111;
height: 40px;
width: 40px;
cursor: move;
}
#ground {
position: absolute;
background: #666;
top: 140px;
height: 120px;
width: 400px;
}
html,body {
position: relative;
height: 100%;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js" integrity="sha512-pi0tSRZdlNRZeANPwdAIHRAYg6gZZV6QlAiyHXn5TYqLzBKE9jlttO/QgYLMhISD6oNv2kPsVelx+n5nw0FqKA==" crossorigin="anonymous"></script>
<div id="box"></div>
<div id="ground"></div>
反应
React改变了工作流程,但基本概念是相同的-MJS主体数据从MJS后端单向流向渲染前端,因此从MJS的角度看,一切都与上面的原始示例相同。大部分工作是正确设置refs和useEffect
以便与requestAnimationFrame
一起使用。
#box {
position: absolute;
background: #111;
height: 40px;
width: 40px;
cursor: move;
}
#ground {
position: absolute;
top: 140px;
height: 120px;
width: 400px;
background: #666;
}
html,body {
position: relative;
height: 100%;
margin: 0;
}
<script type="text/babel" defer>
const {Fragment,useEffect,useRef} = React;
const Scene = () => {
const requestRef = useRef();
const boxRef = useRef();
const groundRef = useRef();
const animate = () => {
const engine = Matter.Engine.create();
const box = {
body: Matter.Bodies.rectangle(150,elem: boxRef.current,render: function () {
const {x,y} = this.body.position;
this.elem.style.top = `${y - 20}px`;
this.elem.style.left = `${x - 20}px`;
this.elem.style.transform = `rotate(${this.body.angle}rad)`;
},};
const ground = Matter.Bodies.rectangle(
200,{isStatic: true}
);
const mouseConstraint = Matter.MouseConstraint.create(
engine,{element: document.body}
);
Matter.World.add(
engine.world,mouseConstraint]
);
(function rerender() {
box.render();
Matter.Engine.update(engine);
requestRef.current = requestAnimationFrame(rerender);
})();
};
useEffect(() => {
animate();
return () => cancelAnimationFrame(requestRef.current);
},[]);
return (
<Fragment>
<div id="box" ref={boxRef}></div>
<div id="ground" ref={groundRef}></div>
</Fragment>
);
};
ReactDOM.render(<Scene />,document.body);
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js" integrity="sha512-pi0tSRZdlNRZeANPwdAIHRAYg6gZZV6QlAiyHXn5TYqLzBKE9jlttO/QgYLMhISD6oNv2kPsVelx+n5nw0FqKA==" crossorigin="anonymous"></script>
请注意,这些只是概念证明。在可以支持更多涉及的用例之前,可能有必要进行更多的工作来建立抽象。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。