Matter js 를 사용해서 움직이는 DOM element 를 만들어 보기로 했다.
Matterjs 는 2d physics engine을 만들 수 있는 library 이다.
Matterjs만 사용해서 그 안에 있는 render 기능을 쓰면 canvas element를 사용하게 된다.
이렇게 되었을 때 어떤 event가 있을 때 각 body의 style property를 쉽게 변경할 수 없다는 단점이 있다.
https://stackoverflow.com/questions/63906218/using-matter-js-to-render-to-the-dom-or-react
Using Matter.js to render to the DOM or React
I want to render custom HTML elements as Bodies in Matter.js. I am using it in React which adds a bit of complexity but it's irrelevant to my issue. I've searched a lot and the only example I found...
stackoverflow.com
이 포스트를 보고 물리엔진을 돌린 좌표를 그대로 사용하되 DOM element 의 transform, position 을 조정하면서 사용하게 되면, style property들을 쉽게 업데이트를 할 수 있는 것을 알 수 있었다. 위 코드에 잘 설명이 되어있어서 따로 변경할것이 많진 않았지만,
typescript와 react를 사용해서 하다보니, 위 코드와 다른 점이 몇가지 있었다. Mouseconstraint를 설정할 때 element field가 없고, 따로 mouse object를 선언해서 사용해야 한다.
const mouse = Mouse.create(document.body)
mouseConstraint.current = MouseConstraint.create(engine.current, {
mouse: mouse,
constraint: {
stiffness: 0.1,
length: 0,
},
})
이렇게 설정하게 되면 mouse.create함수 안에 parameter로 들어가는 element에 mouse event listener를 설정하게 된다. 그래서 위 코드에서는 document.body element 에 bounded되어서 mouse event가 관리되는 것이다.
(참조 : https://github.com/liabru/matter-js/blob/master/src/core/Mouse.js#L15 )
그리고 나서 맨 위의 stackoverflow글을 참조하여 react 관련해서 잘 설정해주고 나면, 잘 돌아간다!
Mouse event가 발생했을 때 CSS style을 바꾸려면 아래와 같이 하면된다.
Events.on(mouseConstraint.current, 'mousedown', (e: any): void => {
if (!!mouseConstraint.current?.body) {
_.map(objects, (val) => {
if (val.id === mouseConstraint.current?.body.id) {
if (!!selected.current.has(val.id)) {
if (!selected.current.get(val.id)?.selected) {
//style 변경
} else {
//style 변경
}
}
}
}
}
}
'Frontend (React)' 카테고리의 다른 글
GSAP Mistakes - 2편 (0) | 2024.08.28 |
---|---|
Avoiding FOUC & GSAP Mistakes 정리 (0) | 2024.08.28 |
React 상태관리 (1) | 2024.02.11 |