Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
9d084b63
authored
Jun 26, 2024
by
江晚
Committed by
GitHub
Jun 26, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
实现在移动端,点击AI回答的图片后,可以通过双指放大缩小移动图片的功能 (#1857)
parent
4b4bea19
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
178 additions
and
2 deletions
+178
-2
projects/app/src/components/Markdown/img/Image.tsx
+178
-2
No files found.
projects/app/src/components/Markdown/img/Image.tsx
View file @
9d084b63
import
React
,
{
WheelEventHandler
,
useState
}
from
'react'
;
import
React
,
{
WheelEventHandler
,
useState
,
MouseEventHandler
,
TouchEventHandler
,
useRef
}
from
'react'
;
import
{
import
{
Box
,
Box
,
Image
,
Image
,
...
@@ -11,11 +11,32 @@ import {
...
@@ -11,11 +11,32 @@ import {
}
from
'@chakra-ui/react'
;
}
from
'@chakra-ui/react'
;
const
MdImage
=
({
src
}:
{
src
?:
string
})
=>
{
const
MdImage
=
({
src
}:
{
src
?:
string
})
=>
{
const
imgRef
=
useRef
<
HTMLImageElement
>
(
null
);
const
[
isLoading
,
setIsLoading
]
=
useState
(
true
);
const
[
isLoading
,
setIsLoading
]
=
useState
(
true
);
const
[
succeed
,
setSucceed
]
=
useState
(
false
);
const
[
succeed
,
setSucceed
]
=
useState
(
false
);
const
{
isOpen
,
onOpen
,
onClose
}
=
useDisclosure
();
const
{
isOpen
,
onOpen
,
onClose
}
=
useDisclosure
();
const
[
scale
,
setScale
]
=
useState
(
1
);
const
[
scale
,
setScale
]
=
useState
(
1
);
const
[
positionLeft
,
setPositionLeft
]
=
useState
(
0
)
const
[
positionTop
,
setPositionTop
]
=
useState
(
0
)
const
[
store
]
=
useState
({
scale
:
1
,
moveable
:
false
,
pageX
:
0
,
pageY
:
0
,
pageX2
:
0
,
pageY2
:
0
,
originScale
:
1
})
// 自定义Modal关闭事件
const
customOnClose
=
():
void
=>
{
setPositionLeft
(
0
)
setPositionTop
(
0
)
setScale
(
1
)
onClose
()
}
const
handleWheel
:
WheelEventHandler
<
HTMLImageElement
>
=
(
e
)
=>
{
const
handleWheel
:
WheelEventHandler
<
HTMLImageElement
>
=
(
e
)
=>
{
setScale
((
prevScale
)
=>
{
setScale
((
prevScale
)
=>
{
const
newScale
=
prevScale
+
e
.
deltaY
*
0.5
*
-
0.01
;
const
newScale
=
prevScale
+
e
.
deltaY
*
0.5
*
-
0.01
;
...
@@ -25,6 +46,153 @@ const MdImage = ({ src }: { src?: string }) => {
...
@@ -25,6 +46,153 @@ const MdImage = ({ src }: { src?: string }) => {
});
});
};
};
const
handleTouchStart
:
TouchEventHandler
<
HTMLImageElement
>
=
(
event
)
=>
{
let
touches
=
event
.
touches
;
let
events
=
touches
[
0
];
//单指
let
events2
=
touches
[
1
];
//双指
if
(
touches
.
length
==
1
)
{
// 单指操作
store
.
pageX
=
events
.
pageX
store
.
pageY
=
events
.
pageY
store
.
moveable
=
true
;
}
else
{
// 第一个触摸点的坐标
store
.
pageX
=
events
.
pageX
;
store
.
pageY
=
events
.
pageY
;
store
.
moveable
=
true
;
if
(
events2
)
{
store
.
pageX2
=
events2
.
pageX
;
store
.
pageY2
=
events2
.
pageY
;
}
store
.
originScale
=
store
.
scale
||
1
;
}
}
const
handleTouchMove
:
TouchEventHandler
<
HTMLImageElement
>
=
(
event
)
=>
{
if
(
!
store
.
moveable
)
{
return
;
}
let
touches
=
event
.
touches
;
let
events
=
touches
[
0
];
let
events2
=
touches
[
1
];
//最大移动距离
let
moveMaxWith
=
(
Number
(
imgRef
.
current
?.
width
)
*
scale
-
window
.
innerWidth
)
/
2
;
let
moveMaxHeight
=
(
Number
(
imgRef
.
current
?.
height
)
*
scale
-
window
.
innerHeight
)
/
2
;
if
(
touches
.
length
==
1
)
{
//未放大,不移动图片
if
(
scale
<=
1
)
return
;
let
pageX
=
store
.
pageX
;
let
pageY
=
store
.
pageY
let
pageX2
=
events
.
pageX
;
let
pageY2
=
events
.
pageY
;
let
newLeft
=
positionLeft
+
pageX2
/
20
-
pageX
/
20
;
let
newTop
=
positionTop
+
pageY2
/
20
-
pageY
/
20
;
if
(
Math
.
abs
(
newLeft
)
>
moveMaxWith
)
{
if
(
newLeft
>
0
)
{
newLeft
=
moveMaxWith
;
}
else
{
newLeft
=
0
-
moveMaxWith
;
}
}
// 放大倍数没超过屏高
if
(
moveMaxHeight
<
0
)
{
newTop
=
0
;
}
else
if
(
Math
.
abs
(
newTop
)
>
moveMaxHeight
)
{
if
(
newTop
>
0
)
{
newTop
=
moveMaxHeight
;
}
else
{
newTop
=
0
-
moveMaxHeight
;
}
}
//控制图片移动
setPositionLeft
(
newLeft
)
setPositionTop
(
newTop
)
}
else
{
// 双指移动
if
(
events2
)
{
// 第2个指头坐标在touchmove时候获取
store
.
pageX2
=
events2
.
pageX
;
store
.
pageY2
=
events2
.
pageY
;
// 获取坐标之间的距离
let
getDistance
=
function
(
start
:
any
,
stop
:
any
)
{
//用到三角函数
return
Math
.
hypot
(
stop
.
x
-
start
.
x
,
stop
.
y
-
start
.
y
);
};
// 双指缩放比例计算
let
zoom
=
getDistance
({
x
:
events
.
pageX
,
y
:
events
.
pageY
},
{
x
:
events2
.
pageX
,
y
:
events2
.
pageY
})
/
getDistance
({
x
:
store
.
pageX
,
y
:
store
.
pageY
},
{
x
:
store
.
pageX2
,
y
:
store
.
pageY2
});
// 应用在元素上的缩放比例
let
newScale
=
store
.
originScale
*
zoom
;
// 缩放比例限制
if
(
newScale
>
10
)
{
newScale
=
10
;
}
if
(
newScale
<=
1
)
{
newScale
=
1
;
}
store
.
scale
=
newScale
;
// 图像应用缩放效果
setScale
(
newScale
);
// 如果是缩小图片,则限制移动的距离
if
(
Math
.
abs
(
positionLeft
)
>
moveMaxWith
)
{
if
(
positionLeft
>
0
)
{
setPositionLeft
(
moveMaxWith
);
}
else
{
setPositionLeft
(
0
-
moveMaxWith
);
}
}
if
(
moveMaxHeight
<
0
)
{
setPositionTop
(
0
);
}
else
if
(
Math
.
abs
(
positionTop
)
>
moveMaxHeight
)
{
if
(
positionTop
>
0
)
{
setPositionTop
(
moveMaxHeight
);
}
else
{
setPositionTop
(
0
-
moveMaxHeight
);
}
}
}
}
}
const
handleTouchEnd
:
TouchEventHandler
<
HTMLImageElement
>
=
(
e
)
=>
{
store
.
moveable
=
false
;
store
.
pageX2
=
0
;
store
.
pageY2
=
0
;
}
const
handleTouchCancel
:
TouchEventHandler
<
HTMLImageElement
>
=
(
e
)
=>
{
store
.
moveable
=
false
;
store
.
pageX2
=
0
;
store
.
pageY2
=
0
;
}
return
(
return
(
<>
<>
<
Image
<
Image
...
@@ -50,10 +218,11 @@ const MdImage = ({ src }: { src?: string }) => {
...
@@ -50,10 +218,11 @@ const MdImage = ({ src }: { src?: string }) => {
onOpen
();
onOpen
();
}
}
}
}
/>
/>
<
Modal
isOpen=
{
isOpen
}
onClose=
{
o
nClose
}
isCentered
>
<
Modal
isOpen=
{
isOpen
}
onClose=
{
customO
nClose
}
isCentered
>
<
ModalOverlay
/>
<
ModalOverlay
/>
<
ModalContent
boxShadow=
{
'none'
}
maxW=
{
'auto'
}
w=
"auto"
bg=
{
'transparent'
}
>
<
ModalContent
boxShadow=
{
'none'
}
maxW=
{
'auto'
}
w=
"auto"
bg=
{
'transparent'
}
>
<
Image
<
Image
ref=
{
imgRef
}
transform=
{
`scale(${scale})`
}
transform=
{
`scale(${scale})`
}
borderRadius=
{
'md'
}
borderRadius=
{
'md'
}
src=
{
src
}
src=
{
src
}
...
@@ -64,7 +233,14 @@ const MdImage = ({ src }: { src?: string }) => {
...
@@ -64,7 +233,14 @@ const MdImage = ({ src }: { src?: string }) => {
fallbackSrc=
{
'/imgs/errImg.png'
}
fallbackSrc=
{
'/imgs/errImg.png'
}
fallbackStrategy=
{
'onError'
}
fallbackStrategy=
{
'onError'
}
objectFit=
{
'contain'
}
objectFit=
{
'contain'
}
position=
{
'relative'
}
top=
{
positionTop
+
'px'
}
left=
{
positionLeft
+
"px"
}
onWheel=
{
handleWheel
}
onWheel=
{
handleWheel
}
onTouchStart=
{
handleTouchStart
}
onTouchMove=
{
handleTouchMove
}
onTouchEnd=
{
handleTouchEnd
}
onTouchCancel=
{
handleTouchCancel
}
/>
/>
</
ModalContent
>
</
ModalContent
>
<
ModalCloseButton
bg=
{
'myWhite.500'
}
zIndex=
{
999999
}
/>
<
ModalCloseButton
bg=
{
'myWhite.500'
}
zIndex=
{
999999
}
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment