react-best-gradient-color-picker
Advanced tools
Comparing version 2.0.5 to 2.0.6
@@ -1,5 +0,5 @@ | ||
import React, { createContext, useContext, useState, useEffect } from 'react'; | ||
import { computePickerPosition, getGradientType, computeSquareXY, getDegrees, getNewHsl, getHandleValue, isUpperCase } from './utils'; | ||
import { low, high, getColors } from './formatters'; | ||
import { config } from './constants'; | ||
import React, { createContext, useContext, useState, useEffect } from "react"; | ||
import { computePickerPosition, getGradientType, computeSquareXY, getDegrees, getNewHsl, getHandleValue, isUpperCase } from "./utils"; | ||
import { low, high, getColors } from "./formatters"; | ||
import { config } from "./constants"; | ||
@@ -20,6 +20,6 @@ var tinycolor = require("tinycolor2"); | ||
const offsetLeft = bounds?.x; | ||
const isGradient = value?.includes('gradient'); | ||
const isGradient = value?.includes("gradient"); | ||
const gradientType = getGradientType(value); | ||
const degrees = getDegrees(value); | ||
const degreeStr = gradientType === 'linear-gradient' ? `${degrees}deg` : 'circle'; | ||
const degreeStr = gradientType === "linear-gradient" ? `${degrees}deg` : "circle"; | ||
const colors = getColors(value); | ||
@@ -34,6 +34,3 @@ const indexedColors = colors?.map((c, i) => ({ ...c, | ||
const [tinyColor, setTinyColor] = useState(tinycolor(currentColor)); | ||
const [inputType, setInputType] = useState('rgb'); | ||
useEffect(() => { | ||
setTinyColor(tinycolor(currentColor)); | ||
}, [currentColor]); | ||
const [inputType, setInputType] = useState("rgb"); | ||
const { | ||
@@ -54,2 +51,3 @@ r, | ||
} = tinyColor.toHsv(); | ||
const [internalHue, setInternalHue] = useState(Math.round(h)); | ||
const hue = Math.round(h); | ||
@@ -60,2 +58,6 @@ const [x, y] = computeSquareXY([hue, s, l]); | ||
useEffect(() => { | ||
setTinyColor(tinycolor(currentColor)); | ||
setInternalHue(hue); | ||
}, [currentColor, hue]); | ||
useEffect(() => { | ||
if (isGradient) { | ||
@@ -74,3 +76,3 @@ setPreviousGradients([value, ...previousGraidents?.slice(0, 4)]); | ||
let colorString = sorted?.map(cc => `${cc?.value} ${cc.left}%`); | ||
onChange(`${gradientType}(${degreeStr}, ${colorString.join(', ')})`); | ||
onChange(`${gradientType}(${degreeStr}, ${colorString.join(", ")})`); | ||
}; | ||
@@ -103,3 +105,3 @@ | ||
let newHue = getHandleValue(e) * 3.6; | ||
let newHsl = getNewHsl(newHue, s, l, opacity); | ||
let newHsl = getNewHsl(newHue, s, l, opacity, setInternalHue); | ||
handleChange(newHsl); | ||
@@ -167,2 +169,3 @@ }; | ||
deletePoint, | ||
internalHue, | ||
setInputType, | ||
@@ -174,2 +177,3 @@ gradientType, | ||
handleOpacity, | ||
setInternalHue, | ||
previousColors, | ||
@@ -176,0 +180,0 @@ handleGradient, |
@@ -9,3 +9,3 @@ import React, { useRef, useState } from 'react'; | ||
handleHue, | ||
hue | ||
internalHue | ||
} = usePicker(); | ||
@@ -47,3 +47,3 @@ const [dragging, setDragging] = useState(false); | ||
style: { | ||
left: hue * .766666666666667, | ||
left: internalHue * .766666666666667, | ||
top: -.5 | ||
@@ -50,0 +50,0 @@ }, |
@@ -121,7 +121,9 @@ import React, { useState, useEffect } from 'react'; | ||
l, | ||
hue, | ||
opacity | ||
internalHue, | ||
opacity, | ||
setInternalHue | ||
} = usePicker(); | ||
const handleHsl = value => { | ||
const handleH = (h, s, l) => { | ||
setInternalHue(h); | ||
let { | ||
@@ -131,2 +133,15 @@ r, | ||
b | ||
} = tc({ | ||
h: h, | ||
s: s, | ||
l: l | ||
}).toRgb(); | ||
handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
}; | ||
const handleSl = value => { | ||
let { | ||
r, | ||
g, | ||
b | ||
} = tc(value).toRgb(); | ||
@@ -137,8 +152,4 @@ handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Input, { | ||
value: round(hue), | ||
callback: newVal => handleHsl({ | ||
h: newVal, | ||
s: s, | ||
l: l | ||
}), | ||
value: round(internalHue), | ||
callback: newVal => handleH(newVal, s, l), | ||
label: "H", | ||
@@ -148,4 +159,4 @@ max: 360 | ||
value: round(s * 100), | ||
callback: newVal => handleHsl({ | ||
h: hue, | ||
callback: newVal => handleSl({ | ||
h: internalHue, | ||
s: newVal, | ||
@@ -157,4 +168,4 @@ l: l | ||
value: round(l * 100), | ||
callback: newVal => handleHsl({ | ||
h: hue, | ||
callback: newVal => handleSl({ | ||
h: internalHue, | ||
s: s, | ||
@@ -172,7 +183,9 @@ l: newVal | ||
hsvV, | ||
hue, | ||
internalHue, | ||
setInternalHue, | ||
opacity | ||
} = usePicker(); | ||
const handleHsv = value => { | ||
const handleH = (h, s, v) => { | ||
setInternalHue(h); | ||
let { | ||
@@ -182,2 +195,15 @@ r, | ||
b | ||
} = tc({ | ||
h: h, | ||
s: s, | ||
v: v | ||
}).toRgb(); | ||
handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
}; | ||
const handleSV = value => { | ||
let { | ||
r, | ||
g, | ||
b | ||
} = tc(value).toRgb(); | ||
@@ -188,14 +214,10 @@ handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Input, { | ||
value: round(hue), | ||
callback: newVal => handleHsv({ | ||
h: newVal, | ||
s: hsvS, | ||
v: hsvV | ||
}), | ||
value: round(internalHue), | ||
callback: newVal => handleH(newVal, hsvS, hsvV), | ||
label: "H", | ||
max: 360 | ||
}), /*#__PURE__*/React.createElement(Input, { | ||
value: round(hsvV * 100), | ||
callback: newVal => handleHsv({ | ||
h: hue, | ||
value: round(hsvS * 100), | ||
callback: newVal => handleSV({ | ||
h: internalHue, | ||
s: newVal, | ||
@@ -207,4 +229,4 @@ v: hsvV | ||
value: round(hsvV * 100), | ||
callback: newVal => handleHsv({ | ||
h: hue, | ||
callback: newVal => handleSV({ | ||
h: internalHue, | ||
s: hsvS, | ||
@@ -211,0 +233,0 @@ v: newVal |
import React, { useRef, useState } from "react"; | ||
import throttle from "lodash.throttle"; | ||
import usePaintSquare from "./usePaintSquare"; | ||
import { usePicker } from './context'; | ||
import { usePicker } from "./context"; | ||
@@ -11,7 +11,7 @@ const Square = () => { | ||
y, | ||
hue | ||
internalHue | ||
} = usePicker(); | ||
const [dragging, setDragging] = useState(false); | ||
const canvas = useRef(null); | ||
usePaintSquare(canvas, hue); | ||
usePaintSquare(canvas, internalHue); | ||
@@ -28,6 +28,2 @@ const handleChange = e => { | ||
const stopDraggingTest = () => { | ||
setDragging(false); | ||
}; | ||
const handleMove = e => { | ||
@@ -49,3 +45,3 @@ if (dragging) { | ||
style: { | ||
position: 'absolute', | ||
position: "absolute", | ||
left: -7, | ||
@@ -56,3 +52,3 @@ top: -7, | ||
}, | ||
onMouseEnter: stopDraggingTest | ||
onMouseEnter: stopDragging | ||
}), /*#__PURE__*/React.createElement("div", { | ||
@@ -59,0 +55,0 @@ className: "ps-rl c-cross", |
@@ -1,3 +0,3 @@ | ||
import { formatInputValues } from './formatters'; | ||
import { config } from './constants'; | ||
import { formatInputValues } from "./formatters"; | ||
import { config } from "./constants"; | ||
@@ -48,9 +48,10 @@ var tc = require("tinycolor2"); | ||
export const getDegrees = value => { | ||
let s1 = value?.split(',')[0]; | ||
return parseInt(s1?.split('(')[1]?.slice(0, -3)); | ||
let s1 = value?.split(",")[0]; | ||
return parseInt(s1?.split("(")[1]?.slice(0, -3)); | ||
}; | ||
export const getGradientType = value => { | ||
return value?.split('(')[0]; | ||
return value?.split("(")[0]; | ||
}; | ||
export const getNewHsl = (newHue, s, l, o) => { | ||
export const getNewHsl = (newHue, s, l, o, setInternalHue) => { | ||
setInternalHue(newHue); | ||
let tiny = tc({ | ||
@@ -70,4 +71,6 @@ h: newHue, | ||
let client = e.target.parentNode.getBoundingClientRect(); | ||
let className = e.target.className; | ||
let adjuster = className === "c-resize ps-rl" ? 15 : 0; | ||
return { | ||
offsetLeft: client?.x, | ||
offsetLeft: client?.x + adjuster, | ||
offsetTop: client?.y | ||
@@ -74,0 +77,0 @@ }; |
{ | ||
"name": "react-best-gradient-color-picker", | ||
"version": "2.0.5", | ||
"version": "2.0.6", | ||
"description": "An easy to use color/gradient picker for React.js", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -21,7 +21,6 @@ <div align="center"> | ||
<!-- <br /> --> | ||
<!-- <div align="center"> | ||
<img alt="" src="https://i.ibb.co/6grxb9W/Screen-Shot-2022-04-13-at-8-26-54-AM.png" width="200px"/> | ||
<img alt="" src="https://i.ibb.co/JmX6GH6/Screen-Shot-2022-04-13-at-8-26-45-AM.png" width="200px"/> | ||
</div> --> | ||
<br /> | ||
<img alt="" src="https://i.ibb.co/7yKnzdL/rbgcp2.png" width="100%" /> | ||
<br /> | ||
@@ -49,3 +48,3 @@ | ||
function MyApp() { | ||
const [color, setColor] = useState('rgba(255,255,255,1'); | ||
const [color, setColor] = useState('rgba(255,255,255,1)'); | ||
@@ -265,2 +264,4 @@ return <ColorPicker value={color} onChange={setColor} /> | ||
This still works, although most functions are available through the useColorPicker hook, if there is something you need that is not available you could use the below methods to create your desired functionality. | ||
The state of the picker is determined by parsing the value string. You can update props like colorType (solid/gradient), gradientType (linear/radial), gradientDegrees, hex, rgba, opacity and hue simply by updating the value you are passing into the component. Let's say you want to change the colorType from gradient to solid: | ||
@@ -267,0 +268,0 @@ |
@@ -1,36 +0,47 @@ | ||
import React, { createContext, useContext, useState, useEffect } from 'react'; | ||
import { computePickerPosition, getGradientType, computeSquareXY, getDegrees, getNewHsl, getHandleValue, isUpperCase } from './utils' | ||
import { low, high, getColors } from './formatters' | ||
import { config } from './constants' | ||
import React, { createContext, useContext, useState, useEffect } from "react"; | ||
import { | ||
computePickerPosition, | ||
getGradientType, | ||
computeSquareXY, | ||
getDegrees, | ||
getNewHsl, | ||
getHandleValue, | ||
isUpperCase | ||
} from "./utils"; | ||
import { low, high, getColors } from "./formatters"; | ||
import { config } from "./constants"; | ||
var tinycolor = require("tinycolor2"); | ||
const { squareSize, crossSize } = config | ||
const { squareSize, crossSize } = config; | ||
const PickerContext = createContext(); | ||
export default function PickerContextWrapper({ children, bounds, value, onChange }) { | ||
const offsetLeft = bounds?.x | ||
export default function PickerContextWrapper({ | ||
children, | ||
bounds, | ||
value, | ||
onChange | ||
}) { | ||
const offsetLeft = bounds?.x; | ||
const isGradient = value?.includes('gradient') | ||
const gradientType = getGradientType(value) | ||
const degrees = getDegrees(value) | ||
const degreeStr = gradientType === 'linear-gradient' ? `${degrees}deg` : 'circle' | ||
const isGradient = value?.includes("gradient"); | ||
const gradientType = getGradientType(value); | ||
const degrees = getDegrees(value); | ||
const degreeStr = | ||
gradientType === "linear-gradient" ? `${degrees}deg` : "circle"; | ||
const colors = getColors(value); | ||
const indexedColors = colors?.map((c, i) => ({...c, index: i})) | ||
const currentColorObj = indexedColors?.filter(c => isUpperCase(c.value))[0] || indexedColors[0] | ||
const indexedColors = colors?.map((c, i) => ({ ...c, index: i })); | ||
const currentColorObj = | ||
indexedColors?.filter(c => isUpperCase(c.value))[0] || indexedColors[0]; | ||
const currentColor = currentColorObj?.value; | ||
const selectedColor = currentColorObj?.index; | ||
const currentLeft = currentColorObj?.left | ||
const currentLeft = currentColorObj?.left; | ||
const [tinyColor, setTinyColor] = useState(tinycolor(currentColor)); | ||
const [inputType, setInputType] = useState('rgb'); | ||
const [inputType, setInputType] = useState("rgb"); | ||
useEffect(() => { | ||
setTinyColor(tinycolor(currentColor)) | ||
}, [currentColor]) | ||
const { r, g, b, a: opacity } = tinyColor.toRgb(); | ||
const { h, s, l } = tinyColor.toHsl(); | ||
const { s: hsvS, v: hsvV } = tinyColor.toHsv(); | ||
const [internalHue, setInternalHue] = useState(Math.round(h)); | ||
const hue = Math.round(h); | ||
const [x, y] = computeSquareXY([hue, s, l]); | ||
const [previousColors, setPreviousColors] = useState([]); | ||
@@ -40,70 +51,84 @@ const [previousGraidents, setPreviousGradients] = useState([]); | ||
useEffect(() => { | ||
setTinyColor(tinycolor(currentColor)); | ||
setInternalHue(hue); | ||
}, [currentColor, hue]); | ||
useEffect(() => { | ||
if (isGradient) { | ||
setPreviousGradients([value, ...previousGraidents?.slice(0, 4) ]); | ||
setPreviousGradients([value, ...previousGraidents?.slice(0, 4)]); | ||
} else { | ||
if (tinycolor(value).isValid()) { | ||
setPreviousColors([value, ...previousColors?.slice(0, 4) ]) | ||
setPreviousColors([value, ...previousColors?.slice(0, 4)]); | ||
} | ||
} | ||
//eslint-disable-next-line | ||
}, [value]) | ||
//eslint-disable-next-line | ||
}, [value]); | ||
const createGradientStr = (newColors) => { | ||
let sorted = newColors.sort((a, b) => a.left - b.left) | ||
let colorString = sorted?.map((cc) => `${cc?.value} ${cc.left}%`) | ||
onChange(`${gradientType}(${degreeStr}, ${colorString.join(', ')})`) | ||
} | ||
const createGradientStr = newColors => { | ||
let sorted = newColors.sort((a, b) => a.left - b.left); | ||
let colorString = sorted?.map(cc => `${cc?.value} ${cc.left}%`); | ||
onChange(`${gradientType}(${degreeStr}, ${colorString.join(", ")})`); | ||
}; | ||
const handleGradient = (newColor, left = currentLeft) => { | ||
let remaining = colors?.filter(c => !isUpperCase(c.value)); | ||
let newColors = [{value: newColor.toUpperCase(), left: left}, ...remaining] | ||
createGradientStr(newColors) | ||
} | ||
let newColors = [ | ||
{ value: newColor.toUpperCase(), left: left }, | ||
...remaining | ||
]; | ||
createGradientStr(newColors); | ||
}; | ||
const handleChange = (newColor) => { | ||
const handleChange = newColor => { | ||
if (isGradient) { | ||
handleGradient(newColor) | ||
handleGradient(newColor); | ||
} else { | ||
onChange(newColor) | ||
onChange(newColor); | ||
} | ||
} | ||
}; | ||
const handleOpacity = (e) => { | ||
const handleOpacity = e => { | ||
let newO = getHandleValue(e) / 100; | ||
let newColor = `rgba(${r}, ${g}, ${b}, ${newO})` | ||
handleChange(newColor) | ||
} | ||
let newColor = `rgba(${r}, ${g}, ${b}, ${newO})`; | ||
handleChange(newColor); | ||
}; | ||
const handleHue = (e) => { | ||
const handleHue = e => { | ||
let newHue = getHandleValue(e) * 3.6; | ||
let newHsl = getNewHsl(newHue, s, l, opacity); | ||
handleChange(newHsl) | ||
} | ||
let newHsl = getNewHsl(newHue, s, l, opacity, setInternalHue); | ||
handleChange(newHsl); | ||
}; | ||
const handleColor = (e, ctx) => { | ||
const [x, y] = computePickerPosition(e) | ||
const x1 = Math.min(x + crossSize / 2, squareSize - 1) | ||
const y1 = Math.min(y + crossSize / 2, squareSize - 1) | ||
const [r, g, b] = ctx.getImageData(x1, y1, 1, 1).data | ||
let newColor = `rgba(${r}, ${g}, ${b}, ${opacity})` | ||
handleChange(newColor) | ||
} | ||
const [x, y] = computePickerPosition(e); | ||
const x1 = Math.min(x + crossSize / 2, squareSize - 1); | ||
const y1 = Math.min(y + crossSize / 2, squareSize - 1); | ||
const [r, g, b] = ctx.getImageData(x1, y1, 1, 1).data; | ||
let newColor = `rgba(${r}, ${g}, ${b}, ${opacity})`; | ||
handleChange(newColor); | ||
}; | ||
const setSelectedColor = (index) => { | ||
let newGradStr = colors?.map((cc, i) => ({...cc, value: i === index ? high(cc) : low(cc)})) | ||
createGradientStr(newGradStr) | ||
} | ||
const setSelectedColor = index => { | ||
let newGradStr = colors?.map((cc, i) => ({ | ||
...cc, | ||
value: i === index ? high(cc) : low(cc) | ||
})); | ||
createGradientStr(newGradStr); | ||
}; | ||
const addPoint = (e) => { | ||
let left = getHandleValue(e, offsetLeft) | ||
let newColors = [...colors.map(c => ({...c, value: low(c)})), {value: currentColor, left: left }] | ||
createGradientStr(newColors) | ||
} | ||
const addPoint = e => { | ||
let left = getHandleValue(e, offsetLeft); | ||
let newColors = [ | ||
...colors.map(c => ({ ...c, value: low(c) })), | ||
{ value: currentColor, left: left } | ||
]; | ||
createGradientStr(newColors); | ||
}; | ||
const deletePoint = () => { | ||
if (colors?.length > 2) { | ||
let remaining = colors?.filter((rc, i) => i !== selectedColor) | ||
createGradientStr(remaining) | ||
let remaining = colors?.filter((rc, i) => i !== selectedColor); | ||
createGradientStr(remaining); | ||
} | ||
} | ||
}; | ||
@@ -135,2 +160,3 @@ const pickerState = { | ||
deletePoint, | ||
internalHue, | ||
setInputType, | ||
@@ -142,9 +168,14 @@ gradientType, | ||
handleOpacity, | ||
setInternalHue, | ||
previousColors, | ||
handleGradient, | ||
setSelectedColor, | ||
previousGraidents, | ||
previousGraidents | ||
}; | ||
return <PickerContext.Provider value={pickerState}>{children}</PickerContext.Provider>; | ||
return ( | ||
<PickerContext.Provider value={pickerState}> | ||
{children} | ||
</PickerContext.Provider> | ||
); | ||
} | ||
@@ -151,0 +182,0 @@ |
@@ -7,3 +7,3 @@ import React, { useRef, useState } from 'react' | ||
const barRef = useRef(null); | ||
const { handleHue, hue } = usePicker(); | ||
const { handleHue, internalHue } = usePicker(); | ||
const [dragging, setDragging] = useState(false) | ||
@@ -36,3 +36,3 @@ usePaintHue(barRef); | ||
<div className='c-resize ps-rl' onMouseMove={(e) => handleMove(e)}> | ||
<div style={{left: hue * .766666666666667, top: -.5}} className='handle' onMouseDown={handleDown} /> | ||
<div style={{left: internalHue * .766666666666667, top: -.5}} className='handle' onMouseDown={handleDown} /> | ||
<canvas ref={barRef} width='294px' height='14px' style={{position: 'relative', borderRadius: 14}} onClick={(e) => handleClick(e)} /> | ||
@@ -39,0 +39,0 @@ </div> |
@@ -64,5 +64,11 @@ import React, { useState, useEffect } from 'react' | ||
const HSLInputs = () => { | ||
const { handleChange, s, l, hue, opacity } = usePicker(); | ||
const { handleChange, s, l, internalHue, opacity, setInternalHue } = usePicker(); | ||
const handleHsl = (value) => { | ||
const handleH = (h, s, l) => { | ||
setInternalHue(h) | ||
let {r, g, b} = tc({h: h, s: s, l: l}).toRgb(); | ||
handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
} | ||
const handleSl = (value) => { | ||
let {r, g, b} = tc(value).toRgb(); | ||
@@ -74,5 +80,5 @@ handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
<> | ||
<Input value={round(hue)} callback={(newVal) => handleHsl({h: newVal, s: s, l: l})} label='H' max={360} /> | ||
<Input value={round(s * 100)} callback={(newVal) => handleHsl({h: hue, s: newVal, l: l})} label='S' /> | ||
<Input value={round(l * 100)} callback={(newVal) => handleHsl({h: hue, s: s, l: newVal})} label='L' /> | ||
<Input value={round(internalHue)} callback={(newVal) => handleH(newVal, s, l)} label='H' max={360} /> | ||
<Input value={round(s * 100)} callback={(newVal) => handleSl({h: internalHue, s: newVal, l: l})} label='S' /> | ||
<Input value={round(l * 100)} callback={(newVal) => handleSl({h: internalHue, s: s, l: newVal})} label='L' /> | ||
</> | ||
@@ -83,5 +89,11 @@ ) | ||
const HSVInputs = () => { | ||
const { handleChange, hsvS, hsvV, hue, opacity } = usePicker(); | ||
const { handleChange, hsvS, hsvV, internalHue, setInternalHue, opacity } = usePicker(); | ||
const handleHsv = (value) => { | ||
const handleH = (h, s, v) => { | ||
setInternalHue(h) | ||
let {r, g, b} = tc({h: h, s: s, v: v}).toRgb(); | ||
handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
} | ||
const handleSV = (value) => { | ||
let {r, g, b} = tc(value).toRgb(); | ||
@@ -93,5 +105,5 @@ handleChange(`rgba(${r}, ${g}, ${b}, ${opacity})`); | ||
<> | ||
<Input value={round(hue)} callback={(newVal) => handleHsv({h: newVal, s: hsvS, v: hsvV})} label='H' max={360} /> | ||
<Input value={round(hsvV * 100)} callback={(newVal) => handleHsv({h: hue, s: newVal, v: hsvV})} label='S' /> | ||
<Input value={round(hsvV * 100)} callback={(newVal) => handleHsv({h: hue, s: hsvS, v: newVal})} label='V' /> | ||
<Input value={round(internalHue)} callback={(newVal) => handleH(newVal, hsvS, hsvV)} label='H' max={360} /> | ||
<Input value={round(hsvS * 100)} callback={(newVal) => handleSV({h: internalHue, s: newVal, v: hsvV})} label='S' /> | ||
<Input value={round(hsvV * 100)} callback={(newVal) => handleSV({h: internalHue, s: hsvS, v: newVal})} label='V' /> | ||
</> | ||
@@ -98,0 +110,0 @@ ) |
@@ -1,51 +0,64 @@ | ||
import React, { useRef, useState } from "react" | ||
import throttle from "lodash.throttle" | ||
import usePaintSquare from "./usePaintSquare" | ||
import { usePicker } from './context' | ||
import React, { useRef, useState } from "react"; | ||
import throttle from "lodash.throttle"; | ||
import usePaintSquare from "./usePaintSquare"; | ||
import { usePicker } from "./context"; | ||
const Square = () => { | ||
const { handleColor, x, y, hue } = usePicker(); | ||
const { handleColor, x, y, internalHue } = usePicker(); | ||
const [dragging, setDragging] = useState(false); | ||
const canvas = useRef(null); | ||
usePaintSquare(canvas, hue); | ||
usePaintSquare(canvas, internalHue); | ||
const handleChange = (e) => { | ||
const handleChange = e => { | ||
const ctx = canvas?.current?.getContext("2d"); | ||
const onMouseMove = throttle(() => handleColor(e, ctx), 250) | ||
onMouseMove() | ||
} | ||
const onMouseMove = throttle(() => handleColor(e, ctx), 250); | ||
onMouseMove(); | ||
}; | ||
const stopDragging = () => { | ||
setDragging(false) | ||
} | ||
setDragging(false); | ||
}; | ||
const stopDraggingTest = () => { | ||
setDragging(false) | ||
} | ||
const handleMove = (e) => { | ||
const handleMove = e => { | ||
if (dragging) { | ||
handleChange(e) | ||
handleChange(e); | ||
} | ||
} | ||
}; | ||
const handleClick = (e) => { | ||
const handleClick = e => { | ||
if (!dragging) { | ||
handleChange(e) | ||
handleChange(e); | ||
} | ||
} | ||
}; | ||
return ( | ||
<div className='ps-rl'> | ||
<div style={{position: 'absolute', left: -7, top: -7, width: 308, height: 308}} onMouseEnter={stopDraggingTest} /> | ||
<div className='ps-rl c-cross' onMouseMove={(e) => handleMove(e)} onMouseUp={stopDragging}> | ||
<div style={{left: x, top: y}} className='handle' onMouseDown={() => setDragging(true)} /> | ||
<div className='canvas-wrapper' onClick={(e) => handleClick(e)}> | ||
<canvas ref={canvas} width='294px' height='294px' /> | ||
<div className="ps-rl"> | ||
<div | ||
style={{ | ||
position: "absolute", | ||
left: -7, | ||
top: -7, | ||
width: 308, | ||
height: 308 | ||
}} | ||
onMouseEnter={stopDragging} | ||
/> | ||
<div | ||
className="ps-rl c-cross" | ||
onMouseMove={e => handleMove(e)} | ||
onMouseUp={stopDragging} | ||
> | ||
<div | ||
style={{ left: x, top: y }} | ||
className="handle" | ||
onMouseDown={() => setDragging(true)} | ||
/> | ||
<div className="canvas-wrapper" onClick={e => handleClick(e)}> | ||
<canvas ref={canvas} width="294px" height="294px" /> | ||
</div> | ||
</div> | ||
</div> | ||
) | ||
} | ||
); | ||
}; | ||
export default Square | ||
export default Square; |
@@ -1,6 +0,6 @@ | ||
import { formatInputValues } from './formatters' | ||
import { config } from './constants' | ||
import { formatInputValues } from "./formatters"; | ||
import { config } from "./constants"; | ||
var tc = require("tinycolor2"); | ||
const { squareSize, barSize, crossSize } = config | ||
const { squareSize, barSize, crossSize } = config; | ||
@@ -10,53 +10,56 @@ export function getHandleValue(e) { | ||
let pos = e.clientX - offsetLeft - barSize / 2; | ||
let bounded = formatInputValues(pos, 0, 276) | ||
return Math.round(bounded / 2.76) | ||
let bounded = formatInputValues(pos, 0, 276); | ||
return Math.round(bounded / 2.76); | ||
} | ||
export function computeSquareXY(hsl) { | ||
const s = hsl[1] * 100 | ||
const l = hsl[2] * 100 | ||
const t = (s * (l < 50 ? l : 100 - l)) / 100 | ||
const s1 = Math.round((200 * t) / (l + t)) | 0 | ||
const b1 = Math.round(t + l) | ||
const x = (squareSize / 100) * s1 - crossSize / 2 | ||
const y = squareSize - (squareSize / 100) * b1 - crossSize / 2 | ||
return [x, y] | ||
const s = hsl[1] * 100; | ||
const l = hsl[2] * 100; | ||
const t = (s * (l < 50 ? l : 100 - l)) / 100; | ||
const s1 = Math.round((200 * t) / (l + t)) | 0; | ||
const b1 = Math.round(t + l); | ||
const x = (squareSize / 100) * s1 - crossSize / 2; | ||
const y = squareSize - (squareSize / 100) * b1 - crossSize / 2; | ||
return [x, y]; | ||
} | ||
export function computePickerPosition(e) { | ||
const { offsetLeft, offsetTop } = safeBounds(e) | ||
const { offsetLeft, offsetTop } = safeBounds(e); | ||
const getX = () => { | ||
let xPos = e.clientX - offsetLeft - crossSize / 2 | ||
return formatInputValues(xPos, -8, 284) | ||
} | ||
let xPos = e.clientX - offsetLeft - crossSize / 2; | ||
return formatInputValues(xPos, -8, 284); | ||
}; | ||
const getY = () => { | ||
let yPos = e.clientY - offsetTop - crossSize / 2 | ||
return formatInputValues(yPos, -8, 284) | ||
} | ||
let yPos = e.clientY - offsetTop - crossSize / 2; | ||
return formatInputValues(yPos, -8, 284); | ||
}; | ||
return [getX(), getY()] | ||
return [getX(), getY()]; | ||
} | ||
export const getDegrees = (value) => { | ||
let s1 = value?.split(',')[0] | ||
return parseInt(s1?.split('(')[1]?.slice(0,-3)) | ||
} | ||
export const getDegrees = value => { | ||
let s1 = value?.split(",")[0]; | ||
return parseInt(s1?.split("(")[1]?.slice(0, -3)); | ||
}; | ||
export const getGradientType = (value) => { | ||
return value?.split('(')[0] | ||
} | ||
export const getGradientType = value => { | ||
return value?.split("(")[0]; | ||
}; | ||
export const getNewHsl = (newHue, s, l, o) => { | ||
let tiny = tc({h: newHue, s: s, l: l}) | ||
export const getNewHsl = (newHue, s, l, o, setInternalHue) => { | ||
setInternalHue(newHue); | ||
let tiny = tc({ h: newHue, s: s, l: l }); | ||
let { r, g, b } = tiny.toRgb(); | ||
return `rgba(${r}, ${g}, ${b}, ${o})` | ||
} | ||
return `rgba(${r}, ${g}, ${b}, ${o})`; | ||
}; | ||
export const safeBounds = (e) => { | ||
export const safeBounds = e => { | ||
let client = e.target.parentNode.getBoundingClientRect(); | ||
return { offsetLeft: client?.x, offsetTop: client?.y} | ||
} | ||
let className = e.target.className; | ||
let adjuster = className === "c-resize ps-rl" ? 15 : 0; | ||
return { offsetLeft: client?.x + adjuster, offsetTop: client?.y }; | ||
}; | ||
export const isUpperCase = (str) => { | ||
export const isUpperCase = str => { | ||
return str?.[0] === str?.[0]?.toUpperCase(); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
157909
4554
337