Simple Draggables
You can easily scale the number of Dots here since both the refs and positions are kept as arrays.
TSX
import { Dom } from "OneJS/Dom"
import { emo } from "onejs/styled"
import { h, render } from "preact"
import { forwardRef } from "preact/compact"
import { useRef } from "preact/hooks"
import { PointerDownEvent, PointerUpEvent, PointerLeaveEvent, PointerMoveEvent } from "UnityEngine/UIElements"
const DraggableDot = forwardRef((props: any, ref) => {
return <div ref={ref} class={emo`
width: 80px;
height: 80px;
border-radius: 50%;
background-color: white;
`}
onPointerDown={props.onPointerDown}
>
</div>
})
const App = () => {
const dotRefs = [useRef<Dom>(), useRef<Dom>()]
let selectedIndex = -1
let positions = [{ x: 0, y: 0 }, { x: 0, y: 0 }]
let offsetPosition = { x: 0, y: 0 }
function pointerDown(index) {
return function (evt: PointerDownEvent) {
selectedIndex = index
offsetPosition = { x: evt.position.x - positions[index].x, y: evt.position.y - positions[index].y }
}
}
function onPointerUp(evt: PointerUpEvent) {
selectedIndex = -1
}
function onPointerLeave(evt: PointerLeaveEvent) {
selectedIndex = -1
}
function onPointerMove(evt: PointerMoveEvent) {
if (selectedIndex == -1)
return
positions[selectedIndex].x = evt.position.x - offsetPosition.x
positions[selectedIndex].y = evt.position.y - offsetPosition.y
dotRefs[selectedIndex].current.style.translate = positions[selectedIndex]
}
return <div class={emo`
width: 100%;
height: 100%;
justify-content: space-around;
align-items: center;
flex-direction: row;
`} onPointerUp={onPointerUp} onPointerLeave={onPointerLeave} onPointerMove={onPointerMove}>
<DraggableDot ref={dotRefs[0]} onPointerDown={pointerDown(0)} />
<DraggableDot ref={dotRefs[1]} onPointerDown={pointerDown(1)} />
</div>
}
render(<App />, document.body)