Steal Jess's mouse move code (#137)

steal Jess's mouse move code
This commit is contained in:
Kurt Hutten
2023-06-21 09:15:02 +10:00
committed by GitHub
parent efa3bc7ac6
commit dd3117cf03
4 changed files with 106 additions and 19 deletions

View File

@ -56,7 +56,7 @@
}, },
"jest": { "jest": {
"transformIgnorePatterns": [ "transformIgnorePatterns": [
"node_modules/(?!(three|allotment|@tauri-apps\/api)/)" "node_modules/(?!(three|allotment|@tauri-apps/api)/)"
] ]
}, },
"prettier": { "prettier": {
@ -93,6 +93,7 @@
"@tauri-apps/cli": "^1.3.1", "@tauri-apps/cli": "^1.3.1",
"@types/crypto-js": "^4.1.1", "@types/crypto-js": "^4.1.1",
"@types/three": "^0.146.0", "@types/three": "^0.146.0",
"@types/uuid": "^9.0.2",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"postcss": "^8.4.19", "postcss": "^8.4.19",
"prettier": "^2.8.0", "prettier": "^2.8.0",

View File

@ -209,7 +209,7 @@ function App() {
<MemoryPanel /> <MemoryPanel />
<Logs /> <Logs />
</Allotment> </Allotment>
<Allotment vertical defaultSizes={[400, 1]} minSize={20}> <Allotment vertical defaultSizes={[1, 400]} minSize={20}>
<div className="h-full"> <div className="h-full">
<PanelHeader title="Drafting Board" /> <PanelHeader title="Drafting Board" />
<Toolbar /> <Toolbar />

View File

@ -1,5 +1,6 @@
import { useEffect, useRef } from 'react' import { useEffect, useRef } from 'react'
import { PanelHeader } from '../components/PanelHeader' import { PanelHeader } from '../components/PanelHeader'
import { v4 as uuidv4 } from 'uuid'
export const Stream = () => { export const Stream = () => {
const videoRef = useRef<HTMLVideoElement>(null) const videoRef = useRef<HTMLVideoElement>(null)
@ -11,6 +12,8 @@ export const Stream = () => {
) )
return return
const url = 'wss://api.dev.kittycad.io/ws/modeling/commands' const url = 'wss://api.dev.kittycad.io/ws/modeling/commands'
const file_id = uuidv4()
let currentCmdId: null | string = null
const [pc, socket] = [new RTCPeerConnection(), new WebSocket(url)] const [pc, socket] = [new RTCPeerConnection(), new WebSocket(url)]
// Connection opened // Connection opened
socket.addEventListener('open', (event) => { socket.addEventListener('open', (event) => {
@ -41,13 +44,13 @@ export const Stream = () => {
if (message.type === 'SDPAnswer') { if (message.type === 'SDPAnswer') {
pc.setRemoteDescription(new RTCSessionDescription(message.answer)) pc.setRemoteDescription(new RTCSessionDescription(message.answer))
} else if (message.type === 'TrickleIce') { } else if (message.type === 'TrickleIce') {
console.log("got remote trickle ice"); console.log('got remote trickle ice')
pc.addIceCandidate(message.candidate); pc.addIceCandidate(message.candidate)
} else if (message.type === 'IceServerInfo') { } else if (message.type === 'IceServerInfo') {
console.log('received IceServerInfo') console.log('received IceServerInfo')
pc.setConfiguration({ pc.setConfiguration({
iceServers: message.ice_servers, iceServers: message.ice_servers,
iceTransportPolicy: "relay", iceTransportPolicy: 'relay',
}) })
pc.ontrack = function (event) { pc.ontrack = function (event) {
if (videoRef.current) { if (videoRef.current) {
@ -69,14 +72,14 @@ export const Stream = () => {
}) })
) )
} else { } else {
console.log("sending trickle ice candidate"); console.log('sending trickle ice candidate')
const { const { candidate } = event
candidate socket.send(
} = event; JSON.stringify({
socket.send(JSON.stringify({ type: 'TrickleIce',
type: "TrickleIce",
candidate: candidate.toJSON(), candidate: candidate.toJSON(),
})); })
)
} }
} }
@ -87,11 +90,13 @@ export const Stream = () => {
pc.createOffer() pc.createOffer()
.then((d) => pc.setLocalDescription(d)) .then((d) => pc.setLocalDescription(d))
.then(() => { .then(() => {
console.log("sent SDPOffer begin"); console.log('sent SDPOffer begin')
socket.send(JSON.stringify({ socket.send(
type: "SDPOffer", JSON.stringify({
type: 'SDPOffer',
offer: pc.localDescription, offer: pc.localDescription,
})); })
)
}) })
.catch(console.log) .catch(console.log)
} }
@ -101,15 +106,89 @@ export const Stream = () => {
const debounceSocketSend = throttle((message) => { const debounceSocketSend = throttle((message) => {
socket.send(JSON.stringify(message)) socket.send(JSON.stringify(message))
}, 100) }, 100)
const handleClick = ({ clientX, clientY }: MouseEvent) => {
if (!videoRef.current) return
const { left, top } = videoRef.current.getBoundingClientRect()
const x = clientX - left
const y = clientY - top
console.log('click', x, y)
if (currentCmdId == null) {
currentCmdId = uuidv4()
debounceSocketSend({
type: 'ModelingCmdReq',
cmd: {
CameraDragStart: {
interaction: 'rotate',
window: {
x: x,
y: y,
},
},
},
cmd_id: uuidv4(),
file_id: file_id,
})
}
}
const handleMouseUp = ({ clientX, clientY }: MouseEvent) => {
if (!videoRef.current) return
const { left, top } = videoRef.current.getBoundingClientRect()
const x = clientX - left
const y = clientY - top
console.log('click', x, y)
if (currentCmdId == null) {
return
}
debounceSocketSend({
type: 'ModelingCmdReq',
cmd: {
CameraDragEnd: {
interaction: 'rotate',
window: {
x: x,
y: y,
},
},
},
cmd_id: uuidv4(),
file_id: file_id,
})
currentCmdId = null
}
const handleMouseMove = ({ clientX, clientY }: MouseEvent) => { const handleMouseMove = ({ clientX, clientY }: MouseEvent) => {
if (!videoRef.current) return if (!videoRef.current) return
const { left, top } = videoRef.current.getBoundingClientRect() const { left, top } = videoRef.current.getBoundingClientRect()
const x = clientX - left const x = clientX - left
const y = clientY - top const y = clientY - top
debounceSocketSend({ type: 'MouseMove', x: x, y: y }) if (currentCmdId == null) {
return
} else {
console.log('mouse move', x, y)
debounceSocketSend({
type: 'ModelingCmdReq',
cmd: {
CameraDragMove: {
interaction: 'rotate',
window: {
x: x,
y: y,
},
},
},
cmd_id: uuidv4(),
file_id: file_id,
})
}
} }
if (videoRef.current) { if (videoRef.current) {
videoRef.current.addEventListener('mousemove', handleMouseMove) videoRef.current.addEventListener('mousemove', handleMouseMove)
videoRef.current.addEventListener('mousedown', handleClick)
videoRef.current.addEventListener('mouseup', handleMouseUp)
} }
return () => { return () => {
@ -117,6 +196,8 @@ export const Stream = () => {
pc.close() pc.close()
if (!videoRef.current) return if (!videoRef.current) return
videoRef.current.removeEventListener('mousemove', handleMouseMove) videoRef.current.removeEventListener('mousemove', handleMouseMove)
videoRef.current.removeEventListener('mousedown', handleClick)
videoRef.current.removeEventListener('mouseup', handleMouseUp)
} }
}, []) }, [])

View File

@ -2695,6 +2695,11 @@
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
"@types/uuid@^9.0.2":
version "9.0.2"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.2.tgz#ede1d1b1e451548d44919dc226253e32a6952c4b"
integrity sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==
"@types/webxr@*": "@types/webxr@*":
version "0.5.0" version "0.5.0"
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.0.tgz#aae1cef3210d88fd4204f8c33385a0bbc4da07c9" resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.0.tgz#aae1cef3210d88fd4204f8c33385a0bbc4da07c9"