# Reanimated Color Picker > A pure JavaScript color picker for React Native, supporting iOS, Android, Expo, Web and RTL layouts. > Every document from https://alabsi91.github.io/reanimated-color-picker/llms.txt inlined in full, so no links need following. --- ## Reanimated Color Picker - **A Pure JavaScript Color Picker for React Native.** - **Highly customizable.** - **Supports iOS, Android, Expo, and Web platforms.** - **Supports right-to-left (RTL) layouts.** ### For LLMs This documentation is also published as plain Markdown for AI coding agents: [llms.txt](https://alabsi91.github.io/reanimated-color-picker/llms.txt) indexes every page, and [llms-full.txt](https://alabsi91.github.io/reanimated-color-picker/llms-full.txt) contains the whole documentation in a single file. ### Screenshots ![Example_1](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_1.png) ![Example_7](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_7.png) ![Example_2](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_2.png) ![Example_3](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_3.png) ![Example_4](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_4.png) ![Example_5](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_5.png) ![Example_8](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_8.png) ![Example_9](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_9.png) ![Example_10](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_10.png) ![Example_11](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_11.png) ![Example_6](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_6.png) ![Example_12](https://raw.githubusercontent.com/alabsi91/reanimated-color-picker/main/images/example_12.png) Source: https://alabsi91.github.io/reanimated-color-picker/index.md --- ## ColorKit `colorKit` is a collection of color tools that are utilized internally within the `ColorPicker`. ### Supported Colors ##### RGB - `"rgb(255, 0, 255)"` - `"rgb(255 0 255)"` - `"rgba(255, 0, 255, 1.0)"` - `"rgb(255, 0, 255, 1.0)"` - `"rgba(255 0 255 / 1.0)"` - `"rgb(255 0 255 / 1.0)"` - `{r: number, g: number, b: number, a: number}` - `{r: number, g: number, b: number}` ##### HEX - `"#f0f"` (#rgb) - `"#ff00ff"` (#rrggbb) - `"#f0ff"` (#rgba) - `"#ff00ff00"` (#rrggbbaa) ##### HSL - `"hsl(360, 100%, 100%)"` - `"hsl(360deg, 100%, 100%)"` - `"hsl(360 100% 100%)"` - `"hsl(360deg 100% 100%)"` - `"hsla(360, 100%, 100%, 1.0)"` - `"hsl(360, 100%, 100%, 1.0)"` - `"hsla(360deg, 100%, 100%, 1.0)"` - `"hsl(360deg, 100%, 100%, 1.0)"` - `"hsla(360 100% 100% / 1.0)"` - `"hsl(360 100% 100% / 1.0)"` - `"hsla(360deg 100% 100% / 1.0)"` - `"hsl(360deg 100% 100% / 1.0)"` - `{h: number, s: number, l: number}` - `{h: number, s: number, l: number, a: number}` ##### HSV - `"hsv(360, 100%, 100%)"` - `"hsv(360deg, 100%, 100%)"` - `"hsv(360 100% 100%)"` - `"hsv(360deg 100% 100%)"` - `"hsva(360, 100%, 100%, 1.0)"` - `"hsv(360, 100%, 100%, 1.0)"` - `"hsva(360deg, 100%, 100%, 1.0)"` - `"hsv(360deg, 100%, 100%, 1.0)"` - `"hsva(360 100% 100% / 1.0)"` - `"hsv(360 100% 100% / 1.0)"` - `"hsva(360deg 100% 100% / 1.0)"` - `"hsv(360deg 100% 100% / 1.0)"` - `{h: number, s: number, v: number}` - `{h: number, s: number, v: number, a: number}` ##### HWB - `"hwb(360, 100%, 100%)"` - `"hwb(360deg, 100%, 100%)"` - `"hwb(360 100% 100%)"` - `"hwb(360deg 100% 100%)"` - `"hwba(360, 100%, 100%, 1.0)"` - `"hwb(360, 100%, 100%, 1.0)"` - `"hwba(360deg, 100%, 100%, 1.0)"` - `"hwb(360deg, 100%, 100%, 1.0)"` - `"hwba(360 100% 100% / 1.0)"` - `"hwb(360 100% 100% / 1.0)"` - `"hwba(360deg 100% 100% / 1.0)"` - `"hwb(360deg 100% 100% / 1.0)"` - `{h: number, w: number, b: number}` - `{h: number, w: number, b: number, a: number}` ##### Color ints - `0xff00ffff` (0xrrggbbaa) ##### Color keywords The named colors implementation follows the [CSS3/SVG specification](https://www.w3.org/TR/css-color-3/#svg-color). - aliceblue (`#f0f8ff`) - antiquewhite (`#faebd7`) - aqua (`#00ffff`) - aquamarine (`#7fffd4`) - azure (`#f0ffff`) - and more ... > [!info] HOW TO RUN ON THE UI THREAD > To execute any of the `colorKit` methods, you can use `runOnUI`. For example: > > ```js > function workletFunction() { > "worklet"; > const rgb = colorKit.runOnUI().RGB("#f0ff").object(); > } > ``` ### Color Conversion #### RGB Convert any of the [supported color](#supported-colors) formats into the `RGB` format. ##### Syntax ```ts colorKit.RGB(color: SupportedColorFormats).string(forceRGBA = false): string; colorKit.RGB(color: SupportedColorFormats).array(roundValues = true): number[]; colorKit.RGB(color: SupportedColorFormats).object(roundValues = true): { r: number; g: number; b: number; a: number }; ``` ##### Example ```js import { colorKit } from "reanimated-color-picker"; colorKit.RGB("hsl(360, 100%, 100%)").string(); // rgb(255, 255, 255) colorKit.RGB("hsl(360, 100%, 100%)").string(true); // rgba(255, 255, 255, 1) force rgba colorKit.RGB("#f0ff").object(); // { r: 255, g: 0, b: 255, a: 1 } colorKit.RGB({ h: 360, s: 100, v: 50 }).array(); // [128, 0, 0, 1] ``` #### HEX Convert any of the [supported color](#supported-colors) formats into the `HEX` format. ##### Syntax ```ts colorKit.HEX(color: SupportedColorFormats, forceAlpha?: boolean): string; ``` ##### Example ```js import { colorKit } from "reanimated-color-picker"; colorKit.HEX("red"); // #ff0000 colorKit.HEX("hsv(360, 10%, 100%)"); // #ffe6e6 colorKit.HEX("rgba(25, 255, 255, 1)"); // #19ffff colorKit.HEX({ h: 360, s: 100, l: 50 }); // #ff0000 ``` #### HSL Convert any of the [supported color](#supported-colors) formats into the `HSL` format. ##### Syntax ```ts colorKit.HSL(color: SupportedColorFormats).string(forceHSLA = false): string; colorKit.HSL(color: SupportedColorFormats).array(roundValues = true): number[]; colorKit.HSL(color: SupportedColorFormats).object(roundValues = true): { h: number; s: number; l: number; a: number }; ``` ##### Example ```js import { colorKit } from "reanimated-color-picker"; colorKit.HSL("orange").string(); // hsl(39, 100%, 50%) colorKit.HSL("#503e7a").string(true); // hsla(258, 33%, 36%, 1) colorKit.HSL("rgb(114, 99, 29)").object(); // { h: 49, s: 59, l: 28, a: 1 } colorKit.HSL({ a: 1, h: 336, s: 44, v: 28 }).array(); // [336, 28, 22, 1] ``` #### HSV Convert any of the [supported color](#supported-colors) formats into the `HSV` format. ##### Syntax ```ts colorKit.HSV(color: SupportedColorFormats).string(forceHSVA = false): string; colorKit.HSV(color: SupportedColorFormats).array(roundValues = true): number[]; colorKit.HSV(color: SupportedColorFormats).object(roundValues = true): { h: number; s: number; v: number; a: number }; ``` ##### Example ```js import { colorKit } from "reanimated-color-picker"; colorKit.HSV("orange").string(true); // hsva(39, 100%, 100%, 1) colorKit.HSV("#503e7a").string(); // hsv(258, 49%, 48%) colorKit.HSV("rgb(114, 99, 29)").object(); // { h: 49, s: 75, v: 45, a: 1 } colorKit.HSV({ a: 1, h: 336, s: 44, v: 28 }).array(); // [336, 44, 28, 1] ``` #### HWB Convert any of the [supported color](#supported-colors) formats into the `HWB` format. ##### Syntax ```ts colorKit.HWB(color: SupportedColorFormats).string(forceHWBA = false): string; colorKit.HWB(color: SupportedColorFormats).array(roundValues = true): number[]; colorKit.HWB(color: SupportedColorFormats).object(roundValues = true): { h: number; w: number; b: number; a: number }; ``` ##### Example ```js import { colorKit } from "reanimated-color-picker"; colorKit.HWB("orange").string(); // hwb(39 0% 0%) colorKit.HWB("#503e7a").string(true); // hwb(258 24% 52% / 1) colorKit.HWB("rgb(114, 99, 29)").object(); // { h: 49, w: 11, b: 55, a: 1 } colorKit.HWB({ a: 1, h: 336, s: 44, v: 28 }).array(); // [336, 16, 72, 1] ``` ### Color Information #### `getFormat` Identify the color format of a given `string` or `object`, and return `null` for invalid colors. ```js colorKit.getFormat("orange"); // named colorKit.getFormat("rgb(211, 168, 151)"); // rgb colorKit.getFormat("rgba(211, 168, 151, 1)"); // rgba colorKit.getFormat({ r: 211, g: 168, b: 151 }); // rgb colorKit.getFormat({ r: 211, g: 168, b: 151, a: 1 }); // rgba colorKit.getFormat("hsl(224, 77%, 28%)"); // hsl colorKit.getFormat("hsla(224, 77%, 28%, 1)"); // hsla colorKit.getFormat({ h: 224, s: 77, l: 28 }); // hsl colorKit.getFormat({ h: 224, s: 77, l: 28, a: 1 }); // hsla colorKit.getFormat("hsva(289, 99%, 40%, 1)"); // hsva colorKit.getFormat("hsv(289, 99%, 40%)"); // hsv colorKit.getFormat({ h: 289, s: 99, v: 40 }); // hsv colorKit.getFormat({ h: 289, s: 99, v: 40, a: 1 }); // hsva colorKit.getFormat("hwba(289, 99%, 40%, 1)"); // hwba colorKit.getFormat("hwb(289, 99%, 40%)"); // hwb colorKit.getFormat({ h: 289, w: 99, b: 40 }); // hwb colorKit.getFormat({ h: 289, w: 99, b: 40, a: 1 }); // hwba colorKit.getFormat("#fff"); // hex3 colorKit.getFormat("#ffff"); // hex4 colorKit.getFormat("#ffffffff"); // hex8 colorKit.getFormat("rgb(211, 168)"); // null (missing the blue channel) ``` #### `getRed` Get the `red` channel value of a given color. ```js colorKit.getRed("red"); // 255 ``` #### `getGreen` Get the `green` channel value of a given color. ```js colorKit.getGreen("rgb(0, 200, 0)"); // 200 ``` #### `getBlue` Get the `blue` channel value of a given color. ```js colorKit.getBlue("hsl(200, 60%, 50%)"); // 204 ``` #### `getHue` Get the `hue` channel value of a given color. ```js colorKit.getHue("#87c270"); // 103 ``` #### `getLuminance` Get the color's HSL `luminosity` channel value. If you want the overall `luminosity` of a color, use the [`getLuminanceWCAG`](#getluminancewcag) method. ```js colorKit.getLuminance({ r: 67, g: 59, b: 79, a: 1 }); // 27 ``` #### `getBrightness` Get the HSV's `value` (brightness) channel value of a given color. ```js colorKit.getBrightness({ h: 127, s: 36, l: 8, a: 1 }); // 11 ``` #### `getAlpha` Get the `alpha` channel value of a given color. ```js colorKit.getAlpha("#d2c765c7"); // 0.78 ``` #### `getLuminanceWCAG` Returns the perceived `luminance` of the given color, from `0-1` as defined by [Web Content Accessibility Guidelines (Version 2.0)](https://www.w3.org/TR/WCAG20/). ```js colorKit.getLuminanceWCAG("rgba(176, 7, 120, 1)"); // 0.10738130030129947 ``` #### `areColorsEqual` Check if two colors are similar within a specified tolerance. ```js const tolerance = 0; const isEqual = colorKit.areColorsEqual("#F00", "red", tolerance); // true ``` #### `contrastRatio` Calculates the contrast ratio between two colors, useful for ensuring accessibility and readability. ```js colorKit.contrastRatio("yellow", "rgba(40, 38, 43, 1)"); // 13.95 ``` #### `isDark` Returns a boolean indicating whether the color is considered "dark" or not. ```js colorKit.isDark("hsla(224, 77%, 28%, 1)"); // true ``` #### `isLight` Returns a boolean indicating whether the color is considered "light" or not. ```js colorKit.isLight("hsla(224, 77%, 28%, 1)"); // false ``` ### Color Manipulation #### `setRed` Set the `red` value of a color to a specific amount. ```js colorKit.setRed("#a5a2a1", 150).hex(); // #96a2a1 colorKit.setRed("#a5a2a1", 200).rgb().string(); // rgb(200, 162, 161) colorKit.setRed("#a5a2a1", 200).rgb().object(); // { r: 200, g: 162, b: 161, a: 1 } colorKit.setRed("#a5a2a1", 200).rgb().array(); // [200, 162, 161, 1] colorKit.setRed("#a5a2a1", 200).hsl().string(); // hsl(2, 26%, 71%) colorKit.setRed("#a5a2a1", 200).hsl().object(); // { h: 2, s: 26, l: 71, a: 1 } colorKit.setRed("#a5a2a1", 200).hsl().array(); // [2, 26, 71, 1] colorKit.setRed("#a5a2a1", 200).hsv().string(); // hsv(2, 20%, 78%) colorKit.setRed("#a5a2a1", 200).hsv().object(); // { h: 2, s: 20, v: 78, a: 1 } colorKit.setRed("#a5a2a1", 200).hsv().array(); // [2, 20, 78, 1] ``` #### `increaseRed` Increase the `red` value of a color by the given percentage/amount. ```js colorKit.increaseRed("#bb661b", 50).hex(); // #ed661b colorKit.increaseRed("#bb661b", "50%").hex(); // #ff661b ``` #### `decreaseRed` Decrease the `red` value of a color by the given percentage/amount. ```js colorKit.decreaseRed("#bb661b", 50).hex(); // #89661b colorKit.decreaseRed("#bb661b", "50%").hex(); // #5e661b ``` #### `setGreen` Set the `green` value of a color to a specific amount. ```js colorKit.setGreen("#d7e2d0", 50).hex(); // #d732d0 ``` #### `increaseGreen` Increase the `green` value of a color by the given percentage/amount. ```js colorKit.increaseGreen("#d7e2d0", 50).hex(); // #d7ffd0 colorKit.increaseGreen("#d7e2d0", "10%").hex(); // #d7f9d0 ``` #### `decreaseGreen` Decrease the `green` value of a color by the given percentage/amount. ```js colorKit.decreaseGreen("#d7e2d0", 50).hex(); // #d7b0d0 colorKit.decreaseGreen("#d7e2d0", "10%").hex(); // #d7cbd0 ``` #### `setBlue` Set the `blue` value of a color to a specific amount. ```js colorKit.setBlue("#5d8e92", 50).hex(); // #5d8e32 ``` #### `increaseBlue` Increase the `blue` value of a color by the given percentage/amount. ```js colorKit.increaseBlue("#5d8e92", 50).hex(); // #5d8ec4 colorKit.increaseBlue("#5d8e92", "50%").hex(); // #5d8edb ``` #### `decreaseBlue` Decrease the `blue` value of a color by the given percentage/amount. ```js colorKit.decreaseBlue("#5d8e92", 50).hex(); // #5d8e60 colorKit.decreaseBlue("#5d8e92", "50%").hex(); // #5d8e49 ``` #### `setHue` Set the `hue` value of a color to a specific amount. ```js colorKit.setHue("#2c1a51", 50).hex(); // #51481a ``` #### `increaseHue` Increase the `hue` value of a color by the given percentage/amount. ```js colorKit.increaseHue("#2c1a51", 50).hex(); // #511a48 colorKit.increaseHue("#2c1a51", "50%").hex(); // #511a1a ``` #### `decreaseHue` Decrease the `hue` value of a color by the given percentage/amount. ```js colorKit.decreaseHue("#2c1a51", 50).hex(); // #1a3651 colorKit.decreaseHue("#2c1a51", "50%").hex(); // #1a5123 ``` #### `spin` Spin the `hue` channel by a certain percentage/amount. ```js colorKit.spin("#2c1a51", 350).hex(); // #231a51 colorKit.spin("#2c1a51", "350%").hex(); // #40511a ``` #### `setSaturation` Set the `saturation` value of a color to a specific amount. ```js colorKit.setSaturation("#482e45", 100).hex(); // #750068 ``` #### `saturate` Increase the `saturation` value of a color by the given percentage/amount. ```js colorKit.saturate("#482e45", 50).hex(); // #65105b colorKit.saturate("#482e45", "50%").hex(); // #4e2749 ``` #### `desaturate` Decrease the `saturation` value of a color by the given percentage/amount. ```js colorKit.desaturate("#482e45", 50).hex(); // #3b3b3b colorKit.desaturate("#482e45", "50%").hex(); // #413440 ``` #### `setLuminance` Set HSL's `luminosity` channel for a given color to a specific amount. ```js colorKit.setLuminance("#dadafc", 50).hex(); // #1313ec ``` #### `brighten` Increase the `brightness` of the given color by a certain percentage/amount. ```js colorKit.brighten("#dadafc", 50).hex(); // #ffffff colorKit.brighten("#dadafc", "5%").hex(); // #efeffe ``` #### `darken` Decrease the `brightness` of the given color by a certain percentage/amount. ```js colorKit.darken("#dadafc", 50).hex(); // #1010c6 colorKit.darken("#dadafc", "50%").hex(); // #1212d9 ``` #### `setBrightness` Set HSV's `value` (brightness) channel for a given color to a specific amount. ```js colorKit.setBrightness("#dadafc", 50).hex(); // #6f6f80 ``` #### `increaseBrightness` Increase HSV's `value` (brightness) channel value of a color by the given percentage/amount. ```js colorKit.increaseBrightness("#dadafc", 50).hex(); // #dedeff colorKit.increaseBrightness("#dadafc", "5%").hex(); // #dedeff ``` #### `decreaseBrightness` Decrease HSV's `value` (brightness) channel value of a color by the given percentage/amount. ```js colorKit.decreaseBrightness("#dadafc", 50).hex(); // #6d6d7d colorKit.decreaseBrightness("#dadafc", "50%").hex(); // #6e6e7e ``` #### `setAlpha` Set the `alpha` value of a color to a specific amount. #### `increaseAlpha` Increase the `alpha` value of a color by the given percentage/amount. #### `decreaseAlpha` Decrease the `alpha` value of a color by the given percentage/amount. ### Color Utilities #### `parse` Parse any supported color format into a typed `{ format, value }` object. Returns `undefined` if the input is invalid. ```ts colorKit.parse("#ff0000"); // → { format: 'hex6', value: { r: 255, g: 0, b: 0 } } colorKit.parse("hsl(120, 100%, 50%)"); // → { format: 'hsl', value: { h: 120, s: 100, l: 50 } } colorKit.parse({ r: 255, g: 0, b: 0, a: 0.5 }); // → { format: 'rgba', value: { r: 255, g: 0, b: 0, a: 0.5 } } colorKit.parse("not-a-color"); // → undefined ``` #### `blend` Blends two colors by a certain amount. ```js colorKit.blend("red", "yellow", 50).hex(); // #ff8000 ``` #### `invert` Invert (negate) a color: black becomes white, white becomes black, blue becomes orange, and so on. ```js colorKit.invert("#000").hex(); // #ffffff ``` #### `grayscale` Completely desaturates a color into grayscale. ```js colorKit.grayscale("#172140").hex(); // #212121 ``` #### `adjustContrast` Returns the first color (text color) with the desired contrast ratio against the second color (background color). ```js colorKit.adjustContrast("rgb(50, 50, 50)", "#fff", 4.5).hex(); // #777777 ``` #### `randomHslColor` Generate a random color from `HSL` values. You can provide a range between two values for each channel. ```js colorKit.randomHslColor({ h: [0, 360], s: [0, 100], l: [0, 100], a: [1, 1] }).hex(); // #b07345 colorKit.randomHslColor().hex(); // #d0bfd6 ``` #### `randomHsvColor` Generate a random color from `HSV` values. You can provide a range between two values for each channel. ```js colorKit.randomHsvColor({ h: [0, 360], s: [0, 100], v: [0, 100], a: [1, 1] }).hex(); // #59078c colorKit.randomHsvColor().hex(); // #2b553f ``` #### `randomRgbColor` Generate a random color from `rgb` values. You can provide a range between two values for each channel. ```js colorKit.randomRgbColor({ r: [0, 360], g: [0, 100], b: [0, 100], a: [1, 1] }).hex(); // #ff0f0b colorKit.randomRgbColor().hex(); // #b07345 ``` #### `randomHwbColor` Generate a random color from `hwb` values. You can provide a range between two values for each channel. ```js colorKit.randomHwbColor({ h: [0, 360], w: [0, 100], b: [0, 100], a: [1, 1] }).hex(); // #ff0f0b colorKit.randomHwbColor().hex(); // #b07345 ``` Source: https://alabsi91.github.io/reanimated-color-picker/colorkit/index.md --- ## All Examples The full source of every example app, shared by the bare and Expo workflows. ### Shared Components Every example below imports these from `./components`. #### `BaseContainer` ```tsx import React, { createContext, useContext, useEffect, useState } from 'react'; import { Modal, Platform, Pressable, StyleSheet, Text, View } from 'react-native'; import Animated, { useAnimatedStyle, useSharedValue, type SharedValue } from 'react-native-reanimated'; type RegisterBackgroundColor = (color: SharedValue) => void; const RegisterBackgroundColorContext = createContext(null); /** * The color the example follows, tinting the modal background while the example runs inside a `BaseContainer`. * * Rendered on its own, outside a container, it is an ordinary shared value and nothing paints with it. */ export function useContainerBackgroundColor(initialColor: string): SharedValue { const color = useSharedValue(initialColor); const registerBackgroundColor = useContext(RegisterBackgroundColorContext); useEffect(() => registerBackgroundColor?.(color), [registerBackgroundColor, color]); return color; } type BaseContainerProps = { name: string; children: React.ReactNode; }; export default function BaseContainer({ name, children }: BaseContainerProps) { const [showModal, setShowModal] = useState(false); const [backgroundColor, setBackgroundColor] = useState | null>(null); const backgroundColorStyle = useAnimatedStyle(() => { return { backgroundColor: backgroundColor ? backgroundColor.value : '#aaa' }; }); return ( <> setShowModal(true)}> {name} setShowModal(false)} visible={showModal} animationType='slide'> {children} setShowModal(false)}> Close ); } const styles = StyleSheet.create({ wrapper: { flex: 1, }, container: { flex: 1, justifyContent: 'center', }, btnTxt: { color: '#707070', fontWeight: 'bold', fontFamily: 'Quicksand', textAlign: 'center', }, btn: { alignSelf: 'center', width: '100%', maxWidth: 300, borderRadius: 20, paddingHorizontal: 40, paddingVertical: 10, backgroundColor: '#fff', ...Platform.select({ web: { boxShadow: 'rgba(0, 0, 0, 0.3) 0px 0px 2px' }, default: { shadowColor: '#000', shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.2, shadowRadius: 1.41, elevation: 2, }, }), }, closeBtnContainer: { marginVertical: 24, marginHorizontal: 16, alignItems: 'center', }, }); ``` #### `Divider` ```tsx import React from 'react'; import { View } from 'react-native'; export default function Divider() { return ; } ``` #### `colorPickerStyle` ```ts import { Platform, StyleSheet } from "react-native"; const shadow = Platform.select({ web: { boxShadow: "rgba(0, 0, 0, 0.3) 0px 0px 2px" }, default: { shadowColor: "#000", shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.2, shadowRadius: 1.41, elevation: 2, }, }); export const colorPickerStyle = StyleSheet.create({ title: { textAlign: "center", fontFamily: "Quicksand", fontWeight: "bold", marginVertical: 20, color: "gray", }, picker: { gap: 20, }, pickerContainer: { alignSelf: "center", width: 300, backgroundColor: "#eee", padding: 20, borderRadius: 20, ...shadow, }, panelStyle: { borderRadius: 16, ...shadow, }, sliderStyle: { borderRadius: 20, ...shadow, }, sliderVerticalStyle: { borderRadius: 20, height: 300, ...shadow, }, sliderTitle: { color: "#000", fontWeight: "bold", marginBottom: 5, paddingHorizontal: 4, fontFamily: "Quicksand", }, previewStyle: { height: 40, borderRadius: 14, }, previewTxt: { color: "#707070", fontFamily: "Quicksand", }, inputStyle: { color: "#707070", paddingVertical: 2, borderColor: "#707070", fontSize: 12, marginLeft: 5, }, swatchesContainer: { alignItems: "center", flexWrap: "nowrap", gap: 10, }, swatchStyle: { borderRadius: 20, height: 30, width: 30, margin: 0, marginBottom: 0, marginHorizontal: 0, marginVertical: 0, }, }); ``` ### Panel1 ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { colorKit, HueSlider, OpacitySlider, Panel1, PreviewText, Swatches } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel2 — Saturation ```tsx import React, { useState } from 'react'; import { KeyboardAvoidingView, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BrightnessSlider, InputWidget, OpacitySlider, Panel2, colorKit } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // initial random color const initialColor = colorKit.randomRgbColor().hex(); export default function Example() { const [resultColor, setResultColor] = useState(initialColor); const currentColor = useContainerBackgroundColor(initialColor); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel2 — Brightness ```tsx import React, { useState } from 'react'; import { KeyboardAvoidingView, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { colorKit, InputWidget, OpacitySlider, Panel2, SaturationSlider } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // initial random color const initialColor = colorKit.randomRgbColor().hex(); export default function Example() { const [resultColor, setResultColor] = useState(initialColor); const currentColor = useContainerBackgroundColor(initialColor); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel2 — HSL Saturation ```tsx import React, { useState } from 'react'; import { KeyboardAvoidingView, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { InputWidget, LuminanceSlider, OpacitySlider, Panel2, colorKit } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // initial random color const initialColor = colorKit.randomRgbColor().hex(); export default function Example() { const [resultColor, setResultColor] = useState(initialColor); const currentColor = useContainerBackgroundColor(initialColor); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel3 — Saturation ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BrightnessSlider, ExtraThumb, OpacitySlider, Panel3, Preview, Swatches, colorKit, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel3 — Brightness ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { colorKit, OpacitySlider, Panel3, Preview, SaturationSlider, Swatches } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel3 — HSL Saturation ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { LuminanceSlider, OpacitySlider, Panel3, Preview, Swatches, colorKit } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel4 ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { colorKit, OpacitySlider, Panel4, PreviewText } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // initial random color, within the range that `Panel4` can display const initialColor = colorKit.randomHsvColor({ s: [100, 100], v: [100, 100] }).hex(); export default function Example() { const [resultColor, setResultColor] = useState(initialColor); const currentColor = useContainerBackgroundColor(initialColor); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Panel5 ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { OpacitySlider, Panel5, PreviewText } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // initial color; one of the grid colors const initialColor = '#ad3e00'; export default function Example() { const [resultColor, setResultColor] = useState(initialColor); const currentColor = useContainerBackgroundColor(initialColor); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Circular Hue ```tsx import React, { useState } from 'react'; import { View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { colorKit, HueCircular, Panel1, PreviewText, Swatches } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } ``` ### Circular Luminance ```tsx import React, { useState } from 'react'; import { StyleSheet, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { LuminanceCircular, Panel3, PreviewText, Swatches, colorKit } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( ); } const styles = StyleSheet.create({ hueContainer: { justifyContent: 'center', }, panelStyle: { width: '90%', height: '90%', alignSelf: 'center', borderRadius: 16, }, thumbInner: { borderWidth: 4, }, }); ``` ### HSB — Horizontal ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BrightnessSlider, colorKit, HueSlider, OpacitySlider, PreviewText, SaturationSlider, Swatches, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( Hue Saturation Brightness Opacity ); } ``` ### HSB — Vertical ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BrightnessSlider, colorKit, HueSlider, OpacitySlider, PreviewText, SaturationSlider, Swatches, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( H S B A ); } ``` ### HSL — Horizontal ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { HSLSaturationSlider, HueSlider, LuminanceSlider, OpacitySlider, PreviewText, Swatches, colorKit, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( Hue Saturation Luminance Opacity ); } ``` ### HSL — Vertical ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { HSLSaturationSlider, HueSlider, LuminanceSlider, OpacitySlider, PreviewText, Swatches, colorKit, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( H S L A ); } ``` ### RGB — Horizontal ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BlueSlider, colorKit, GreenSlider, OpacitySlider, PreviewText, RedSlider, Swatches, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( Red Green Blue Opacity ); } ``` ### RGB — Vertical ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { BlueSlider, colorKit, GreenSlider, OpacitySlider, PreviewText, RedSlider, Swatches, } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import Divider from './components/Divider'; import { colorPickerStyle } from './components/colorPickerStyle'; // generate 6 random colors for swatches const customSwatches = new Array(6).fill('#fff').map(() => colorKit.randomRgbColor().hex()); export default function Example() { const [resultColor, setResultColor] = useState(customSwatches[0]); const currentColor = useContainerBackgroundColor(customSwatches[0]); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( R G B A ); } ``` ### Inside a Gesture Handler `ScrollView` ```tsx import React, { useState } from 'react'; import { Text, View } from 'react-native'; import { GestureHandlerRootView, ScrollView } from 'react-native-gesture-handler'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { HSLSaturationSlider, HueSlider, LuminanceSlider, OpacitySlider } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import { colorPickerStyle } from './components/colorPickerStyle'; /* * Using react-native-gesture-handler ScrollView to prevent scrolling while using the color picker */ export default function Example() { const [resultColor, setResultColor] = useState('#f00'); const currentColor = useContainerBackgroundColor('#f00'); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; return ( Color Picker in a RNGH ScrollView H S L A ); } ``` ### Inside a Reanimated `ScrollView` ```tsx import React, { useState } from 'react'; import { Platform, Text, View } from 'react-native'; import { Gesture } from 'react-native-gesture-handler'; import Animated, { useAnimatedProps, useSharedValue } from 'react-native-reanimated'; import type { ColorFormatsObject } from 'reanimated-color-picker'; import ColorPicker, { HSLSaturationSlider, HueSlider, LuminanceSlider, OpacitySlider } from 'reanimated-color-picker'; import { useContainerBackgroundColor } from './components/BaseContainer'; import { colorPickerStyle } from './components/colorPickerStyle'; /* * Using react-native-reanimated ScrollView and cancelling the scroll while using the color picker */ export default function Example() { const [resultColor, setResultColor] = useState('#f00'); const currentColor = useContainerBackgroundColor('#f00'); // runs on the ui thread on color change const onColorChange = (color: ColorFormatsObject) => { 'worklet'; currentColor.value = color.hex; }; // runs on the js thread on color pick const onColorPick = (color: ColorFormatsObject) => { setResultColor(color.hex); }; const isScrollEnabled = useSharedValue(true); //? NOTE: // - You cannot use the same gesture for multiple color picker components. // - Either pass a new gesture or deep clone the gesture constructor. const [hueGesture, saturationGesture, lumGesture, opacityGesture] = Array.from({ length: 4 }, () => Gesture.Pan() .onBegin(() => (isScrollEnabled.value = false)) .onFinalize(() => (isScrollEnabled.value = true)), ); const animatedProps = useAnimatedProps( () => ({ scrollEnabled: isScrollEnabled.value }), Platform.OS === 'web' ? [isScrollEnabled] : undefined, ); return ( Color Picker in a Animated.ScrollView H S L A ); } ``` ### Examples List ```tsx import React from 'react'; import { ScrollView, StyleSheet, View } from 'react-native'; import CircularHue from './CircularHue'; import HorizontalHsbSliders from './HsbHorizontal'; import VerticalHsbSliders from './HsbVertical'; import HorizontalHslSliders from './HslHorizontal'; import VerticalHslSliders from './HslVertical'; import LuminanceCircular from './LuminanceCircular'; import Panel1Example from './Panel1'; import Panel2Brightness from './Panel2Brightness'; import Panel2HslSaturation from './Panel2HslSaturation'; import Panel2Saturation from './Panel2Saturation'; import WheelBrightness from './Panel3Brightness'; import WheelHSLSaturation from './Panel3HslSaturation'; import WheelSaturation from './Panel3Saturation'; import Panel4Example from './Panel4'; import Panel5Example from './Panel5'; import HorizontalRgbSliders from './RgbHorizontal'; import VerticalRgbSliders from './RgbVertical'; import WithReanimatedScrollView from './WithReanimatedScrollView'; import WithRnghScrollView from './WithRnghScrollView'; import BaseContainer from './components/BaseContainer'; export default function ExamplesList() { return ( ); } const styles = StyleSheet.create({ container: { flexGrow: 1, justifyContent: 'space-evenly', paddingTop: 16, paddingBottom: 54, gap: 20, }, }); ``` Source: https://alabsi91.github.io/reanimated-color-picker/examples-all/index.md --- ## Installation ### Prerequisites Before installing, make sure you have the following packages set up: - [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#installation) `>= 2.0.0`. - [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation) `>= 2.0.0`. - For Expo users: [Expo managed workflow](https://docs.expo.dev/get-started/installation/) `>= 44`. ### Install Run the following command in your project root: ```bash npm install reanimated-color-picker ``` Source: https://alabsi91.github.io/reanimated-color-picker/installation/index.md --- ## Usage You can add, remove, rearrange, or style the built-in components of the color picker. See [Panel1](https://alabsi91.github.io/reanimated-color-picker/examples/panel1/) and the examples beside it for working demos, or [Example Apps](https://alabsi91.github.io/reanimated-color-picker/examples/example-apps/) to run them yourself. > [!tip] Using inside a `ScrollView` > > If you experience gesture conflicts when using the color picker inside a `ScrollView`, simply import the `ScrollView` from `react-native-gesture-handler` instead of from `react-native`. > > ```ts > import { ScrollView } from "react-native-gesture-handler"; > ``` ### Example ```jsx // App.tsx import React, { useState } from "react"; import { Button, Modal, StyleSheet, View } from "react-native"; import ColorPicker, { Panel1, Swatches, Preview, OpacitySlider, HueSlider } from "reanimated-color-picker"; export default function App() { const [showModal, setShowModal] = useState(false); // Note: use `onCompleteJS` and `onChangeJS` for non-worklet functions const onSelectColor = ({ hex }) => { "worklet"; // do something with the selected color. console.log(hex); }; return (