Working on first support of svg on mobiles but seems quite complicated

This commit is contained in:
Clément Le Bihan
2023-11-27 01:05:04 +01:00
parent 262353376c
commit 9f57e8ac67
3 changed files with 81 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { View, ImageBackground, Image } from 'react-native';
import { View, ImageBackground, Image, Platform } from 'react-native';
import API from '../../API';
import { useQuery } from '../../Queries';
import { PianoCC } from '../../views/PlayView';
@@ -7,6 +7,7 @@ import Animated, { useSharedValue, withTiming, Easing } from 'react-native-reani
import { CursorInfoItem } from '../../models/SongCursorInfos';
import { PianoNotes } from '../../state/SoundPlayerSlice';
import { Audio } from 'expo-av';
import { SvgContainer, GetSvgDims } from './SvgContainer';
// note we are also using timestamp in a context
export type ParitionMagicProps = {
@@ -17,8 +18,10 @@ export type ParitionMagicProps = {
};
const getSVGURL = (songID: number) => {
return 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.3.0/flags/1x1/ad.svg';
return API.getPartitionSvgUrl(songID);
};
const getCursorToPlay = (
cursorInfos: CursorInfoItem[],
currentCurIdx: number,
@@ -40,7 +43,7 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
const { data, isLoading, isError } = useQuery(API.getSongCursorInfos(songID));
const [currentCurIdx, setCurrentCurIdx] = React.useState(-1);
const partitionOffset = useSharedValue(0);
const [partitionDims, setPartitionDims] = React.useState<[number, number]>([0, 0]);
const [partitionDims, setPartitionDims] = React.useState<[number, number]>([0, 1]);
const pianoCC = React.useContext(PianoCC);
const pianoSounds = React.useRef<Record<string, Audio.Sound>>();
const cursorPaddingVertical = 10;
@@ -55,7 +58,13 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
const cursorLeft = (data?.cursors[0]?.x ?? 0) - cursorPaddingHorizontal;
React.useEffect(() => {
Image.getSize(getSVGURL(songID), (w, h) => {
if (Platform.OS === 'web') {
Image.getSize(getSVGURL(songID), (w, h) => {
setPartitionDims([w, h]);
});
return;
}
GetSvgDims(getSVGURL(songID), (w, h) => {
setPartitionDims([w, h]);
});
if (!pianoSounds.current) {
@@ -146,13 +155,19 @@ const PartitionMagic = ({ songID, onEndReached, onError, onReady }: ParitionMagi
}}
>
{!isLoading && !isError && (
<ImageBackground
source={{ uri: getSVGURL(songID) }}
onLoad={onReady}
<SvgContainer
url={getSVGURL(songID)}
onReady={() => {
console.log('ready');
console.log(partitionDims);
onReady();
}}
style={{
aspectRatio: partitionDims[0] / partitionDims[1],
// check to avoid NaN
// aspectRatio: partitionDims[1]
// ? partitionDims[0] / partitionDims[1]
// : undefined,
height: '100%',
position: 'relative',
}}
/>
)}

View File

@@ -0,0 +1,57 @@
import React from 'react';
import { ViewStyle, ImageBackground, Platform, Image } from 'react-native';
import { SvgCssUri } from 'react-native-svg';
type SvgContainerProps = {
url: string;
onReady?: () => void;
style?: ViewStyle;
};
export const GetSvgDims = (url: string, success: (w: number, h: number) => void) => {
if (Platform.OS === 'web') {
React.useEffect(() => {
Image.getSize(url, (w, h) => {
success(w, h);
});
}, [url]);
return;
}
success(470.1052279999999, 275);
};
export const SvgContainer = ({ url, onReady, style }: SvgContainerProps) => {
// const [dims, setDims] = React.useState<[number, number]>([470.1052279999999, 0]);
if (Platform.OS === 'web') {
return (
<ImageBackground
source={{ uri: url }}
onLoad={onReady}
style={[
{
// aspectRatio: dims[0] / dims[1],
},
style,
]}
/>
);
}
return (
<SvgCssUri
uri={url}
style={[
{
// aspectRatio: 2545.469353542076 / 193.5,
// aspectRatio: 470 / 275,
},
style,
]}
// onLayout={(e) => {
// const { width, height } = e.nativeEvent.layout;
// getDims(width, height);
// }}
onLoad={onReady}
/>
);
};

View File

@@ -79,7 +79,7 @@ export const PianoCC = createContext<PianoCanvasContext>({
});
const PlayView = ({ songId, route }: RouteProps<PlayViewProps>) => {
songId = 1;
songId = 13;
const [type, setType] = useState<'practice' | 'normal'>();
const accessToken = useSelector((state: RootState) => state.user.accessToken);
const navigation = useNavigation();