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'); selectedColorDiv.addEventListener('click', () => { const dropdownContent = this.shadowRoot.querySelector('.dropdown-content'); dropdownContent.style.display = dropdownContent.style.display === 'block' ? 'none' : 'block'; }); 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); 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); }); } // 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; this.setHueLabel(hue); this.hideDropdown(); 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; }else 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; } } customElements.define('hue-select', HueSelect);