湖上湖
但是,我无法理解如何像上面的示例那样在 Bodies 矩形内传递 HTML 元素。这不是这个例子所做的。当无头运行时,Matter.js 处理物理而不知道它是如何呈现的。每个动画帧,您可以使用 MJS 主体的当前位置并重新定位您的元素(或在画布上绘制等)以反映 MJS 的世界观。向 MJS 提供根元素似乎会破坏单向数据流,但这只是为了通知 MJS 有关鼠标位置和点击等事件的信息——不要与渲染混淆。这是一个希望能使这一点更清楚的最小示例:const engine = Matter.Engine.create(); const box = { body: Matter.Bodies.rectangle(150, 0, 40, 40), elem: document.querySelector("#box"), render() { 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.Composite.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.19.0/matter.min.js"></script><div id="box"></div><div id="ground"></div>反应React 改变了工作流程,但基本概念是相同的——MJS 主体数据从 MJS 后端单向流向渲染前端,因此从 MJS 的角度来看,一切都与上面的普通示例相同。大部分工作是设置refs并useEffect正确地与requestAnimationFrame.const {Fragment, useEffect, useRef} = React;const Scene = () => { const requestRef = useRef(); const boxRef = useRef(); const groundRef = useRef(); const engineRef = useRef(); const animate = () => { engineRef.current = Matter.Engine.create(); const engine = engineRef.current; const box = { body: Matter.Bodies.rectangle(150, 0, 40, 40), elem: boxRef.current, render() { 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, // x 200, // y 400, // w 120, // h {isStatic: true} ); const mouseConstraint = Matter.MouseConstraint.create( engine, {element: document.body} ); Matter.Composite.add(engine.world, [ box.body, ground, mouseConstraint, ]); (function rerender() { box.render(); Matter.Engine.update(engine); requestRef.current = requestAnimationFrame(rerender); })(); }; useEffect(() => { animate(); return () => { cancelAnimationFrame(requestRef.current); Matter.Engine.clear(engineRef.current); // see https://github.com/liabru/matter-js/issues/564 // for additional cleanup if using MJS renderer/runner }; }, []); return ( <Fragment> <div id="box" ref={boxRef}></div> <div id="ground" ref={groundRef}></div> </Fragment> );};ReactDOM.createRoot(document.querySelector("#app")).render( <Scene />);#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 crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script><script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script><div id="app"></div>请注意,这些只是概念验证。在它们能够支持更多涉及的用例之前,可能需要更多的工作来设置抽象。