diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/component.jsx index 106a6f75b8..df411e4eaf 100644 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/component.jsx @@ -2,7 +2,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; import { TldrawApp, Tldraw } from '@tldraw/tldraw'; -import SlideCalcUtil, { HUNDRED_PERCENT } from '/imports/utils/slideCalcUtils'; +import SlideCalcUtil, { HUNDRED_PERCENT, MAX_PERCENT } from '/imports/utils/slideCalcUtils'; // eslint-disable-next-line import/no-extraneous-dependencies import { Utils } from '@tldraw/core'; import Cursors from './cursors/container'; @@ -92,11 +92,13 @@ export default function Whiteboard(props) { const [history, setHistory] = React.useState(null); const [zoom, setZoom] = React.useState(HUNDRED_PERCENT); const [tldrawZoom, setTldrawZoom] = React.useState(1); + const zoomValueRef = React.useRef(zoomValue); const [isMounting, setIsMounting] = React.useState(true); const prevShapes = usePrevious(shapes); const prevSlidePosition = usePrevious(slidePosition); const prevFitToWidth = usePrevious(fitToWidth); const prevSvgUri = usePrevious(svgUri); + const prevPageId = usePrevious(curPageId); const language = mapLanguage(Settings?.application?.locale?.toLowerCase() || 'en'); const [currentTool, setCurrentTool] = React.useState(null); const [currentStyle, setCurrentStyle] = React.useState({}); @@ -114,6 +116,10 @@ export default function Whiteboard(props) { }; }, []); + React.useEffect(() => { + zoomValueRef.current = zoomValue; + }, [zoomValue]); + const setSafeTLDrawAPI = (api) => { if (isMountedRef.current) { setTldrawAPI(api); @@ -208,8 +214,16 @@ export default function Whiteboard(props) { tldrawAPI?.completeSession?.(); } }; - + const handleWheelEvent = (event) => { + if ((zoomValueRef.current >= MAX_PERCENT && event.deltaY < 0) + || (zoomValueRef.current <= HUNDRED_PERCENT && event.deltaY > 0)) + { + event.stopPropagation(); + event.preventDefault(); + return window.dispatchEvent(new Event('resize')); + } + if (!event.ctrlKey) { // Prevent the event from reaching the tldraw library event.stopPropagation(); @@ -450,6 +464,19 @@ export default function Whiteboard(props) { const newZoom = calculateZoom(slidePosition.viewBoxWidth, slidePosition.viewBoxHeight); tldrawAPI?.setCamera([slidePosition.x, slidePosition.y], newZoom, 'zoomed'); } + + const camera = tldrawAPI?.getPageState()?.camera; + if (isPresenter && slidePosition && camera) { + const zoomFitSlide = calculateZoom(slidePosition.width, slidePosition.height); + const zoomCamera = (zoomFitSlide * zoomValue) / HUNDRED_PERCENT; + let zoomToolbar = Math.round( + ((HUNDRED_PERCENT * camera.zoom) / zoomFitSlide) * 100, + ) / 100; + if ((zoom !== zoomToolbar) && (curPageId && curPageId !== prevPageId)) { + setZoom(zoomToolbar); + zoomChanger(zoomToolbar); + } + } }, [curPageId, slidePosition]); // update zoom according to toolbar @@ -750,11 +777,6 @@ export default function Whiteboard(props) { camera.point[1] = 0; } - if (camera.point[0] === 0 && camera.point[1] === 0) { - const newZoom = calculateZoom(slidePosition.viewBoxWidth, slidePosition.viewBoxHeight); - e?.setCamera([camera.point[0], camera.point[1]], newZoom); - } - const zoomFitSlide = calculateZoom(slidePosition.width, slidePosition.height); if (camera.zoom < zoomFitSlide) { camera.zoom = zoomFitSlide;