UNPKG

reanimated-color-picker

Version:
264 lines (255 loc) 8.69 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.HueCircular = HueCircular; var _react = _interopRequireDefault(require('react')); var _reactNative = require('react-native'); var _reactNativeReanimated = _interopRequireWildcard(require('react-native-reanimated')); var _AppContext = _interopRequireDefault(require('../../../AppContext')); var _CircularSliderCore = require('../CircularSliderCore'); var _styles = require('../../../styles'); var _Thumb = _interopRequireDefault(require('../../Thumb/Thumb')); var _utils = require('../../../utils'); function _interopRequireWildcard(e, t) { if ('function' == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || ('object' != typeof e && 'function' != typeof e)) return f; if ((o = t ? n : r)) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) 'default' !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : (f[t] = e[t])); return f; })(e, t); } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** @see [HueCircular](https://alabsi91.github.io/reanimated-color-picker/api/sliders/hue/hue-circular-slider/) */ function HueCircular({ children, gestures = [], style = {}, containerStyle = {}, rotate = 0, ...props }) { const { hueValue, saturationValue, brightnessValue, onGestureChange, onGestureEnd, ...ctx } = (0, _AppContext.default)(); const thumbShape = props.thumbShape ?? ctx.thumbShape; const thumbSize = props.thumbSize ?? ctx.thumbSize; const thumbColor = props.thumbColor ?? ctx.thumbColor; const renderThumb = props.renderThumb ?? ctx.renderThumb; const thumbStyle = props.thumbStyle ?? ctx.thumbStyle ?? {}; const sliderThickness = props.sliderThickness ?? ctx.sliderThickness; const thumbScaleAnimationValue = props.thumbScaleAnimationValue ?? ctx.thumbScaleAnimationValue; const thumbScaleAnimationDuration = props.thumbScaleAnimationDuration ?? ctx.thumbScaleAnimationDuration; const adaptSpectrum = props.adaptSpectrum ?? ctx.adaptSpectrum; const thumbInnerStyle = props.thumbInnerStyle ?? ctx.thumbInnerStyle ?? {}; const isGestureActive = (0, _reactNativeReanimated.useSharedValue)(false); const width = (0, _reactNativeReanimated.useSharedValue)(0); const borderRadius = (0, _reactNativeReanimated.useSharedValue)(0); const borderRadiusStyle = (0, _reactNativeReanimated.useAnimatedStyle)( () => ({ borderRadius: borderRadius.value, }), [borderRadius], ); const handleScale = (0, _reactNativeReanimated.useSharedValue)(1); const thumbAnimatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { const center = width.value / 2; const rotatedHue = (hueValue.value - rotate) % 360; const distance = (width.value - sliderThickness) / 2; const angle = (rotatedHue * Math.PI) / 180; const posY = width.value - (Math.sin(angle) * distance + center) - thumbSize / 2; const posX = width.value - (Math.cos(angle) * distance + center) - thumbSize / 2; return { transform: [ { translateX: posX, }, { translateY: posY, }, { scale: handleScale.value, }, { rotate: rotatedHue + 90 + 'deg', }, ], }; }, [width, hueValue, handleScale, thumbSize, sliderThickness, rotate]); const activeSaturationStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { if (!adaptSpectrum) { return {}; } return { backgroundColor: (0, _utils.HSVA2HSLA_string)(0, 0, brightnessValue.value, 1 - saturationValue.value / 100), }; }, [brightnessValue, saturationValue, adaptSpectrum]); const activeBrightnessStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { if (!adaptSpectrum) { return {}; } return { backgroundColor: (0, _utils.HSVA2HSLA_string)(0, 0, 0, 1 - brightnessValue.value / 100), }; }, [brightnessValue, adaptSpectrum]); const clipViewStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => { return { position: 'absolute', width: width.value - sliderThickness * 2, height: width.value - sliderThickness * 2, borderRadius: width.value / 2, }; }, [width, sliderThickness]); const onBegin = ({ x, y }) => { 'worklet'; const radius = width.value / 2; const dx = radius - x; const dy = radius - y; const pressDistance = Math.sqrt(dx * dx + dy * dy); // Check if the press is outside the circle if (pressDistance > radius) { isGestureActive.value = false; return; } // check if the press inside the circle (not on the actual slider) const innerR = width.value / 2 - sliderThickness; if (pressDistance < innerR) { isGestureActive.value = false; return; } isGestureActive.value = true; handleScale.value = (0, _reactNativeReanimated.withTiming)(thumbScaleAnimationValue, { duration: thumbScaleAnimationDuration, }); }; const onUpdate = newValue => { 'worklet'; if (hueValue.value === newValue) { return; } hueValue.value = newValue; onGestureChange(); }; const onGestureUpdate = ({ x, y }) => { 'worklet'; if (!isGestureActive.value) return; const center = width.value / 2; const dx = center - x; const dy = center - y; const theta = Math.atan2(dy, dx) * (180 / Math.PI); // [0 - 180] range const angle = theta < 0 ? 360 + theta : theta; // [0 - 360] range const newHueValue = (angle + rotate) % 360; onUpdate(newHueValue); }; const onEnd = () => { 'worklet'; isGestureActive.value = false; handleScale.value = (0, _reactNativeReanimated.withTiming)(1, { duration: thumbScaleAnimationDuration, }); onGestureEnd(); }; const getAdaptiveColor = hsva => { 'worklet'; if (adaptSpectrum) { return hsva; } return { h: hsva.h, s: 100, v: 100, }; }; return /*#__PURE__*/ _react.default.createElement( _CircularSliderCore.CircularSliderCore, { style: [ _styles.styles.panelContainer, { justifyContent: 'center', alignItems: 'center', }, style, { position: 'relative', aspectRatio: 1, borderWidth: 0, padding: 0, }, borderRadiusStyle, ], label: props.accessibilityLabel ?? 'Hue circular slider', hint: props.accessibilityHint, currentValue: hueValue, maxValue: 360, width: width, borderRadius: borderRadius, gestures: gestures, onGestureUpdate: onGestureUpdate, onBegin: onBegin, onUpdate: onUpdate, onEnd: onEnd, }, /*#__PURE__*/ _react.default.createElement( _reactNative.ImageBackground, { source: require('../../../assets/circularHue.png'), style: [ _styles.styles.panelImage, { transform: [ { rotate: -rotate + 'deg', }, ], }, ], resizeMode: 'stretch', 'aria-hidden': true, }, /*#__PURE__*/ _react.default.createElement( _utils.ConditionalRendering, { if: adaptSpectrum, }, /*#__PURE__*/ _react.default.createElement(_reactNativeReanimated.default.View, { style: [borderRadiusStyle, activeBrightnessStyle, _reactNative.StyleSheet.absoluteFill], }), /*#__PURE__*/ _react.default.createElement(_reactNativeReanimated.default.View, { style: [borderRadiusStyle, activeSaturationStyle, _reactNative.StyleSheet.absoluteFill], }), ), ), /*#__PURE__*/ _react.default.createElement( _reactNativeReanimated.default.View, { style: [ clipViewStyle, { backgroundColor: '#fff', }, containerStyle, ], }, children, ), /*#__PURE__*/ _react.default.createElement(_Thumb.default, { thumbShape: thumbShape, thumbSize: thumbSize, thumbColor: thumbColor, renderThumb: renderThumb, innerStyle: thumbInnerStyle, thumbAnimatedStyle: thumbAnimatedStyle, style: thumbStyle, getAdaptiveColor: getAdaptiveColor, }), ); }