fix: image viewer flick

This commit is contained in:
jialin
2025-03-10 17:11:32 +08:00
parent 12707793b1
commit c0988da176
4 changed files with 82 additions and 10 deletions
+3 -4
View File
@@ -115,9 +115,7 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
)} )}
<span <span
className="thumb-img" className="thumb-img"
style={{ style={{ ...thumImgWrapStyle }}
...thumImgWrapStyle
}}
ref={imgWrapper} ref={imgWrapper}
> >
<> <>
@@ -158,10 +156,11 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
}} }}
> >
<AutoImage <AutoImage
style={{ objectFit: 'cover' }}
preview={preview} preview={preview}
autoSize={autoSize} autoSize={autoSize}
src={dataUrl} src={dataUrl}
width={imgSize.width || 100} width={imgSize.width || '100%'}
height={imgSize.height || 100} height={imgSize.height || 100}
onLoad={handleOnLoad} onLoad={handleOnLoad}
/> />
@@ -1,5 +1,6 @@
.markdown-viewer { .markdown-viewer {
font-family: var(--font-family) !important; font-family: var(--font-family) !important;
word-wrap: break-word;
.hr { .hr {
border: none; border: none;
@@ -311,7 +311,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
); );
const renderDistributionInfo = useCallback( const renderDistributionInfo = useCallback(
(severList: any[], label: string) => { (severList: any[]) => {
if (!severList.length) { if (!severList.length) {
return null; return null;
} }
@@ -340,7 +340,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
> >
<InfoCircleOutlined className="m-r-5" /> <InfoCircleOutlined className="m-r-5" />
{intl.formatMessage({ {intl.formatMessage({
id: label id: 'models.table.acrossworker'
})} })}
</Tag> </Tag>
</Tooltip> </Tooltip>
@@ -468,12 +468,10 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
> >
{renderOffloadInfo} {renderOffloadInfo}
{renderDistributionInfo( {renderDistributionInfo(
instanceData.distributed_servers?.rpc_servers || [], instanceData.distributed_servers?.rpc_servers || []
'models.table.llamaAcrossworker'
)} )}
{renderDistributionInfo( {renderDistributionInfo(
instanceData.distributed_servers?.ray_actors || [], instanceData.distributed_servers?.ray_actors || []
'models.table.vllmAcrossworker'
)} )}
</span> </span>
</Col> </Col>
@@ -0,0 +1,74 @@
import { useEffect, useRef, useState } from 'react';
const ImageCanvas = ({ imageUrl }) => {
const canvasRef = useRef(null);
const [scale, setScale] = useState(1);
const [offset, setOffset] = useState({ x: 0, y: 0 });
const [image, setImage] = useState(null);
const requestRef = useRef();
// 加载图片
useEffect(() => {
const img = new Image();
img.src = imageUrl;
img.onload = () => {
setImage(img);
};
}, [imageUrl]);
// 绘制图片
const drawImage = () => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (image) {
ctx.save();
ctx.translate(offset.x, offset.y);
ctx.scale(scale, scale);
ctx.drawImage(image, 0, 0);
ctx.restore();
}
// 请求下一帧绘制
requestRef.current = requestAnimationFrame(drawImage);
};
// 启动动画循环
useEffect(() => {
requestRef.current = requestAnimationFrame(drawImage);
return () => cancelAnimationFrame(requestRef.current);
}, [image, scale, offset]);
// 处理滚轮事件
const handleWheel = (event) => {
event.preventDefault();
const { deltaY, clientX, clientY } = event;
const canvas = canvasRef.current;
const rect = canvas.getBoundingClientRect();
const mouseX = clientX - rect.left;
const mouseY = clientY - rect.top;
const zoomFactor = deltaY > 0 ? 0.9 : 1.1; // 缩小或放大
const newScale = scale * zoomFactor;
// 计算新的偏移量,确保以鼠标位置为中心缩放
const newOffsetX = mouseX - (mouseX - offset.x) * zoomFactor;
const newOffsetY = mouseY - (mouseY - offset.y) * zoomFactor;
setScale(newScale);
setOffset({ x: newOffsetX, y: newOffsetY });
};
return (
<canvas
ref={canvasRef}
width={800}
height={600}
onWheel={handleWheel}
style={{ border: '1px solid black' }}
/>
);
};
export default ImageCanvas;