vieport fix
This commit is contained in:
@@ -32,7 +32,6 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/component
|
|||||||
import { Sparkles, ZoomIn, ZoomOut, RotateCcw, RotateCw, Copy, Play, ChevronDown, Loader2 } from 'lucide-react'
|
import { Sparkles, ZoomIn, ZoomOut, RotateCcw, RotateCw, Copy, Play, ChevronDown, Loader2 } from 'lucide-react'
|
||||||
import { InputHandle } from '@/components/graph/NodeHandles'
|
import { InputHandle } from '@/components/graph/NodeHandles'
|
||||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
||||||
import { Input } from '@/components/ui/input'
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { ButtonGroup } from '@/components/ui/button-group'
|
import { ButtonGroup } from '@/components/ui/button-group'
|
||||||
import {
|
import {
|
||||||
@@ -556,18 +555,6 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
|
|
||||||
const status = loading ? 'loading' : error ? 'error' : renderedContent ? 'success' : 'initial'
|
const status = loading ? 'loading' : error ? 'error' : renderedContent ? 'success' : 'initial'
|
||||||
|
|
||||||
const [viewportDraft, setViewportDraft] = useState({ width: viewportWidth, height: viewportHeight })
|
|
||||||
useEffect(() => {
|
|
||||||
setViewportDraft({ width: viewportWidth, height: viewportHeight })
|
|
||||||
}, [viewportWidth, viewportHeight])
|
|
||||||
|
|
||||||
const onViewportDraftChange = useCallback((field: 'width' | 'height', value: number) => {
|
|
||||||
setViewportDraft((prev) => ({ ...prev, [field]: Math.min(4000, Math.max(200, value)) }))
|
|
||||||
}, [])
|
|
||||||
const onViewportApply = useCallback(() => {
|
|
||||||
updateData({ viewportWidth: viewportDraft.width, viewportHeight: viewportDraft.height })
|
|
||||||
}, [updateData, viewportDraft.width, viewportDraft.height])
|
|
||||||
|
|
||||||
const { theme } = useTheme()
|
const { theme } = useTheme()
|
||||||
const [rawEditorHeight, rawEditorContainerRef] = useResizeHeight(180, [viewMode])
|
const [rawEditorHeight, rawEditorContainerRef] = useResizeHeight(180, [viewMode])
|
||||||
const rawExtensions = useMemo(() => {
|
const rawExtensions = useMemo(() => {
|
||||||
@@ -685,51 +672,6 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
>
|
>
|
||||||
Raw
|
Raw
|
||||||
</MenubarCheckboxItem>
|
</MenubarCheckboxItem>
|
||||||
{outputType === 'image' && (
|
|
||||||
<MenubarSub>
|
|
||||||
<MenubarSeparator />
|
|
||||||
<MenubarSubTrigger className="text-xs">Viewport size</MenubarSubTrigger>
|
|
||||||
<MenubarSubContent className="min-w-[12rem] p-2">
|
|
||||||
<div className="grid gap-2">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<label className="text-xs text-muted-foreground shrink-0">Width</label>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={200}
|
|
||||||
max={4000}
|
|
||||||
value={viewportDraft.width}
|
|
||||||
onChange={(e) => {
|
|
||||||
const v = parseInt(e.target.value, 10)
|
|
||||||
if (!Number.isNaN(v)) onViewportDraftChange('width', v)
|
|
||||||
}}
|
|
||||||
className="h-7 text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<label className="text-xs text-muted-foreground shrink-0">Height</label>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={200}
|
|
||||||
max={4000}
|
|
||||||
value={viewportDraft.height}
|
|
||||||
onChange={(e) => {
|
|
||||||
const v = parseInt(e.target.value, 10)
|
|
||||||
if (!Number.isNaN(v)) onViewportDraftChange('height', v)
|
|
||||||
}}
|
|
||||||
className="h-7 text-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={onViewportApply}
|
|
||||||
className="mt-1 w-full rounded bg-primary px-2 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90"
|
|
||||||
>
|
|
||||||
Apply
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</MenubarSubContent>
|
|
||||||
</MenubarSub>
|
|
||||||
)}
|
|
||||||
<MenubarSeparator />
|
<MenubarSeparator />
|
||||||
<MenubarSub>
|
<MenubarSub>
|
||||||
<MenubarSubTrigger className="text-xs" disabled={!isSvgOutput}>
|
<MenubarSubTrigger className="text-xs" disabled={!isSvgOutput}>
|
||||||
@@ -846,28 +788,7 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
initialPositionY={0}
|
initialPositionY={0}
|
||||||
minScale={0.2}
|
minScale={0.2}
|
||||||
maxScale={4}
|
maxScale={4}
|
||||||
centerOnInit={true}
|
centerOnInit={false}
|
||||||
onInit={(ctx) => {
|
|
||||||
if (!ctx?.instance?.wrapperComponent || !ctx?.instance?.contentComponent) return
|
|
||||||
const fitToView = () => {
|
|
||||||
const wrapper = ctx.instance.wrapperComponent
|
|
||||||
const content = ctx.instance.contentComponent
|
|
||||||
if (!wrapper || !content) return
|
|
||||||
const wW = wrapper.clientWidth
|
|
||||||
const wH = wrapper.clientHeight
|
|
||||||
const cW = content.scrollWidth || content.clientWidth
|
|
||||||
const cH = content.scrollHeight || content.clientHeight
|
|
||||||
if (cW > 0 && cH > 0) {
|
|
||||||
const scale = Math.min(wW / cW, wH / cH, 1)
|
|
||||||
const posX = (wW - cW * scale) / 2
|
|
||||||
const posY = (wH - cH * scale) / 2
|
|
||||||
ctx.setTransform(posX, posY, scale, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
requestAnimationFrame(fitToView)
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
panning={{ disabled: !selected && !viewportFocused }}
|
panning={{ disabled: !selected && !viewportFocused }}
|
||||||
wheel={{ disabled: !selected && !viewportFocused }}
|
wheel={{ disabled: !selected && !viewportFocused }}
|
||||||
doubleClick={{ disabled: !selected && !viewportFocused }}
|
doubleClick={{ disabled: !selected && !viewportFocused }}
|
||||||
@@ -900,13 +821,13 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
<RotateCcw className="size-3 max-w-[12px] max-h-[12px]" />
|
<RotateCcw className="size-3 max-w-[12px] max-h-[12px]" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute inset-0 nodrag nopan overflow-hidden flex flex-col">
|
<div className="absolute inset-0 nodrag nopan overflow-hidden [&_.react-transform-component]:!w-full [&_.react-transform-component]:!h-full [&_.react-transform-wrapper]:!w-full [&_.react-transform-wrapper]:!h-full">
|
||||||
<TransformComponent
|
<TransformComponent
|
||||||
wrapperClass="!w-full !h-full"
|
wrapperClass="!w-full !h-full"
|
||||||
contentClass="inline-flex flex-col nodrag nopan !w-full !min-h-0 !flex-1"
|
contentClass="nodrag nopan !w-full !h-full !block !min-h-0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="rendering-diagram inline-flex w-full min-h-0 flex-1 p-4 nodrag nopan"
|
className="rendering-diagram absolute inset-0 w-full h-full min-w-0 min-h-0 nodrag nopan"
|
||||||
dangerouslySetInnerHTML={{ __html: displayContent ?? '' }}
|
dangerouslySetInnerHTML={{ __html: displayContent ?? '' }}
|
||||||
/>
|
/>
|
||||||
</TransformComponent>
|
</TransformComponent>
|
||||||
|
|||||||
Reference in New Issue
Block a user