Color Picker
document.body.innerHTML = ''; var ColorPicker = class { constructor(size=150, parent) { var wrap = document.createElement('div'); (parent || document.body).appendChild(wrap); var shadow = wrap.shadowRoot || wrap.attachShadow({mode: 'open'}); var style = document.createElement('style'); style.innerHTML = ` :host { --transparent: linear-gradient(45deg, #eee 25%, transparent 0, transparent 75%, #eee 0) 0 0/14px 14px, linear-gradient(45deg, #eee 25%, transparent 0, transparent 75%, #eee 0) 7px 7px/14px 14px; } :host hr { border: none; margin: 0; padding: 0; } :host .range_wrap { background: var(--transparent); display: inline-block; position: relative; } :host .range_wrap input[type="range"] { -webkit-appearance: none; background: linear-gradient(90deg, rgba(0,0,0,0), rgba(0,0,0,1)); border: none; cursor: pointer; display: block; height: 1em; margin: 0; padding: 0; width: calc(var(--range_size) * 1px); } :host .range_wrap input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; -moz-appearance: none; width: 0; height: 0; } :host .range_wrap label { background: rgb(255, 255, 255); border-radius: 50%; box-shadow: rgb(170 170 170) 1px 1px 3px; display: block; height: 1em; left: calc(var(--value) / 255 * (var(--range_size) * 1px - 1em)); pointer-events: none; position: absolute; top: 0px; width: 1em; } :host .range_wrap:focus-within label { outline: 2px solid #4d90fe; } `; this.picker = document.createElement('canvas'); this.strip = document.createElement('canvas'); var range = document.createElement('div'); var hr = document.createElement('hr'); range.classList.add('range_wrap'); this.opacity = document.createElement('input'); this.opacity.type = 'range'; this.opacity.max = 255; this.opacity.value = 255; var label = document.createElement('label'); label.style.setProperty('--value', 255); this.opacity.__label__ = label; [this.opacity, label].forEach(v => range.appendChild(v)); [style, this.picker, this.strip, hr, range].forEach(v => shadow.appendChild(v)); this.p_ctx = this.picker.getContext('2d'); this.s_ctx = this.strip.getContext('2d'); this.picker.height = parseInt(size * 5 / 6); this.picker.width = parseInt(size); this.strip.height = parseInt(size * 5 / 6); this.strip.width = parseInt(size / 4); range.style.setProperty('--range_size', parseInt(size / 4) + parseInt(size)); this.current_color = 'rgba(255, 0, 0, 1)'; this.update(this.current_color); this.createStrip(); this.picker.onclick = e => { var data = this.p_ctx.getImageData(e.offsetX, e.offsetY, 1, 1).data; this.current_color = `rgba(${data.slice(0, 3).join(', ')}, ${parseInt(this.opacity.value / 255 * 100) / 100})`; console.log( this.current_color ); }; this.strip.onclick = e => { var data = this.s_ctx.getImageData(e.offsetX, e.offsetY, 1, 1).data.slice(0, 3); this.update(`rgba(${data.join(', ')}, 1)`); }; this.opacity.oninput = e => e.target.__label__.style.setProperty('--value', e.target.value); } createStrip() { this.s_ctx.rect(0, 0, this.strip.width, this.strip.height); var grd = this.s_ctx.createLinearGradient(0, 0, 0, this.strip.height); var colors = ['rgba(255, 0, 0, 1)', 'rgba(255, 255, 0, 1)', 'rgba(0, 255, 0, 1)', 'rgba(0, 255, 255, 1)', 'rgba(0, 0, 255, 1)', 'rgba(255, 0, 255, 1)', 'rgba(255, 0, 0, 1)'] colors.forEach((v, i) => grd.addColorStop(i / colors.length, v)); this.s_ctx.fillStyle = grd; this.s_ctx.fill(); } update(color) { this.p_ctx.fillStyle = color; this.p_ctx.fillRect(0, 0, this.picker.width, this.picker.height); var grdWhite = this.s_ctx.createLinearGradient(0, 0, this.picker.width, 0); grdWhite.addColorStop(0, 'rgba(255, 255, 255, 1)'); grdWhite.addColorStop(1, 'rgba(255, 255, 255, 0)'); this.p_ctx.fillStyle = grdWhite; this.p_ctx.fillRect(0, 0, this.picker.width, this.picker.height); var grdBlack = this.s_ctx.createLinearGradient(0, 0, 0, this.picker.height); grdBlack.addColorStop(0, 'rgba(0, 0, 0, 0)'); grdBlack.addColorStop(1, 'rgba(0, 0, 0, 1)'); this.p_ctx.fillStyle = grdBlack; this.p_ctx.fillRect(0, 0, this.picker.width, this.picker.height); } }; new ColorPicker();
page revision: 0, last edited: 17 Mar 2022 08:46






