Implement zoom for mousewheel event on stream (#238)
This commit is contained in:
@ -15,7 +15,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root" class="h-screen overflow-y-auto"></div>
|
||||||
<script type="module" src="/src/index.tsx"></script>
|
<script type="module" src="/src/index.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -20,7 +20,7 @@ export const AppHeader = ({
|
|||||||
return (
|
return (
|
||||||
<header
|
<header
|
||||||
className={
|
className={
|
||||||
'overlaid-panes z-10 py-1 px-5 bg-chalkboard-10/50 dark:bg-chalkboard-100/50 border-b dark:border-b-2 border-chalkboard-30 dark:border-chalkboard-90 flex justify-between items-center ' +
|
'overlaid-panes sticky top-0 z-10 py-1 px-5 bg-chalkboard-10/50 dark:bg-chalkboard-100/50 border-b dark:border-b-2 border-chalkboard-30 dark:border-chalkboard-90 flex justify-between items-center ' +
|
||||||
className
|
className
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
import { MouseEventHandler, useEffect, useRef } from 'react'
|
import {
|
||||||
|
MouseEventHandler,
|
||||||
|
WheelEventHandler,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { useStore } from '../useStore'
|
import { useStore } from '../useStore'
|
||||||
|
import { throttle } from '../lib/utils'
|
||||||
|
import { EngineCommand } from '../lang/std/engineConnection'
|
||||||
|
|
||||||
export const Stream = ({ className = '' }) => {
|
export const Stream = ({ className = '' }) => {
|
||||||
|
const [zoom, setZoom] = useState(0)
|
||||||
const videoRef = useRef<HTMLVideoElement>(null)
|
const videoRef = useRef<HTMLVideoElement>(null)
|
||||||
const {
|
const {
|
||||||
mediaStream,
|
mediaStream,
|
||||||
@ -31,6 +40,7 @@ export const Stream = ({ className = '' }) => {
|
|||||||
if (!mediaStream) return
|
if (!mediaStream) return
|
||||||
videoRef.current.srcObject = mediaStream
|
videoRef.current.srcObject = mediaStream
|
||||||
setFileId(uuidv4())
|
setFileId(uuidv4())
|
||||||
|
setZoom(videoRef.current.getBoundingClientRect().height / 2)
|
||||||
}, [mediaStream, engineCommandManager, setFileId])
|
}, [mediaStream, engineCommandManager, setFileId])
|
||||||
|
|
||||||
const handleMouseDown: MouseEventHandler<HTMLVideoElement> = ({
|
const handleMouseDown: MouseEventHandler<HTMLVideoElement> = ({
|
||||||
@ -63,6 +73,27 @@ export const Stream = ({ className = '' }) => {
|
|||||||
setIsMouseDownInStream(true)
|
setIsMouseDownInStream(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: consolidate this with the same function in App.tsx
|
||||||
|
const debounceSocketSend = throttle<EngineCommand>((message) => {
|
||||||
|
engineCommandManager?.sendSceneCommand(message)
|
||||||
|
}, 16)
|
||||||
|
|
||||||
|
const handleScroll: WheelEventHandler<HTMLVideoElement> = (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
debounceSocketSend({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd: {
|
||||||
|
type: 'camera_drag_move',
|
||||||
|
interaction: 'zoom',
|
||||||
|
window: { x: 0, y: zoom + e.deltaY },
|
||||||
|
},
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
file_id: uuidv4(),
|
||||||
|
})
|
||||||
|
|
||||||
|
setZoom(zoom + e.deltaY)
|
||||||
|
}
|
||||||
|
|
||||||
const handleMouseUp: MouseEventHandler<HTMLVideoElement> = ({
|
const handleMouseUp: MouseEventHandler<HTMLVideoElement> = ({
|
||||||
clientX,
|
clientX,
|
||||||
clientY,
|
clientY,
|
||||||
@ -105,6 +136,7 @@ export const Stream = ({ className = '' }) => {
|
|||||||
onMouseUp={handleMouseUp}
|
onMouseUp={handleMouseUp}
|
||||||
onContextMenu={(e) => e.preventDefault()}
|
onContextMenu={(e) => e.preventDefault()}
|
||||||
onContextMenuCapture={(e) => e.preventDefault()}
|
onContextMenuCapture={(e) => e.preventDefault()}
|
||||||
|
onWheelCapture={handleScroll}
|
||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,6 +12,7 @@ body {
|
|||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
@apply text-chalkboard-110 bg-chalkboard-10;
|
@apply text-chalkboard-110 bg-chalkboard-10;
|
||||||
|
overflow: hidden;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: var(--color-chalkboard-20) var(--color-chalkboard-40);
|
scrollbar-color: var(--color-chalkboard-20) var(--color-chalkboard-40);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ export const Settings = () => {
|
|||||||
Close
|
Close
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
</AppHeader>
|
</AppHeader>
|
||||||
<div className="mt-16 max-w-3xl mx-auto">
|
<div className="my-24 max-w-5xl mx-auto">
|
||||||
<h1 className="text-4xl font-bold">User Settings</h1>
|
<h1 className="text-4xl font-bold">User Settings</h1>
|
||||||
{(window as any).__TAURI__ && (
|
{(window as any).__TAURI__ && (
|
||||||
<SettingsSection
|
<SettingsSection
|
||||||
|
Reference in New Issue
Block a user