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
className="thumb-img"
style={{
...thumImgWrapStyle
}}
style={{ ...thumImgWrapStyle }}
ref={imgWrapper}
>
<>
@@ -158,10 +156,11 @@ const SingleImage: React.FC<SingleImageProps> = (props) => {
}}
>
<AutoImage
style={{ objectFit: 'cover' }}
preview={preview}
autoSize={autoSize}
src={dataUrl}
width={imgSize.width || 100}
width={imgSize.width || '100%'}
height={imgSize.height || 100}
onLoad={handleOnLoad}
/>
@@ -1,5 +1,6 @@
.markdown-viewer {
font-family: var(--font-family) !important;
word-wrap: break-word;
.hr {
border: none;
@@ -311,7 +311,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
);
const renderDistributionInfo = useCallback(
(severList: any[], label: string) => {
(severList: any[]) => {
if (!severList.length) {
return null;
}
@@ -340,7 +340,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
>
<InfoCircleOutlined className="m-r-5" />
{intl.formatMessage({
id: label
id: 'models.table.acrossworker'
})}
</Tag>
</Tooltip>
@@ -468,12 +468,10 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
>
{renderOffloadInfo}
{renderDistributionInfo(
instanceData.distributed_servers?.rpc_servers || [],
'models.table.llamaAcrossworker'
instanceData.distributed_servers?.rpc_servers || []
)}
{renderDistributionInfo(
instanceData.distributed_servers?.ray_actors || [],
'models.table.vllmAcrossworker'
instanceData.distributed_servers?.ray_actors || []
)}
</span>
</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;