11import * as React from "react" ;
2- import { useCallback , useLayoutEffect , useState , useEffect , useMemo } from "react" ;
2+ import { useCallback , useLayoutEffect , useRef , useState , useEffect , useMemo } from "react" ;
33import {
44 PanelExtensionContext ,
55 SettingsTree ,
@@ -126,6 +126,7 @@ const CraneVisualizer: React.FC<{ context: PanelExtensionContext }> = ({ context
126126 // 時間軸管理
127127 const [ seekTime , setSeekTime ] = useState < number | undefined > ( ) ;
128128 const [ currentDisplayMsg , setCurrentDisplayMsg ] = useState < SvgLayerArray | undefined > ( ) ;
129+ const svgRef = useRef < SVGSVGElement > ( null ) ;
129130
130131 const resetViewBox = useCallback ( ( ) => {
131132 const x = - config . viewBoxWidth / 2 ;
@@ -603,6 +604,7 @@ const CraneVisualizer: React.FC<{ context: PanelExtensionContext }> = ({ context
603604 { seekTime !== undefined && < p > Seek Time: { new Date ( seekTime ) . toISOString ( ) } </ p > }
604605 </ div >
605606 < svg
607+ ref = { svgRef }
606608 width = "100%"
607609 height = "100%"
608610 viewBox = { viewBox }
@@ -611,11 +613,14 @@ const CraneVisualizer: React.FC<{ context: PanelExtensionContext }> = ({ context
611613 const startX = e . clientX ;
612614 const startY = e . clientY ;
613615 const [ x , y , width , height ] = viewBox . split ( " " ) . map ( Number ) ;
616+ const rect = svgRef . current ?. getBoundingClientRect ( ) ;
617+ const svgPixelWidth = rect ?. width ?? width ;
618+ const svgPixelHeight = rect ?. height ?? height ;
614619 const handleMouseMove = ( e : MouseEvent ) => {
615620 const dx = e . clientX - startX ;
616621 const dy = e . clientY - startY ;
617- const scaledDx = dx * width / 400 ;
618- const scaledDy = dy * height / 400 ;
622+ const scaledDx = dx * ( width / svgPixelWidth ) ;
623+ const scaledDy = dy * ( height / svgPixelHeight ) ;
619624 setViewBox ( `${ x - scaledDx } ${ y - scaledDy } ${ width } ${ height } ` ) ;
620625 } ;
621626 const handleMouseUp = ( ) => {
0 commit comments