Skip to content

Commit

Permalink
Adding playground to withRepeat subpage (#5917)
Browse files Browse the repository at this point in the history
## Summary
This PR includes a playground to withRepeat subpage.

## Preview
withRepeat Playground
<img width="1024" alt="Zrzut ekranu 2024-04-19 o 14 38 33"
src="https://github.com/software-mansion/react-native-reanimated/assets/80314375/cbdcf6c6-8d34-4fe3-a4aa-9e5a196b9273">

## Test plan
Command to change current working dictionary:
> cd docs

Command to download libraries:
> yarn

Command to preview feature:
> yarn start
  • Loading branch information
xnameTM authored May 22, 2024
1 parent 80bb6e4 commit 6ea9685
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 6 deletions.
4 changes: 4 additions & 0 deletions docs/docs/animations/withRepeat.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ A function called on animation complete. In case the animation is cancelled, the

A parameter that determines how the animation responds to the device's reduced motion accessibility setting.

import { useRepeatPlayground } from '@site/src/components/InteractivePlayground';

<InteractivePlayground usePlayground={useRepeatPlayground} />

### Returns

`withRepeat` returns an [animation object](/docs/fundamentals/glossary#animation-object) which holds the current state of the animation. It can be either assigned directly to a [shared value](/docs/fundamentals/glossary#shared-value) or can be used as a value for a style object returned from [useAnimatedStyle](docs/core/useAnimatedStyle).
Expand Down
22 changes: 20 additions & 2 deletions docs/src/components/InteractivePlayground/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ReducedMotionWarning from '../ReducedMotionWarning';
import useClampPlayground from './useClampPlayground';
import useSpringPlayground from './useSpringPlayground';
import useTimingPlayground from './useTimingPlayground';
import useRepeatPlayground from './useRepeatPlayground';
import useInterpolateColorPlayground from './useInterpolateColorPlayground';
import useAnimatedSensorPlayground from './useAnimatedSensorPlayground';
import useDecayPlayground from './useDecayPlayground';
Expand All @@ -30,6 +31,7 @@ export {
useClampPlayground,
useSpringPlayground,
useTimingPlayground,
useRepeatPlayground,
useInterpolateColorPlayground,
useAnimatedSensorPlayground,
useDecayPlayground,
Expand Down Expand Up @@ -126,6 +128,7 @@ interface RangeProps {
step?: number;
value: number;
onChange: Dispatch<number>;
disabled?: boolean;
label: string;
}

Expand All @@ -151,6 +154,18 @@ const RangeStyling = {
},
};

const DisabledRangeStyling = {
color: 'var(--swm-interactive-slider)', // color of the main path of slider
'& .MuiSlider-thumb': {
backgroundColor: '#ccc', //color of thumb
transform: 'translate(-50%, -40%)',
},
'& .MuiSlider-rail': {
color: 'var(--swm-interactive-slider-rail)', //color of the rail (remaining area of slider)
opacity: 1,
},
};

const TextFieldStyling = {
minWidth: 88,
'& .MuiInputBase-input': {
Expand All @@ -169,16 +184,18 @@ export function Range({
max,
value,
onChange,
disabled,
label,
step = 1,
}: RangeProps) {
return (
<>
<div className={styles.row}>
<label>{label}</label>
<label style={{ color: disabled ? '#aaa' : 'black' }}>{label}</label>
<TextField
type="number"
hiddenLabel
disabled={disabled}
size="small"
inputProps={{ min: min, max: max, step: step }}
sx={TextFieldStyling}
Expand All @@ -194,7 +211,8 @@ export function Range({
max={max}
step={step}
value={value}
sx={RangeStyling}
disabled={disabled}
sx={disabled ? DisabledRangeStyling : RangeStyling}
onChange={(e: Event & { target: HTMLInputElement }) =>
onChange(parseFloat(e.target.value))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { useEffect } from 'react';
import { StyleSheet, View, Button } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
cancelAnimation,
ReduceMotion,
withTiming,
withRepeat,
} from 'react-native-reanimated';

interface Props {
options: {
numberOfReps: number;
reverse: boolean;
reduceMotion: ReduceMotion;
};
}

export default function App({ options }: Props) {
const offset = useSharedValue(0);
const [running, setRunning] = React.useState(false);

const animatedStyles = useAnimatedStyle(() => {
return {
transform: [{ translateX: offset.value }],
};
});

useEffect(() => {
cancelAnimation(offset);
offset.value = 0;
}, [options]);

const handlePress = () => {
if (running) {
cancelAnimation(offset);
setRunning(false);
return;
}

setRunning(true);
offset.value = 0;
offset.value = withRepeat(
withTiming(200, { duration: 1000 }),
options.numberOfReps,
options.reverse,
() => setRunning(false),
options.reduceMotion
);
};

return (
<View style={styles.container}>
<View style={[styles.wrapper]}>
<Animated.View style={[styles.box, animatedStyles]} />
</View>
<View style={styles.buttonWrapper}>
<Button onPress={handlePress} title={running ? 'Stop' : 'Start'} />
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
height: '100%',
marginTop: 64,
marginBottom: 34,
},
wrapper: {
flex: 1,
width: 300,
},
box: {
height: 100,
width: 100,
backgroundColor: '#b58df1',
borderRadius: 20,
cursor: 'grab',
alignItems: 'center',
justifyContent: 'center',
},
buttonWrapper: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginTop: 16,
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useState } from 'react';
import Example from './Example';

import { Range, CheckboxOption, SelectOption, formatReduceMotion } from '..';
import { ReduceMotion } from 'react-native-reanimated';

const defaultConfig = {
numberOfReps: 2,
reverse: false,
reduceMotion: ReduceMotion.System,
};

const TIMING_OFFSET = 200;

export default function useRepeatPlayground() {
const [infinity, setInfinity] = useState(false);
const [numberOfReps, setNumberOfReps] = useState(defaultConfig.numberOfReps);
const [reverse, setReverse] = useState(defaultConfig.reverse);
const [reduceMotion, setReduceMotion] = useState(defaultConfig.reduceMotion);

const resetOptions = () => {
setNumberOfReps(() => defaultConfig.numberOfReps);
setReverse(() => defaultConfig.reverse);
setReduceMotion(() => defaultConfig.reduceMotion);
};

const code = `
withRepeat(
withTiming(${TIMING_OFFSET}, { duration: 1000 }),
${infinity ? -1 : numberOfReps},
${reverse},
() => {},
${formatReduceMotion(reduceMotion)},
)
`;

const controls = (
<>
<CheckboxOption
label="Infinity"
value={infinity}
onChange={setInfinity}
/>
<Range
label="Repetitions"
min={1}
max={10}
step={1}
disabled={infinity}
value={numberOfReps}
onChange={setNumberOfReps}
/>
<CheckboxOption label="Reverse" value={reverse} onChange={setReverse} />
<SelectOption
label="Reduce motion"
value={reduceMotion}
onChange={(option) => setReduceMotion(option as ReduceMotion)}
options={[ReduceMotion.System, ReduceMotion.Always, ReduceMotion.Never]}
/>
</>
);

return {
example: Example,
props: {
options: {
numberOfReps: infinity ? -1 : numberOfReps,
reverse,
reduceMotion,
},
},
controls,
code,
resetOptions,
additionalComponents: {},
};
}
1 change: 0 additions & 1 deletion docs/src/examples/SpringCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
SharedValue,
} from 'react-native-reanimated';

const INITIAL_OFFSET = 110;
Expand Down
1 change: 0 additions & 1 deletion docs/src/examples/SpringMassCompare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Animated, {
useAnimatedStyle,
withSpring,
withRepeat,
SharedValue,
} from 'react-native-reanimated';

const duration = 1800;
Expand Down
1 change: 0 additions & 1 deletion docs/src/examples/TimingEasingCompare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Animated, {
withTiming,
Easing,
withRepeat,
SharedValue,
} from 'react-native-reanimated';

const duration = 2000;
Expand Down
1 change: 0 additions & 1 deletion docs/src/examples/UseReducedMotion.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import Animated, {
SharedValue,
useAnimatedStyle,
useReducedMotion,
useSharedValue,
Expand Down

0 comments on commit 6ea9685

Please sign in to comment.