I'm trying to make a reusable color color picker component in react, I want to calculate the RGB color code using the mouse coordinates on a 256 by 256 div, the div has a white background color and it has two css gradients, in it the first one is black from the bottom and transparent to the top, the second is blue to the right and transparent to the left, I'm currently assuming that blue is being picked I want to make it dynamic later, in my calculateColor
function I assume that the blue channel is y - 255
please correct me if i'm wrong, but I don't know how to calculate the red and green channel.
function calculateColor(x: number, y: number) {
const r = // ???
const g = // ???
const b = 255 - y
return `rgb(${r}, ${g}, ${b})`;
}
JSX
<div className="colors" onMouseDown={e => colorsMouseDown(e, "colors")} ref={colorsRef}>
<div className="gradient1"></div>
<div className="gradient2"></div>
<div className="picker" draggable="false" ref={colorsPickerRef} />
</div>
I tried to calculate red and green channel using Math.max
but it doesn't seem to be right because I took a screenshot of it and I picked the picked color in and it doesn't match the calculated color in the red and green channel, but it does match the blue channel.
function calculateColor(x: number, y: number) {
const r = 255 - Math.max(x, y);
const g = 255 - Math.max(x, y);
const b = 255 - y
return \`rgb(${r}, ${g}, ${b})\`;
}
CSS
.ColorPicker .colors {
grid-area: 1 / 1 / 2 / 2;
overflow: hidden;
position: relative;
background-color: #fff;
}
.ColorPicker .colors .gradient1,
.ColorPicker .colors .gradient2 {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.ColorPicker .colors .gradient1 {
background: linear-gradient(to left, #00f, transparent);
}
.ColorPicker .colors .gradient2 {
background: linear-gradient(0deg, #000, transparent);
}
You have two overlapping divs. The lower div is blue and the upper div is black. Both divs have a gradient for transparency. At the bottom, the black div has no transparency. At the right, the blue div has no transparency.
First, I calculate the blue background div
255 - x
and then the black div:
function calculateColor(x, y) {
const r = g = Math.round((255 - x) * (255 - y) / 255);
const b = 255 - y;
return `rgb(${r}, ${g}, ${b})`;
}
console.log(calculateColor(174, 157));