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