Files
jrshikoku/components/StationDiagram/ExGridView.tsx

89 lines
2.6 KiB
TypeScript

import { FC } from "react";
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: {
trainNumber: string;
array: string;
name: string;
type: string;
time: string;
}[];
}> = ({ data }) => {
const groupedData = {};
const groupKeys = [];
const { width } = useWindowDimensions();
data.forEach((item) => {
const hour = item.time.split(":")[0];
if (!groupedData[hour]) {
groupedData[hour] = [];
groupKeys.push(hour);
}
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 (
<GestureDetector gesture={pinchGesture}>
<ScrollView horizontal nestedScrollEnabled pinchGestureEnabled={false}>
<Animated.ScrollView
style={[{ backgroundColor: "white", width: width }, animatedStyle]}
pinchGestureEnabled={false}
minimumZoomScale={0.5}
maximumZoomScale={3.0}
stickyHeaderIndices={
groupKeys.at(0) ? groupKeys.map((_, i) => i * 2) : []
}
>
{groupKeys.map((hour) => [
<View
style={{
backgroundColor: "white",
padding: 5,
borderBottomWidth: 0.5,
borderTopWidth: 0.5,
borderBottomColor: "#ccc",
}}
key={hour}
>
<Text style={{ fontSize: 15 }}>{hour}</Text>
</View>,
<View style={{ flexDirection: "row", position: "relative" }}>
{groupedData[hour].map((d, i) => (
<ExGridViewItem
key={d.trainNumber + i}
d={d}
index={i}
width={widthX}
/>
))}
</View>,
])}
</Animated.ScrollView>
</ScrollView>
</GestureDetector>
);
};