横スクロールのサイズ変更をピンチでできるようにした
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { FC } from "react";
|
||||
import { ListViewItem } from "@/components/StationDiagram/ListViewItem";
|
||||
import { View, Text, ScrollView, useWindowDimensions } from "react-native";
|
||||
import { ExGridViewItem } from "./ExGridViewItem";
|
||||
import Animated, {
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
} from "react-native-reanimated";
|
||||
import { Gesture, GestureDetector } from "react-native-gesture-handler";
|
||||
|
||||
export const ExGridView: FC<{
|
||||
data: {
|
||||
@@ -24,13 +28,31 @@ export const ExGridView: FC<{
|
||||
}
|
||||
groupedData[hour].push(item);
|
||||
});
|
||||
// ドラッグ位置を保持する共有値
|
||||
const widthX = useSharedValue(width);
|
||||
const savedWidthX = useSharedValue(width);
|
||||
|
||||
// パンジェスチャー(ドラッグ)のハンドラー
|
||||
const pinchGesture = Gesture.Pinch()
|
||||
.onUpdate((e) => {
|
||||
const calc = savedWidthX.value * e.scale;
|
||||
widthX.value = calc > width ? calc : width;
|
||||
})
|
||||
.onEnd(() => {
|
||||
savedWidthX.value = widthX.value;
|
||||
});
|
||||
// アニメーションスタイル
|
||||
const animatedStyle = useAnimatedStyle(() => ({
|
||||
width: widthX.value,
|
||||
}));
|
||||
return (
|
||||
<ScrollView horizontal nestedScrollEnabled>
|
||||
<ScrollView
|
||||
style={{ backgroundColor: "white", width: width }}
|
||||
<GestureDetector gesture={pinchGesture}>
|
||||
<ScrollView horizontal nestedScrollEnabled pinchGestureEnabled={false}>
|
||||
<Animated.ScrollView
|
||||
style={[{ backgroundColor: "white", width: width }, animatedStyle]}
|
||||
pinchGestureEnabled={false}
|
||||
minimumZoomScale={0.5}
|
||||
maximumZoomScale={3.0}
|
||||
pinchGestureEnabled
|
||||
stickyHeaderIndices={
|
||||
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
|
||||
}
|
||||
@@ -50,11 +72,17 @@ export const ExGridView: FC<{
|
||||
</View>,
|
||||
<View style={{ flexDirection: "row", position: "relative" }}>
|
||||
{groupedData[hour].map((d, i) => (
|
||||
<ExGridViewItem key={d.trainNumber + i} d={d} index={i} />
|
||||
<ExGridViewItem
|
||||
key={d.trainNumber + i}
|
||||
d={d}
|
||||
index={i}
|
||||
width={widthX}
|
||||
/>
|
||||
))}
|
||||
</View>,
|
||||
])}
|
||||
</Animated.ScrollView>
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
</GestureDetector>
|
||||
);
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@ import { migrateTrainName } from "@/lib/eachTrainInfoCoreLib/migrateTrainName";
|
||||
import { getStringConfig, typeID } from "@/lib/getStringConfig";
|
||||
import { getTrainType } from "@/lib/getTrainType";
|
||||
import { useAllTrainDiagram } from "@/stateBox/useAllTrainDiagram";
|
||||
import { FC, useEffect, useMemo, useState } from "react";
|
||||
import { FC, useEffect, useLayoutEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -15,6 +15,8 @@ import { SheetManager } from "react-native-actions-sheet";
|
||||
import { useNavigation } from "@react-navigation/native";
|
||||
import { lineList } from "@/lib/getStationList";
|
||||
import { useStationList } from "@/stateBox/useStationList";
|
||||
import { SharedValue, useAnimatedStyle } from "react-native-reanimated";
|
||||
import Animated from "react-native-reanimated";
|
||||
|
||||
export const ExGridViewItem: FC<{
|
||||
d: {
|
||||
@@ -25,7 +27,8 @@ export const ExGridViewItem: FC<{
|
||||
time: string;
|
||||
};
|
||||
index: number;
|
||||
}> = ({ d, index }) => {
|
||||
width: SharedValue<number>;
|
||||
}> = ({ d, index, width }) => {
|
||||
const { allCustomTrainData } = useAllTrainDiagram();
|
||||
const { navigate, goBack } = useNavigation();
|
||||
const [trainData, setTrainData] = useState<{
|
||||
@@ -53,7 +56,6 @@ export const ExGridViewItem: FC<{
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
const { width } = useWindowDimensions();
|
||||
const { color, name, data } = getTrainType(trainData?.type, true);
|
||||
const { originalStationList } = useStationList();
|
||||
// 列車名、種別、フォントの取得
|
||||
@@ -173,10 +175,18 @@ export const ExGridViewItem: FC<{
|
||||
// if(typeString == "回送"){
|
||||
// return<></>;
|
||||
// }
|
||||
const animatedStyle = useAnimatedStyle(() => {
|
||||
const leftPosition =
|
||||
((((width.value - 50) / 100) * parseInt(formattedTime)) / 60) * 100;
|
||||
return {
|
||||
left: leftPosition,
|
||||
};
|
||||
}, [formattedTime]);
|
||||
return (
|
||||
<View style={{ left: 0, height: 50 }}>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
<Animated.View
|
||||
style={[
|
||||
{
|
||||
flexDirection: "column",
|
||||
borderTopWidth: 1,
|
||||
borderBottomWidth: 0.5,
|
||||
@@ -184,11 +194,12 @@ export const ExGridViewItem: FC<{
|
||||
borderColor: "darkgray",
|
||||
opacity: d.type.includes("通") ? 0.5 : 1,
|
||||
position: "absolute",
|
||||
left: ((((width-50) / 100) * parseInt(formattedTime)) / 60) * 100,
|
||||
height: "100%",
|
||||
}}
|
||||
onPress={() => openTrainInfo()}
|
||||
},
|
||||
animatedStyle,
|
||||
]}
|
||||
>
|
||||
<TouchableOpacity style={{ flex: 1 }} onPress={() => openTrainInfo()}>
|
||||
<View style={{ position: "relative" }}>
|
||||
<Text style={{ fontSize: 20, color: color }}>{formattedTime}</Text>
|
||||
<Text
|
||||
@@ -215,6 +226,7 @@ export const ExGridViewItem: FC<{
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user