提问人:Inzen 提问时间:10/17/2023 更新时间:10/17/2023 访问量:38
如何流畅地进行拖动或移动滑动?时间选择器 rect next js 13 应用目录
How do I smoothly do drags or mobile swipe? Time Picker Rect Next Js 13 App Dir
问:
因此,我决定尝试制作自己的时间选择器组件。为什么?好吧,没有一个单一的 UI 库,用户可以向上或向下滑动以选择小时或分钟或下午 / 上午。我不需要用户选择日期,我只想要他们想要的时间。
到目前为止,我可以滚动并让用户选择向上/向下滑动的数字。问题是我正在尝试用户可以在刷卡器上移动多个数字,而不必滑动并且只能向上或向下移动 1 个数字。我还想看到数字随着用户滑动而移动。
如果我做不到这一点,我将简单地使用带有选项的选择标签,但我想避免这种情况,因为我不喜欢移动设备的外观,因为它们使用本机选择。
这是第一次尝试这样的事情,所以我也尝试使用 chatGPT 来做这件事,所以不要以为我是从头开始做的,哈哈。我以前从来没有做过这样的定制。
"use client";
import React, { useState } from "react";
import TimeSection from "./TimeSection";
export default function TimePickerModal() {
const [isOpen, setIsOpen] = useState(false);
const [selectedHour, setSelectedHour] = useState(12);
const [selectedMinute, setSelectedMinute] = useState(30);
const hours = Array.from({ length: 24 }, (_, i) => i);
const minutes = Array.from({ length: 60 }, (_, i) => i);
const handleSwipe = (
setter: React.Dispatch<React.SetStateAction<number>>,
values: number[],
currentValue: number
) => {
let startY: number | null = null;
let initialValue: number | null = null;
return (e: React.TouchEvent<HTMLDivElement>) => {
if (e.type === "touchstart" && e.touches.length > 0) {
startY = e.touches[0].clientY;
initialValue = currentValue;
} else if (
e.type === "touchmove" &&
startY !== null &&
initialValue !== null
) {
const currentY = e.touches[0].clientY;
const diff = currentY - startY;
const swipeSensitivity = 50;
const unitsToMove = Math.round(diff / swipeSensitivity);
const newValue = initialValue - unitsToMove;
if (newValue >= 0 && newValue < values.length) {
setter(newValue);
} else if (newValue < 0) {
setter(0);
} else if (newValue >= values.length) {
setter(values.length - 1);
}
}
};
};
return (
<div>
<button onClick={() => setIsOpen(true)}>Open Time Picker</button>
{isOpen && (
<div
style={{
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: "rgba(0,0,0,0.5)",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<div
style={{
backgroundColor: "white",
padding: "20px",
borderRadius: "5px",
display: "flex",
flexDirection: "row",
color: "black",
}}
>
<TimeSection
values={hours}
currentValue={selectedHour}
handleSwipe={handleSwipe(setSelectedHour, hours, selectedHour)}
/>
<TimeSection
values={minutes}
currentValue={selectedMinute}
handleSwipe={handleSwipe(
setSelectedMinute,
minutes,
selectedMinute
)}
/>
<button
onClick={() => {
console.log(
`Selected Time: ${String(selectedHour).padStart(
2,
"0"
)}:${String(selectedMinute).padStart(2, "0")}`
);
setIsOpen(false);
}}
>
Enter
</button>
</div>
</div>
)}
</div>
);
}
TimeSection.tsx
import React from "react";
interface TimeSectionProps {
values: number[];
currentValue: number;
handleSwipe: (e: React.TouchEvent<HTMLDivElement>) => void;
}
export default function TimeSection({
values,
currentValue,
handleSwipe,
}: TimeSectionProps) {
return (
<div
style={{
height: "250px",
width: "50px",
overflow: "hidden",
position: "relative",
}}
>
<div
onTouchStart={handleSwipe}
onTouchMove={handleSwipe}
style={{
position: "absolute",
top: `calc(50% - ${currentValue * 24}px)`,
width: "100%",
textAlign: "center",
}}
>
{values.map((value, index) => (
<div
key={index}
style={{
color: "black",
height: "24px",
lineHeight: "24px",
visibility:
index >= currentValue - 2 && index <= currentValue + 2
? "visible"
: "hidden",
opacity: index === currentValue ? 1 : 0.5,
fontSize: index === currentValue ? "24px" : "18px",
}}
>
{String(value).padStart(2, "0")}
</div>
))}
</div>
</div>
);
}
有谁知道我该如何修复,或者是否有隐藏的 npm 包 idk?希望不是,但是如果我找不到解决方案,那么我将坚持使用选择和选项标签。
答:
1赞
HighDevWizards
10/17/2023
#1
AntD 组件支持许多组件,包括 timepicker。https://ant.design/components/time-picker
如果选中此项,则可以找到时间选择器,您只能选择时间。
评论
0赞
Inzen
10/17/2023
不要我找不到这个,但这可能就行了!多谢。
0赞
Inzen
10/18/2023
按照我想要的方式工作,一路上不得不解决一些警告,但它有效。
评论