pull/3282/head
Steve Ruiz 2024-05-04 13:34:04 +01:00
rodzic 4342b93844
commit af263423ed
2 zmienionych plików z 14 dodań i 69 usunięć

Wyświetl plik

@ -1,16 +1,15 @@
import { useCallback, useEffect, useMemo } from 'react'
import {
Box,
DEFAULT_CAMERA_OPTIONS,
PORTRAIT_BREAKPOINT,
SVGContainer,
TLImageShape,
TLShapeId,
TLShapePartial,
Tldraw,
clamp,
compact,
getIndicesBetween,
react,
sortByIndex,
track,
useBreakpoint,
@ -132,78 +131,25 @@ function ConstrainCamera({ pdf }: { pdf: Pdf }) {
const isMobile = breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM
useEffect(() => {
const marginTop = 64
const marginSide = isMobile ? 16 : 164
const marginBottom = 80
const targetBounds = pdf.pages.reduce(
(acc, page) => acc.union(page.bounds),
pdf.pages[0].bounds.clone()
)
function constrainCamera(camera: { x: number; y: number; z: number }): {
x: number
y: number
z: number
} {
const viewportBounds = editor.getViewportScreenBounds()
const usableViewport = new Box(
marginSide,
marginTop,
viewportBounds.w - marginSide * 2,
viewportBounds.h - marginTop - marginBottom
)
const minZoom = Math.min(
usableViewport.w / targetBounds.w,
usableViewport.h / targetBounds.h,
1
)
const zoom = Math.max(minZoom, camera.z)
const centerX = targetBounds.x - targetBounds.w / 2 + usableViewport.midX / zoom
const centerY = targetBounds.y - targetBounds.h / 2 + usableViewport.midY / zoom
const availableXMovement = Math.max(0, targetBounds.w - usableViewport.w / zoom)
const availableYMovement = Math.max(0, targetBounds.h - usableViewport.h / zoom)
return {
x: clamp(camera.x, centerX - availableXMovement / 2, centerX + availableXMovement / 2),
y: clamp(camera.y, centerY - availableYMovement / 2, centerY + availableYMovement / 2),
z: zoom,
}
}
const removeOnChange = editor.sideEffects.registerBeforeChangeHandler(
'camera',
(_prev, next) => {
const constrained = constrainCamera(next)
if (constrained.x === next.x && constrained.y === next.y && constrained.z === next.z)
return next
return { ...next, ...constrained }
}
editor.setCameraOptions(
{
...DEFAULT_CAMERA_OPTIONS,
constraints: {
bounds: targetBounds,
padding: { x: isMobile ? 16 : 164, y: 64 },
origin: { x: 0.5, y: 0 },
initialZoom: 'fit-x',
baseZoom: 'default',
behavior: 'contain',
},
},
{ reset: true }
)
const removeReaction = react('update camera when viewport/shape changes', () => {
const original = editor.getCamera()
const constrained = constrainCamera(original)
if (
original.x === constrained.x &&
original.y === constrained.y &&
original.z === constrained.z
) {
return
}
// this needs to be in a microtask for some reason, but idk why
queueMicrotask(() => editor.setCamera(constrained))
})
return () => {
removeOnChange()
removeReaction()
}
}, [editor, isMobile, pdf.pages])
return null

Wyświetl plik

@ -2170,7 +2170,6 @@ export class Editor extends EventEmitter<TLEventMap> {
if (cameraOptions.constraints) {
const { constraints } = cameraOptions
// Get padding (it's either a number or an array of 2 numbers for t/b, l/r)
// Clamp padding to half the viewport size on either dimension
const py = Math.min(constraints.padding.y, vsb.w / 2)
const px = Math.min(constraints.padding.x, vsb.h / 2)