// Define the HueSelect custom element
class HueSelect extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
`;
this.currentHue = 0;
this.colorList;
this.hueLabel = this.shadowRoot.getElementById('hue-label');
const selectedColorDiv = this.shadowRoot.getElementById('selectedColor');
const colorPatch = selectedColorDiv.querySelector('.color-patch');
/* colorPatch.addEventListener('mouseenter', () => {
const dropdownContent = this.shadowRoot.querySelector('.dropdown-content');
dropdownContent.style.display = 'block';
}); */
// Add the global click event listener to hide the color picker dropdown
/*
window.addEventListener('click', (event) => {
const dropdownContent = this.shadowRoot.querySelector('.dropdown-content');
if (!event.target.closest('.dropdown')) {
dropdownContent.style.display = 'none';
}
}); */
selectedColorDiv.addEventListener('click', () => {
const dropdownContent = this.shadowRoot.querySelector('.dropdown-content');
dropdownContent.style.display = dropdownContent.style.display === 'block' ? 'none' : 'block';
});
// Generate the color options and add them to the dropdown
this.createColorOptions();
this.setHue(0);
}
generateColors() {
const colors = [];
for (let hue = 0; hue <= 360; hue += 10) {
if (hue == 360) { hue = 359; }
colors.push(hue);
}
colors.push(-1);
colors.push(-2);
return colors;
}
createColorOption(hue) {
const colorOption = document.createElement('div');
colorOption.classList.add('color-option');
const colorPatch = document.createElement('span');
colorPatch.classList.add('color-patch');
const colorText = document.createElement('span');
colorText.classList.add('color-text');
colorText.textContent = hue;
const rgbHex = document.createElement('span');
rgbHex.classList.add('rgb-hex');
if (hue === -2) {
colorPatch.style.backgroundColor = 'rgb(0,0,0)';
rgbHex.innerHTML = ' #000000';
} else if (hue === -1) {
colorPatch.style.backgroundColor = 'rgb(255,255,255)';
rgbHex.innerHTML = ' #FFFFFF';
} else {
colorPatch.style.backgroundColor = `hsl(${hue}, 100%, 50%)`;
const hexColor = this.hslToRgb(hue, 100, 50).toUpperCase();
rgbHex.innerHTML = ` ${hexColor}`;
}
colorOption.appendChild(colorPatch);
colorOption.appendChild(colorText);
colorOption.appendChild(rgbHex);
// Add click event listener to each color option
colorOption.addEventListener('click', () => this.handleColorSelection(hue));
return colorOption;
}
createColorOptions() {
const dropdownContent = this.shadowRoot.querySelector('.dropdown-content');
this.colorList = this.generateColors();
this.colorList.forEach(hue => {
const colorOption = this.createColorOption(hue);
dropdownContent.appendChild(colorOption);
});
// Create elements for white and black colors
//const whiteColorOption = this.createColorOption(-1);
//dropdownContent.appendChild(whiteColorOption);
//const blackColorOption = this.createColorOption(-2);
//dropdownContent.appendChild(blackColorOption);
}
// Function to convert HSL to RGB
hslToRgb(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
const toHex = (x) => {
const hex = Math.round(x * 255).toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
handleColorSelection(hue) {
this.currentHue = hue;
const selectedColorDiv = this.shadowRoot.getElementById('selectedColor');
const colorPatch = selectedColorDiv.querySelector('.color-patch');
// Update the color patch and hue label
const rgb = this.getRGBfromHue(hue);
colorPatch.style.backgroundColor = rgb;
//console.log(colorPatch.style.backgroundColor);
this.setHueLabel(hue);
this.hideDropdown();
// Dispatch a 'change' event with the selected hue value
this.dispatchEvent(new CustomEvent('change', { detail: { hue, rgb } }));
}
// Method to get the hue value of the selected item
getSelectedHue() {
return this.currentHue;
}
getSelectedRGB() {
const selectedColorText = this.shadowRoot.getElementById('selectedColor').textContent.trim();
return parseFloat(selectedColorText);
}
getRGBfromHue(hue){
if(hue == -1){
return '#FFFFFF';
}else if(hue == -2){
return '#000000';
}else{
return this.hslToRgb(hue, 100, 50);;
}
}
// Method to get the RGB value of the selected item
getSelectedRgb() {
const selectedHue = this.getSelectedHue();
return getRGBfromHue(selectedHue);
}
setHue(hue) {
// Round the input hue to the nearest 10th
let roundedHue = hue;
if(hue === -1 || hue === -2){
roundedHue = hue;
}else{
roundedHue = Math.round(hue / 10) * 10;
if (roundedHue >= 360) {
roundedHue = 359;
}
if (roundedHue < 0) {
roundedHue = 0;
}
}
this.currentHue = roundedHue;
this.colorList.forEach(colorVal => {
if (colorVal === roundedHue) {
this.handleColorSelection(roundedHue);
}
});
this.hideDropdown();
}
hideDropdown() {
const dropdownContent = this.shadowRoot.querySelector('.dropdown-content');
dropdownContent.style.display = 'none';
}
setHueLabel(value){
this.hueLabel.textContent = "Hue: " + value;
}
}
// Register the custom element
customElements.define('hue-select', HueSelect);