1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Use native view drawing instead of svg

This commit is contained in:
xmflsct
2022-08-19 01:58:17 +02:00
parent 244eda3d12
commit 9ed6343eb7
7 changed files with 116 additions and 231 deletions

View File

@@ -5,16 +5,14 @@ import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { Dimensions, Image, View } from 'react-native'
import { PanGestureHandler } from 'react-native-gesture-handler'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import Animated, {
Extrapolate,
interpolate,
runOnJS,
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue
} from 'react-native-reanimated'
import Svg, { Circle, G, Path } from 'react-native-svg'
import ComposeContext from '../utils/createContext'
export interface Props {
@@ -30,30 +28,19 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
const theAttachmentRemote = composeState.attachments.uploads[index].remote!
const theAttachmentLocal = composeState.attachments.uploads[index].local
const windowWidth = Dimensions.get('window').width
const imageWidthBase =
theAttachmentRemote?.meta?.original?.aspect < 1
? Dimensions.get('screen').width *
theAttachmentRemote?.meta?.original?.aspect
: Dimensions.get('screen').width
const padding = (Dimensions.get('screen').width - imageWidthBase) / 2
? windowWidth * theAttachmentRemote?.meta?.original?.aspect
: windowWidth
const imageDimensionis = {
width: imageWidthBase,
height:
imageWidthBase /
((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.original
?.aspect || 1)
((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.original?.aspect || 1)
}
const panX = useSharedValue(
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.x || 0) *
imageDimensionis.width) /
2
)
const panY = useSharedValue(
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.y || 0) *
imageDimensionis.height) /
2
)
const updateFocus = ({ x, y }: { x: number; y: number }) => {
composeDispatch({
type: 'attachment/edit',
@@ -70,46 +57,50 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
})
}
type PanContext = {
startX: number
startY: number
}
const onGestureEvent = useAnimatedGestureHandler({
onStart: (_, context: PanContext) => {
context.startX = panX.value
context.startY = panY.value
},
onActive: ({ translationX, translationY }, context: PanContext) => {
panX.value = context.startX + translationX
panY.value = context.startY + translationY
},
onEnd: ({ translationX, translationY }, context: PanContext) => {
runOnJS(updateFocus)({
x: (context.startX + translationX) / (imageDimensionis.width / 2),
y: (context.startY + translationY) / (imageDimensionis.height / 2)
})
}
const pan = useSharedValue({
x:
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.x || 0) *
imageDimensionis.width) /
2,
y:
(((theAttachmentRemote as Mastodon.AttachmentImage)?.meta?.focus?.y || 0) *
imageDimensionis.height) /
2
})
const start = useSharedValue({ x: 0, y: 0 })
const gesture = Gesture.Pan()
.onBegin(() => {
start.value = pan.value
})
.onUpdate(e => {
pan.value = {
x: e.translationX + start.value.x,
y: e.translationY + start.value.y
}
})
.onEnd(() => {
runOnJS(updateFocus)({
x: pan.value.x / (imageDimensionis.width / 2),
y: pan.value.y / (imageDimensionis.height / 2)
})
})
.onFinalize(() => {
start.value = pan.value
})
const styleTransform = useAnimatedStyle(() => {
return {
transform: [
{
translateX: interpolate(
panX.value,
[
-imageDimensionis.width / 2 + padding,
imageDimensionis.width / 2 + padding
],
[
-imageDimensionis.width / 2 + padding,
imageDimensionis.width / 2 + padding
],
pan.value.x,
[-imageDimensionis.width / 2, imageDimensionis.width / 2],
[-imageDimensionis.width / 2, imageDimensionis.width / 2],
Extrapolate.CLAMP
)
},
{
translateY: interpolate(
panY.value,
pan.value.y,
[-imageDimensionis.height / 2, imageDimensionis.height / 2],
[-imageDimensionis.height / 2, imageDimensionis.height / 2],
Extrapolate.CLAMP
@@ -128,47 +119,41 @@ const ComposeEditAttachmentImage: React.FC<Props> = ({ index }) => {
height: imageDimensionis.height
}}
source={{
uri: theAttachmentLocal?.uri
? theAttachmentLocal.uri
: theAttachmentRemote?.preview_url
uri: theAttachmentLocal?.uri ? theAttachmentLocal.uri : theAttachmentRemote?.preview_url
}}
/>
<PanGestureHandler onGestureEvent={onGestureEvent}>
<GestureDetector gesture={gesture}>
<Animated.View
style={[
styleTransform,
{
width: windowWidth * 2,
height: imageDimensionis.height * 2,
position: 'absolute',
top: -500 + imageDimensionis.height / 2,
left: -500 + imageDimensionis.width / 2
left: -windowWidth / 2,
top: -imageDimensionis.height / 2,
backgroundColor: colors.backgroundOverlayInvert,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
}
]}
>
<Svg width='1000' height='1000' viewBox='0 0 1000 1000'>
<G stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'>
<G>
<Path
d='M1000,0 L1000,1000 L0,1000 L0,0 L1000,0 Z M500,475 C486.192881,475 475,486.192881 475,500 C475,513.807119 486.192881,525 500,525 C513.807119,525 525,513.807119 525,500 C525,486.192881 513.807119,475 500,475 Z'
fill={colors.backgroundOverlayInvert}
/>
<Circle
stroke={colors.primaryOverlay}
stroke-width='2'
cx='500'
cy='500'
r='24'
/>
<Circle
fill={colors.primaryOverlay}
cx='500'
cy='500'
r='2'
/>
</G>
</G>
</Svg>
</Animated.View>
</PanGestureHandler>
children={
<View
style={{
width: 48,
height: 48,
borderRadius: 24,
borderWidth: 2,
borderColor: colors.primaryOverlay,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
}}
/>
}
/>
</GestureDetector>
</View>
{screenReaderEnabled ? null : (
<CustomText