Skip to content

Commit c5cad85

Browse files
committed
Enhance CircularDraggableSlider: Add animated hour label overlay and adjust label rendering logic
1 parent 1a35278 commit c5cad85

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

src/components/circle-time/index.tsx

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export type DraggableSliderProps = {
3232

3333
const { height: WindowHeight } = Dimensions.get('window');
3434
const radius = 200;
35+
const HOUR_LABELS_AMOUNT = 10;
3536

3637
export type CircularDraggableSliderRefType = {
3738
resetTimer: () => void;
@@ -72,6 +73,33 @@ export const CircularDraggableSlider = forwardRef<
7273
);
7374
}, [listWidth]);
7475

76+
const overlayStyle = useAnimatedStyle(() => {
77+
const angleStep = (2 * Math.PI) / linesAmount;
78+
const hourIndexRatio = progressRadiants.value / (angleStep * bigLineIndexOffset);
79+
const boundedHourIndex = Math.max(
80+
1,
81+
Math.min(HOUR_LABELS_AMOUNT, Math.round(hourIndexRatio)),
82+
);
83+
const requestedTickIndex = boundedHourIndex * bigLineIndexOffset;
84+
if (requestedTickIndex > linesAmount) {
85+
return { opacity: 0 };
86+
}
87+
88+
const targetTickIndex = Math.min(linesAmount - 1, requestedTickIndex);
89+
const labelRadius = radius + LABEL_RADIUS_OFFSET;
90+
const angle = angleStep * targetTickIndex - progressRadiants.value;
91+
const x = Math.cos(angle) * labelRadius;
92+
const y = Math.sin(angle) * labelRadius;
93+
94+
return {
95+
opacity: 1,
96+
transform: [
97+
{ translateX: x - LABEL_WIDTH / 2 },
98+
{ translateY: y - LABEL_HEIGHT / 2 },
99+
],
100+
};
101+
}, [bigLineIndexOffset, linesAmount, radius]);
102+
75103
useAnimatedReaction(
76104
() => selectedDuration?.value ?? null,
77105
duration => {
@@ -144,7 +172,7 @@ export const CircularDraggableSlider = forwardRef<
144172
/>
145173
);
146174
})}
147-
{new Array(10).fill(0).map((_, hourIndex) => {
175+
{new Array(HOUR_LABELS_AMOUNT).fill(0).map((_, hourIndex) => {
148176
const label = `${hourIndex + 1} hr`;
149177
const tickIndex = (hourIndex + 1) * bigLineIndexOffset;
150178
if (tickIndex > linesAmount) {
@@ -162,6 +190,26 @@ export const CircularDraggableSlider = forwardRef<
162190
/>
163191
);
164192
})}
193+
<Animated.View
194+
pointerEvents="none"
195+
style={[styles.hourLabelOverlay, overlayStyle]}
196+
>
197+
<LinearGradient
198+
start={{
199+
x: 0,
200+
y: 0
201+
}}
202+
end={{
203+
x: 0,
204+
y: 1
205+
}}
206+
colors={['transparent','#00000080', '#000000', '#000000', '#000000' , '#00000080', 'transparent']}
207+
style={{
208+
height: "100%",
209+
width: "100%",
210+
}}
211+
/>
212+
</Animated.View>
165213
</Animated.View>
166214
<LinearGradient
167215
colors={['#000000', '#000000', '#000000', '#00000070', 'transparent']}
@@ -256,6 +304,15 @@ const styles = StyleSheet.create({
256304
justifyContent: 'center',
257305
left: 10
258306
},
307+
hourLabelOverlay: {
308+
position: 'absolute',
309+
width: LABEL_WIDTH,
310+
height: LABEL_HEIGHT,
311+
backgroundColor: '#000',
312+
borderRadius: LABEL_HEIGHT / 2,
313+
zIndex: 1,
314+
left: 10,
315+
},
259316
hourLabelText: {
260317
color: '#d8d8d8',
261318
fontFamily: 'SF-Pro-Rounded-Bold',

0 commit comments

Comments
 (0)