我已经看到了一些与我类似的问题,但是我的实现有很大不同,以至于我仍然不确定可行的前进道路。我对 react-native 还是很陌生,而且只用了一天时间就使用了 pan 响应器。
我使用 svgs 创建了一个圆形滑块,松散地基于这个包。我的滑块有一个手柄,从零开始。我想做的是限制用户将知识移动到起点以下(0)或最大值以上的能力。
我的视图呈现为
<View
style={{
width,
height: width,
}}
ref={viewRef}
onLayout={() => {
viewRef.current?.measure((_x, _y, w, h, px, py) => {
location.current = {
x: px + w / 2,
y: py + h / 2,
};
});
}}
>
<Svg width={width} height={width} ref={viewRef}>
{/* Track */}
<Path
stroke={trackColor}
strokeWidth={trackWidth}
d={[
'M',
startCoord.x,
startCoord.y,
'A',
trackRadius,
trackRadius,
0,
maxAngle <= 180 ? '0' : '1',
1,
endTintCoord.x,
endTintCoord.y,
].join(' ')}
/>
{/* Slider fill */}
<Path
stroke="trackColor"
strokeWidth={trackWidth}
fill="none"
d={`M${startCoord.x} ${startCoord.y} A ${trackRadius} ${trackRadius} 0 ${
valuePercentage * 3.6 > 180 ? 1 : 0
} 1 ${endCoord.x} ${endCoord.y}`}
/>
{/* Slider handle */}
<G x={endCoord.x - thumbRadius} y={endCoord.y - thumbRadius}>
<Circle
r={thumbRadius}
cx={thumbRadius}
cy={thumbRadius}
stroke="#EDF4FF"
strokeWidth={2}
fill={thumbColor}
{...panResponder.panHandlers}
/>
<Circle r={5} cx={thumbRadius} cy={thumbRadius} fill="#FFFFFF" />
</G>
</Svg>
</View>
和我的回复
const { current: panResponder } = React.useRef(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
onStartShouldSetPanResponderCapture: () => true,
onMoveShouldSetPanResponder: () => true,
onMoveShouldSetPanResponderCapture: () => true,
onPanResponderGrant: () => location.current.x && location.current.y,
onPanResponderMove: (_e, { moveX, moveY }: PanResponderGestureState) => {
const angle = cartesianToPolar(
moveX - location.current.x + trackRadius + thumbRadius,
moveY - location.current.y + trackRadius + thumbRadius,
);
if (angle <= minAngle) {
onChange((minAngle / 3.6) * (maximumValue / 100));
} else if (angle >= maxAngle) {
onChange((maxAngle / 3.6) * (maximumValue / 100));
} else {
onChange((angle / 3.6) * (maximumValue / 100));
}
},
}),
);
那里还有一些其他逻辑定义了 ui,但可能与我的问题无关。我想知道的是限制滑块手柄移动的模式是什么。