JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
<div class="colorPicker">
<div class="colorPicker-palette">
<div class="colorPicker-palette-pointer"></div>
</div>
<div class="colorPicker-hue">
<div class="colorPicker-hue-pointer"></div>
</div>
<div class="colorPicker-alpha">
<div class="colorPicker-alpha-backgroundColor"></div>
<div class="colorPicker-alpha-pointer"></div>
</div>
</div>
CSS
.colorPicker {
display: inline-flex;
padding: 10px;
background: #fff;
border: 1px solid rgba(0,0,0,0.2);
border-radius: 2px;
}
.colorPicker-palette {
background: #f00;
width: 200px;
height: 200px;
position: relative;
margin-right: 10px;
box-shadow: 0 0 0 1px rgba(0,0,0,0.2);
border-radius: 2px;
}
.colorPicker-palette::before,
.colorPicker-palette::after {
display: block;
content: ' ';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
border-radius: 2px;
}
.colorPicker-palette::before {
background: linear-gradient(to right, #fff 0%, rgba(255,255,255,0) 100%);
}
.colorPicker-palette::after {
background: linear-gradient(to bottom, transparent 0%, #000 100%);
}
.colorPicker-hue {
width: 20px;
height: 200px;
margin-right: 10px;
position: relative;
background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
box-shadow: 0 0 0 1px rgba(0,0,0,0.2);
border-radius: 2px;
}
.colorPicker-alpha {
width: 20px;
height: 200px;
position: relative;
background: linear-gradient(45deg, #aaa 25%, transparent 25%, transparent 75%, #aaa 75%, #aaa),
linear-gradient(45deg, #aaa 25%, transparent 25%, transparent 75%, #aaa 75%, #aaa);
background-size: 10px 10px;
background-position: 0 0, 5px 5px;
box-shadow: 0 0 0 1px rgba(0,0,0,0.2);
border-radius: 2px;
}
.colorPicker-alpha-backgroundColor {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(to bottom, #f00 0%, rgba(255, 0, 0, 0) 100%);
border-radius: 2px;
}
/* Pointers */
.colorPicker-palette-pointer {
width: 8px;
height: 8px;
transform: translate(-50%, -50%);
border-radius: 999px;
border: 1px solid #000;
box-shadow: 0 0 0 1px #fff;
position: absolute;
z-index: 80;
}
.colorPicker-hue-pointer,
.colorPicker-alpha-pointer {
width: 22px;
height: 3px;
transform: translate(-50%, -50%);
border-radius: 2px;
border: 1px...
JavaScript
let colorPicker = document.querySelector('.colorPicker');
let colorPickerPalette = document.querySelector('.colorPicker-palette');
let colorPickerPalettePointer = document.querySelector('.colorPicker-palette-pointer');
let hue = 0;
let shade = 0;
let lightness = 0;
let alpha = 1;
let paletteMouseDown = false;
colorPickerPalette.addEventListener('mousedown', function() {
paletteMouseDown = true;
});
window.addEventListener('mouseup', function() {
paletteMouseDown = false;
});
function updatePalettePointer(e, force) {
if(paletteMouseDown || force) {
let bounds = colorPickerPalette.getBoundingClientRect();
let x = e.clientX - bounds.left;
let y = e.clientY - bounds.top;
x = Math.min(200, Math.max(0, x));
y = Math.min(200, Math.max(0, y));
colorPickerPalettePointer.style.top = y + 'px';
colorPickerPalettePointer.style.left = x + 'px';
}
}
window.addEventListener('mousemove', updatePalettePointer);
colorPickerPalette.addEventListener('click', function(e){ updatePalettePointer(e, true); });
let colorPickerHue = document.querySelector('.colorPicker-hue');
let colorPickerHuePointer = document.querySelector('.colorPicker-hue-pointer');
let hueMouseDown = false;
colorPickerHue.addEventListener('mousedown', function() {
hueMouseDown = true;
});
window.addEventListener('mouseup', function() {
hueMouseDown = false;
});
function updateHuePointer(e, force) {
if(hueMouseDown || force) {
let bounds = colorPickerHue.getBoundingClientRect();
let y = e.clientY - bounds.top;
y = Math.min(200, Math.max(0, y));
hue = y / colorPickerHue.offsetHeight * 360;
colorPickerPalette.style.background = 'hsl(' + hue + ', 100%, 50%)';
colorPickerHuePointer.style.top = y + 'px';
}
}
window.addEventListener('mousemove', updateHuePointer);
colorPickerHue.addEventListener('click', function(e){ updateHuePointer(e, true); });
let colorPickerAlpha = document.querySelector('.colorPicker-alpha');
let colorPickerAlphaPointer =...