import React, { useState, useEffect, useRef } from "react"; export default function MySlider({ lower_bound, upper_bound, step, unit, unitSite = "right", width = 0, onChange, handleFunc = () => {}, disabled = false, thumbSize = 25, stepValues = [], hasInfinity, leftValue = lower_bound, rightValue = stepValues[stepValues.length - 1], maximumTrackTintColor = "#dcdbdb", minimumTrackTintColor = "#577BFF", processHeight = 7, }) { // const leftProcess = useRef(0); // const rightProcess = useRef(0); const [leftProcess, setLeftProcess] = useState(0); const [rightProcess, setRightProcess] = useState(0); const [stepNum, setStepNum] = useState(stepValues.length - 1); const [processWidth, setProcessWidth] = useState(330); const currentLeftValue = useRef(leftValue); const currentRightValue = useRef(rightValue); useEffect(() => { setProcessWidth(width - thumbSize * 2); }, []); useEffect(() => { const currentLeftProcess = (stepValues.indexOf(leftValue) * step - lower_bound) / (upper_bound - lower_bound); const currentRightProcess = (stepValues.indexOf(rightValue) * step - lower_bound) / (upper_bound - lower_bound); setLeftProcess(currentLeftProcess); setRightProcess(currentRightProcess); currentLeftValue.current = leftValue; currentRightValue.current = rightValue; }, [leftValue, rightValue]); // 左侧滑块事件 const _onPanResponderGrantLeft = () => { handleFunc && handleFunc(); }; const _onPanResponderEndLeft = () => { handleFunc && handleFunc(); }; const _onPanResponderMoveLeft = (e) => { if (e.touches.length == 1) { const process = (e.touches[0].pageX - thumbSize * 2) / processWidth; _changeProcess(process, "left"); } }; // 右侧滑块事件 const _onPanResponderGrantRight = (e, gestureState) => { handleFunc && handleFunc(); }; const _onPanResponderEndRight = (e, gestureState) => { handleFunc && handleFunc(); }; const _onPanResponderMoveRight = (e) => { if (e.touches.length == 1) { const process = (e.touches[0].pageX - thumbSize / 2 - 40) / processWidth; _changeProcess(process, "right"); } }; const _changeProcess = (changeProcess, direction) => { // 判断滑动开关 if (disabled) return; // 按步长比例变化刻度 changeProcess = changeProcess > 1 ? 1 : changeProcess < 0 ? 0 : changeProcess; const v = changeProcess * (upper_bound - lower_bound); const newValue = Math.round(v / step) * step; const newProcess = Math.round(newValue) / (upper_bound - lower_bound); setStepNum(stepNum + 1); if (process !== newProcess) { if (direction == "left") { const currentRightProcess = (stepValues.indexOf(currentRightValue.current) * step - lower_bound) / (upper_bound - lower_bound); if (newProcess < currentRightProcess) { const newLower = stepValues[ Math.round( (newProcess * (upper_bound - lower_bound) + lower_bound) / step ) ]; if (newLower <= currentRightValue.current - 3) { setLeftProcess(newProcess); setStepNum((old) => old + 1); onChange({ lower_bound: newLower, upper_bound: currentRightValue.current, }); } } } else { const currentLeftProcess = (stepValues.indexOf(currentLeftValue.current) * step - lower_bound) / (upper_bound - lower_bound); if (newProcess > currentLeftProcess) { const newUpper = stepValues[ Math.round( (newProcess * (upper_bound - lower_bound) + lower_bound) / step ) ]; if (newUpper >= currentLeftValue.current + 3) { setRightProcess(newProcess); setStepNum((old) => old - 1); onChange({ lower_bound: currentLeftValue.current, upper_bound: newUpper, }); } // setStepNum(stepNum - 1); } } } }; return (
{/* 格子步数 */} {hasInfinity && (
{stepValues.map((item, index) => (
= leftValue && item <= rightValue ? minimumTrackTintColor : maximumTrackTintColor, width: thumbSize / 2, height: thumbSize / 2, borderRadius: 50, }} >
))}
)}
{/* 左侧控件 */}
{/* 右侧控件 */}
{unitSite == "left" && ( {unit} )} {hasInfinity && leftProcess == 1 ? "∞" : leftValue} ~ {hasInfinity && rightProcess >= 1 ? "∞" : rightValue} {unitSite == "right" && ( {unit} )}
{lower_bound} {hasInfinity ? "∞" : upper_bound}
); }