Skip to content

Commit

Permalink
feat: add summary/example from documentation (#363)
Browse files Browse the repository at this point in the history
Co-authored-by: Mark Doyle <[email protected]>
Co-authored-by: William Candillon <[email protected]>
  • Loading branch information
3 people authored Oct 7, 2020
1 parent 3accda7 commit 3bd75eb
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/Animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export type AnimationParameter<State extends AnimationState = AnimationState> =
| (() => Animation<State>)
| number;

/**
* @summary Access animations passed as parameters safely on both the UI and JS thread with the proper static types.
* Animations can receive other animations as parameter.
*/
export const animationParameter = <
State extends AnimationState = AnimationState
>(
Expand All @@ -42,6 +46,18 @@ export const animationParameter = <
: animationParam;
};

/**
* @summary Declare custom animations that can be invoked on both the JS and UI thread.
* @example
* defineAnimation(() => {
"worklet";
// ...animation code
return {
animation,
start
}
});
*/
export const defineAnimation = <
S extends AnimationState = AnimationState,
Prev extends AnimationState = AnimationState
Expand All @@ -60,6 +76,16 @@ interface PausableAnimation extends AnimationState {
elapsed: number;
}

/**
* @summary Make an animation pausable. The state of the animation (paused or not)
* is controlled by a boolean shared value.
* @example
const progress = useSharedValue(0);
const paused = useSharedValue(false);
useEffect(() => {
progress.value = withPause(withLoop(withTiming(1)), paused);
}, []);
*/
export const withPause = (
animationParam: AnimationParameter,
paused: Animated.SharedValue<boolean>
Expand Down Expand Up @@ -97,6 +123,13 @@ export const withPause = (
});
};

/**
* @summary Add a bouncing behavior to a physics-based animation.
* An animation is defined as being physics-based if it contains a velocity in its state.
* @example
// will bounce if the animations hits the position 0 or 100
withBouncing(withDecay({ velocity }), 0, 100)
*/
export const withBouncing = (
animationParam: AnimationParameter<PhysicsAnimationState>,
lowerBound: number,
Expand Down
39 changes: 39 additions & 0 deletions src/Colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import { clamp, mix } from "./Math";

declare let _WORKLET: boolean;

/**
* @summary TypeScript type to define an animation value as color.
* @example
// Color can be of string or number depending of the context in which it was executed
const color: Animated.SharedValue<Color> = useDerivedValue(() => mixColor(progress.value, "blue", "red"));
*/
export type Color = string | number;
export enum ColorSpace {
RGB,
Expand Down Expand Up @@ -58,6 +64,9 @@ export const color = (r: number, g: number, b: number, alpha = 1): Color => {
return c;
};

/**
* @summary Convert HSV to RGB
*/
export const hsv2rgb = (h: number, s: number, v: number) => {
"worklet";
// vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
Expand Down Expand Up @@ -86,18 +95,27 @@ export const hsv2rgb = (h: number, s: number, v: number) => {
};
};

/**
* @summary Convert HSV to RGB
*/
export const hsv2color = (h: number, s: number, v: number): Color => {
"worklet";
const { r, g, b } = hsv2rgb(h, s, v);
return color(r, g, b);
};

/**
* @summary Returns black or white depending on the value of the background color.
*/
export const colorForBackground = (r: number, g: number, b: number) => {
"worklet";
const L = 0.299 * r + 0.587 * g + 0.114 * b;
return L > 186 ? 0x000000ff : 0xffffffff;
};

/**
* @summary Convert RGB to HSV
*/
const rgbToHsv = (c: number) => {
"worklet";
const r = red(c) / 255;
Expand Down Expand Up @@ -198,6 +216,20 @@ const interpolateColorsRGB = (
return color(r, g, b, a);
};

/**
* @summary Interpolate an animation value into a color.
The color can be interpolated in the RGB or HSV color space (default is RGB).
* @example
const theta = useSharedValue(Math.PI);
const backgroundColor = useDerivedValue(() => {
return interpolateColor(
theta.value,
[0, Math.PI, Math.PI * 2],
["#ff3884", StyleGuide.palette.primary, "#38ffb3"]
ColorSpace.HSV // default is RGB
);
});
*/
export const interpolateColor = (
value: number,
inputRange: number[],
Expand All @@ -215,6 +247,13 @@ export const interpolateColor = (
return result;
};

/**
* @summary Identical to interpolateColor() but with an animation value that goes from 0 to 1.
* @example
const backgroundColor = useDerivedValue(() =>
mixColor(progress.value, "#ff3884", "#38ffb3")
);
*/
export const mixColor = (
value: number,
color1: Color,
Expand Down
39 changes: 39 additions & 0 deletions src/Math.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Vector } from "./Vectors";

/**
* @summary Convert a boolean value into a number.
* This can be useful in reanimated since 0 and 1 are used for conditional statements.
*/
export const bin = (value: boolean): 0 | 1 => {
"worklet";
return value ? 1 : 0;
Expand All @@ -15,16 +19,25 @@ export const lerp = (x: number, y: number, value: number) => {
return (1 - value) * x + value * y;
};

/**
* @summary Transforms an angle from radians to degrees.
*/
export const toDeg = (rad: number) => {
"worklet";
return (rad * 180) / Math.PI;
};

/**
* @summary Transforms an angle from degrees to radians.
*/
export const toRad = (deg: number) => {
"worklet";
return (deg * Math.PI) / 180;
};

/**
* @summary Returns true if node is within lowerBound and upperBound.
*/
export const between = (
value: number,
lowerBound: number,
Expand All @@ -38,6 +51,13 @@ export const between = (
return value > lowerBound && value < upperBound;
};

/**
* @summary Clamps a node with a lower and upper bound.
* @example
clamp(-1, 0, 100); // 0
clamp(1, 0, 100); // 1
clamp(101, 0, 100); // 100
*/
export const clamp = (
value: number,
lowerBound: number,
Expand All @@ -47,6 +67,11 @@ export const clamp = (
return Math.min(Math.max(lowerBound, value), upperBound);
};

/**
* @description Returns the coordinate of a cubic bezier curve. t is the length of the curve from 0 to 1.
* cubicBezier(0, p0, p1, p2, p3) equals p0 and cubicBezier(1, p0, p1, p2, p3) equals p3.
* p0 and p3 are respectively the starting and ending point of the curve. p1 and p2 are the control points.
*/
export const cubicBezier = (
t: number,
from: number,
Expand All @@ -63,6 +88,9 @@ export const cubicBezier = (
return a + b + c + d;
};

/**
* @summary Computes animation node rounded to precision.
*/
export const round = (value: number, precision = 0) => {
"worklet";
const p = Math.pow(10, precision);
Expand Down Expand Up @@ -140,6 +168,17 @@ const solveCubic = (a: number, b: number, c: number, d: number) => {
return roots;
};

/**
* @summary Given a cubic Bèzier curve, return the y value for x.
* @example
const x = 116;
const from = vec.create(59, 218);
const c1 = vec.create(131, 39);
const c2 = vec.create(204, 223);
const to = vec.create(227, 89);
// y= 139
const y = cubicBezierYForX(x, from, c1, c2, to)));
*/
export const cubicBezierYForX = (
x: number,
a: Vector,
Expand Down
35 changes: 35 additions & 0 deletions src/Paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ const isClose = (command: Segment): command is Close => {
return command.type === SVGCommand.CLOSE;
};

/**
* @summary Serialize a path into an SVG path string
*/
export const serialize = (path: Path) => {
"worklet";
return path
Expand All @@ -91,6 +94,11 @@ export const serialize = (path: Path) => {
.reduce((acc, c) => acc + c);
};

/**
* @description ⚠️ this function cannot run on the UI thread. It must be executed on the JS thread
* @summary Parse an SVG path into a sequence of Bèzier curves.
* The SVG is normalized to have absolute values and to be approximated to a sequence of Bèzier curves.
*/
export const parse = (d: string): Path => {
const segments: SVGNormalizedCommands = normalizeSVG(absSVG(parseSVG(d)));
return segments.map((segment, index) => {
Expand Down Expand Up @@ -123,6 +131,9 @@ export const parse = (d: string): Path => {
});
};

/**
* @summary Interpolate between paths.
*/
export const interpolatePath = (
value: number,
inputRange: number[],
Expand Down Expand Up @@ -221,6 +232,10 @@ export const interpolatePath = (
return serialize(path);
};

/**
* @summary Interpolate two paths with an animation value that goes from 0 to 1
*/

export const mixPath = (
value: number,
p1: Path,
Expand All @@ -231,11 +246,17 @@ export const mixPath = (
return interpolatePath(value, [0, 1], [p1, p2], extrapolate);
};

/**
* @summary Returns a Bèzier curve command.
*/
export const move = (x: number, y: number) => {
"worklet";
return { type: SVGCommand.MOVE as const, x, y };
};

/**
* @summary Returns a Bèzier curve command
*/
export const curve = (c: Omit<Curve, "type">) => {
"worklet";
return {
Expand All @@ -247,11 +268,25 @@ export const curve = (c: Omit<Curve, "type">) => {
};
};

/**
* @summary Returns a close command.
*/
export const close = () => {
"worklet";
return { type: SVGCommand.CLOSE as const };
};

/**
* @summary Return the y value of a path given its x coordinate
* @example
const p1 = parse(
"M150,0 C150,0 0,75 200,75 C75,200 200,225 200,225 C225,200 200,150 0,150"
);
// 75
getYForX(p1, 200))
// ~151
getYForX(p1, 50)
*/
export const getYForX = (path: Path, x: number) => {
"worklet";
const p = path.filter((c) => {
Expand Down
3 changes: 3 additions & 0 deletions src/Physics.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* @summary Select a point where the animation should snap to given the value of the gesture and it's velocity.
*/
export const snapPoint = (
value: number,
velocity: number,
Expand Down
11 changes: 11 additions & 0 deletions src/Vectors.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import Animated, { useSharedValue } from "react-native-reanimated";

/**
* @summary Type representing a vector
* @example
export interface Vector<T = number> {
x: T;
y: T;
}
*/
export interface Vector<T = number> {
x: T;
y: T;
}

/**
* @summary Returns a vector of shared values
*/
export const useVector = (
x1 = 0,
y1?: number
Expand Down

0 comments on commit 3bd75eb

Please sign in to comment.