UNPKG

reanimated-color-picker

Version:
276 lines (270 loc) 6.36 kB
import React from 'react'; import { Image } from 'react-native'; import Animated, { useAnimatedStyle, useDerivedValue, useSharedValue } from 'react-native-reanimated'; import colorKit from '../../colorKit/index'; import usePickerContext from '../../AppContext'; import { PanelCore } from './PanelCore'; import { styles } from '../../styles'; import { getStyle, isRtl } from '../../utils'; /** @see [Panel5](https://alabsi91.github.io/reanimated-color-picker/api/panels/panel5/) */ export function Panel5({ gestures = [], style = {}, selectionStyle = {}, accessibilityLabel, accessibilityHint }) { const { hueValue, saturationValue, brightnessValue, onGestureChange, onGestureEnd } = usePickerContext(); const borderRadius = getStyle(style, 'borderRadius') ?? 0; const row = useSharedValue(0); const column = useSharedValue(0); const adaptiveColor = useSharedValue('#000'); const width = useSharedValue(0); const height = useSharedValue(0); const squareSize = useDerivedValue(() => Math.max(width.value / 12, height.value / 10), [width, height]); const setAdaptiveColor = color => { 'worklet'; const isDark = colorKit.runOnUI().isDark(color); adaptiveColor.value = isDark ? '#ffffff' : '#000000'; }; // Calculate the position of the selected square on color change. // Since color conversion is not 100% accurate, we need to find the closest color in the grid. useDerivedValue(() => { const hsvColor = { h: hueValue.value, s: saturationValue.value, v: brightnessValue.value, }; for (let y = 0; y < GRID_COLORS.length; y++) { for (let x = 0; x < GRID_COLORS[y].length; x++) { const gridColor = GRID_COLORS[y][x]; const areColorsEqual = colorKit.runOnUI().areColorsEqual(gridColor, hsvColor, 5); if (!areColorsEqual) continue; row.value = y; column.value = x; setAdaptiveColor(gridColor); break; } } }, [hueValue, saturationValue, brightnessValue, row, column]); const selectedStyle = useAnimatedStyle(() => { const x = column.value * squareSize.value; const y = row.value * squareSize.value; return { width: squareSize.value, height: squareSize.value, top: y, left: isRtl ? undefined : x, right: isRtl ? x : undefined, borderColor: adaptiveColor.value, }; }, [squareSize, adaptiveColor, row, column]); const onUpdate = (newColumn, newRow) => { 'worklet'; var _GRID_COLORS$newRow; const color = (_GRID_COLORS$newRow = GRID_COLORS[newRow]) === null || _GRID_COLORS$newRow === void 0 ? void 0 : _GRID_COLORS$newRow[newColumn]; if (!color) return; const { h, s, v } = colorKit.runOnUI().HSV(color).object(false); if (hueValue.value === h && saturationValue.value === s && brightnessValue.value === v) { return; } hueValue.value = h; saturationValue.value = s; brightnessValue.value = v; setAdaptiveColor(color); onGestureChange(); }; const onGestureUpdate = ({ x, y }) => { 'worklet'; if (!squareSize.value) return; const newRow = Math.floor(y / squareSize.value); const newColumn = Math.floor(x / squareSize.value); onUpdate(newColumn, newRow); }; const onEnd = () => { 'worklet'; onGestureEnd(); }; return /*#__PURE__*/ React.createElement( PanelCore, { style: [ style, { position: 'relative', borderWidth: 0, padding: 0, aspectRatio: 1.2, }, ], label: accessibilityLabel ?? '12 by 10 Grid of 120 Colors', hint: accessibilityHint ?? 'Double tap to switch between column and row selection', labelX: 'Column', currentXValue: column, maxXValue: 12, labelY: 'Row', currentYValue: row, maxYValue: 10, reverseY: true, width: width, height: height, gestures: gestures, onGestureUpdate: onGestureUpdate, onUpdate: onUpdate, onEnd: onEnd, }, /*#__PURE__*/ React.createElement(Image, { source: require('../../assets/grid.png'), style: { borderRadius, width: '100%', height: '100%', }, resizeMode: 'stretch', 'aria-hidden': true, }), /*#__PURE__*/ React.createElement(Animated.View, { style: [styles.selected, selectionStyle, selectedStyle], 'aria-hidden': true, }), ); } const GRID_COLORS = [ [ '#FFFFFF', '#EBEBEB', '#D6D6D6', '#C2C2C2', '#ADADAD', '#999999', '#858585', '#707070', '#5C5C5C', '#474747', '#333333', '#000000', ], [ '#00374A', '#011D57', '#11053B', '#2E063D', '#3C071B', '#5C0701', '#5A1C00', '#583300', '#563D00', '#666100', '#4F5504', '#263E0F', ], [ '#004D65', '#012F7B', '#1A0A52', '#450D59', '#551029', '#831100', '#7B2900', '#7A4A00', '#785800', '#8D8602', '#6F760A', '#38571A', ], [ '#016E8F', '#0042A9', '#2C0977', '#61187C', '#791A3D', '#B51A00', '#AD3E00', '#A96800', '#A67B01', '#C4BC00', '#9BA50E', '#4E7A27', ], [ '#008CB4', '#0056D6', '#371A94', '#7A219E', '#99244F', '#E22400', '#DA5100', '#D38301', '#D19D01', '#F5EC00', '#C3D117', '#669D34', ], [ '#00A1D8', '#0061FD', '#4D22B2', '#982ABC', '#B92D5D', '#FF4015', '#FF6A00', '#FFAB01', '#FCC700', '#FEFB41', '#D9EC37', '#76BB40', ], [ '#01C7FC', '#3A87FD', '#5E30EB', '#BE38F3', '#E63B7A', '#FE6250', '#FE8648', '#FEB43F', '#FECB3E', '#FFF76B', '#E4EF65', '#96D35F', ], [ '#52D6FC', '#74A7FF', '#864FFD', '#D357FE', '#EE719E', '#FF8C82', '#FEA57D', '#FEC777', '#FED977', '#FFF994', '#EAF28F', '#B1DD8B', ], [ '#93E3FC', '#A7C6FF', '#B18CFE', '#E292FE', '#F4A4C0', '#FFB5AF', '#FFC5AB', '#FED9A8', '#FDE4A8', '#FFFBB9', '#F1F7B7', '#CDE8B5', ], [ '#CBF0FF', '#D2E2FE', '#D8C9FE', '#EFCAFE', '#F9D3E0', '#FFDAD8', '#FFE2D6', '#FEECD4', '#FEF1D5', '#FDFBDD', '#F6FADB', '#DEEED4', ], ];