Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seamless UI Thread Integration: Replacing Utils with colorKit Methods #54

Merged
merged 2 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 59 additions & 16 deletions src/ColorPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { Text } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { useSharedValue, withTiming } from 'react-native-reanimated';
import { runOnJS, useSharedValue, withTiming } from 'react-native-reanimated';

import colorKit from '@colorKit';
import { PickerContextProvider } from '@context';
Expand Down Expand Up @@ -50,36 +50,79 @@ const ColorPicker = forwardRef<ColorPickerRef, ColorPickerProps>(
const brightnessValue = useSharedValue(initialColor.v);
const alphaValue = useSharedValue(initialColor.a);

const returnedResults = (color?: SupportedColorFormats) => {
color = color ?? {
const returnedResults = (inputColor?: SupportedColorFormats) => {
'worklet';

const color = inputColor ?? {
h: hueValue.value,
s: saturationValue.value,
v: brightnessValue.value,
a: alphaValue.value,
};

return {
hex: colorKit.HEX(color),
rgb: colorKit.RGB(color).string(false),
rgba: colorKit.RGB(color).string(true),
hsl: colorKit.HSL(color).string(false),
hsla: colorKit.HSL(color).string(true),
hsv: colorKit.HSV(color).string(false),
hsva: colorKit.HSV(color).string(true),
hwb: colorKit.HWB(color).string(false),
hwba: colorKit.HWB(color).string(true),
get hex() {
return colorKit.runOnUI().HEX(color);
},
get rgb() {
return colorKit.runOnUI().RGB(color).string(false);
},
get rgba() {
return colorKit.runOnUI().RGB(color).string(true);
},
get hsl() {
return colorKit.runOnUI().HSL(color).string(false);
},
get hsla() {
return colorKit.runOnUI().HSL(color).string(true);
},
get hsv() {
return colorKit.runOnUI().HSV(color).string(false);
},
get hsva() {
return colorKit.runOnUI().HSV(color).string(true);
},
get hwb() {
return colorKit.runOnUI().HWB(color).string(false);
},
get hwba() {
return colorKit.runOnUI().HWB(color).string(true);
},
};
};

const onGestureEnd = (color?: SupportedColorFormats) => {
onComplete?.(returnedResults(color));
'worklet';

if (!onComplete) return;
const colorObject = returnedResults(color);

try {
// run on the UI thread
onComplete(colorObject);
} catch (error) {
// run on the JS thread
runOnJS(onComplete)(colorObject);
}
};

const onGestureChange = (color?: SupportedColorFormats) => {
onChange?.(returnedResults(color));
'worklet';

if (!onChange) return;
const colorObject = returnedResults(color);

try {
// run on the UI thread
onChange(colorObject);
} catch (error) {
// run on the JS thread
runOnJS(onChange)(colorObject);
}
};

const setColor = (color: string, duration = thumbAnimationDuration) => {
const { h, s, v, a } = colorKit.HSV(color).object();
const setColor = (color: SupportedColorFormats, duration = thumbAnimationDuration) => {
const { h, s, v, a } = colorKit.HSV(color).object(false);

hueValue.value = withTiming(h, { duration });
saturationValue.value = withTiming(s, { duration });
Expand Down
6 changes: 3 additions & 3 deletions src/components/Panels/Panel1.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { Image, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import { styles } from '@styles';
Expand Down Expand Up @@ -83,7 +83,7 @@ export function Panel1({

saturationValue.value = newSaturationValue;
brightnessValue.value = newBrightnessValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -93,7 +93,7 @@ export function Panel1({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Panels/Panel2.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { ImageBackground, StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import { styles } from '@styles';
Expand Down Expand Up @@ -95,7 +95,7 @@ export function Panel2({

hueValue.value = newHueValue;
channelValue.value = newChannelValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -105,7 +105,7 @@ export function Panel2({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Panels/Panel3.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { Image, ImageBackground, StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import { styles } from '@styles';
Expand Down Expand Up @@ -103,7 +103,7 @@ export function Panel3({

hueValue.value = newHueValue;
channelValue.value = newChannelValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -113,7 +113,7 @@ export function Panel3({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Panels/Panel4.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { Image, View } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import { styles } from '@styles';
Expand Down Expand Up @@ -107,7 +107,7 @@ export function Panel4({
hueValue.value = newHueValue;
saturationValue.value = newSaturationValue;
brightnessValue.value = newBrightnessValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -117,7 +117,7 @@ export function Panel4({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
8 changes: 5 additions & 3 deletions src/components/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue } from 'rea
import colorKit from '@colorKit';
import usePickerContext from '@context';
import { styles } from '@styles';
import { ConditionalRendering, contrastRatio, getStyle, HSVA2HEX, isWeb } from '@utils';
import { ConditionalRendering, getStyle, isWeb } from '@utils';
import { PreviewText } from './PreviewText';

import type { PreviewProps } from '@types';
Expand Down Expand Up @@ -41,12 +41,14 @@ export function Preview({
useDerivedValue(() => {
const currentColor = { h: hueValue.value, s: saturationValue.value, v: brightnessValue.value, a: alphaValue.value };

previewColor.value = HSVA2HEX(hueValue.value, saturationValue.value, brightnessValue.value, alphaValue.value);
previewColor.value = colorKit
.runOnUI()
.HEX({ h: hueValue.value, s: saturationValue.value, v: brightnessValue.value, a: alphaValue.value });

// calculate the contrast ratio
const compareColor1 = alphaValue.value > 0.5 ? currentColor : { h: 0, s: 0, v: 70 };
const compareColor2 = textColor.value === '#000000' ? { h: 0, s: 0, v: 0 } : { h: 0, s: 0, v: 100 };
const contrast = contrastRatio(compareColor1, compareColor2);
const contrast = colorKit.runOnUI().contrastRatio(compareColor1, compareColor2);
const reversedColor = textColor.value === '#ffffff' ? '#000000' : '#ffffff';
textColor.value = contrast < 4.5 ? reversedColor : textColor.value;
}, [hueValue, saturationValue, brightnessValue, alphaValue]);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Sliders/HSB/BrightnessSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import Thumb from '@thumb';
Expand Down Expand Up @@ -86,7 +86,7 @@ export function BrightnessSlider({
if (brightnessValue.value === newBrightnessValue) return;

brightnessValue.value = newBrightnessValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -96,7 +96,7 @@ export function BrightnessSlider({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Sliders/HSB/HueSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import Thumb from '@thumb';
Expand Down Expand Up @@ -93,7 +93,7 @@ export function HueSlider({
if (hueValue.value === newHueValue) return;

hueValue.value = newHueValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -103,7 +103,7 @@ export function HueSlider({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Sliders/HSB/SaturationSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import Thumb from '@thumb';
Expand Down Expand Up @@ -92,7 +92,7 @@ export function SaturationSlider({
if (saturationValue.value === newSaturationValue) return;

saturationValue.value = newSaturationValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -102,7 +102,7 @@ export function SaturationSlider({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Sliders/HueCircular.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { ImageBackground, StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import { styles } from '@styles';
Expand Down Expand Up @@ -105,7 +105,7 @@ export function HueCircular({
if (hueValue.value === newHueValue) return;

hueValue.value = newHueValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -122,7 +122,7 @@ export function HueCircular({
isGestureActive.value = false;

handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
6 changes: 3 additions & 3 deletions src/components/Sliders/OpacitySlider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Image, StyleSheet } from 'react-native';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import usePickerContext from '@context';
import Thumb from '@thumb';
Expand Down Expand Up @@ -97,7 +97,7 @@ export function OpacitySlider({
if (alphaValue.value === newOpacityValue) return;

alphaValue.value = newOpacityValue;
runOnJS(onGestureChange)();
onGestureChange();
};
const onGestureBegin = (event: PanGestureHandlerEventPayload) => {
'worklet';
Expand All @@ -107,7 +107,7 @@ export function OpacitySlider({
const onGestureFinish = () => {
'worklet';
handleScale.value = withTiming(1, { duration: 100 });
runOnJS(onGestureEnd)();
onGestureEnd();
};

const pan = Gesture.Pan().onBegin(onGestureBegin).onUpdate(onGestureUpdate).onEnd(onGestureFinish);
Expand Down
Loading