如何使用前端技术创建类似Phillips Hue的圆形取色器
Canvas 无外部图片圆形取色器实现方案
核心实现思路
- 完全使用 Canvas 原生渐变API绘制取色盘,无任何外部图片依赖
- 配合 CSS
border-radius: 50%实现圆形外形裁剪 - 点击事件直接读取 Canvas 像素点数据获取色值,无额外计算成本
完整可运行代码
HTML
<canvas id="colorPicker" width="300" height="300"></canvas> <p>选中坐标:<span id="coord"></span></p> <p>选中色值(RGBA):<span id="rgbaColor"></span></p> <p>选中色值(HEX):<span id="hexColor"></span></p>
CSS
#colorPicker { border-radius: 50%; cursor: crosshair; border: 2px solid #eee; }
JavaScript
const canvas = document.getElementById('colorPicker'); const ctx = canvas.getContext('2d'); const width = canvas.width; const height = canvas.height; const radius = width / 2; // 绘制取色盘 function drawPicker() { // 1. 绘制色相环底层 for (let angle = 0; angle < 360; angle++) { const startAngle = (angle - 1) * Math.PI / 180; const endAngle = angle * Math.PI / 180; ctx.beginPath(); ctx.moveTo(radius, radius); ctx.arc(radius, radius, radius, startAngle, endAngle); ctx.closePath(); ctx.fillStyle = `hsl(${angle}, 100%, 50%)`; ctx.fill(); } // 2. 叠加白色到透明的水平线性渐变(控制饱和度) const satGradient = ctx.createLinearGradient(0, 0, width, 0); satGradient.addColorStop(0, 'rgba(255,255,255,1)'); satGradient.addColorStop(1, 'rgba(255,255,255,0)'); ctx.fillStyle = satGradient; ctx.fillRect(0, 0, width, height); // 3. 叠加黑色到透明的垂直线性渐变(控制明度) const lightGradient = ctx.createLinearGradient(0, 0, 0, height); lightGradient.addColorStop(0, 'rgba(0,0,0,0)'); lightGradient.addColorStop(1, 'rgba(0,0,0,1)'); ctx.fillStyle = lightGradient; ctx.fillRect(0, 0, width, height); } // RGBA转HEX工具函数 function rgbaToHex(r, g, b) { return '#' + [r, g, b].map(x => { const hex = x.toString(16); return hex.length === 1 ? '0' + hex : hex; }).join(''); } // 点击取色逻辑 canvas.addEventListener('click', (e) => { const x = e.offsetX; const y = e.offsetY; // 判断点击是否在圆形范围内 const distance = Math.sqrt(Math.pow(x - radius, 2) + Math.pow(y - radius, 2)); if (distance > radius) return; // 获取像素色值 const pixel = ctx.getImageData(x, y, 1, 1).data; const [r, g, b, a] = pixel; const rgba = `rgba(${r}, ${g}, ${b}, ${a/255})`; const hex = rgbaToHex(r, g, b); // 输出结果 document.getElementById('coord').textContent = `x: ${x}, y: ${y}`; document.getElementById('rgbaColor').textContent = rgba; document.getElementById('hexColor').textContent = hex; }); // 初始化绘制 drawPicker();
功能说明
- 点击圆形区域内任意位置,即可获取对应点的相对坐标,以及RGBA、HEX两种格式的色值
- 所有绘图逻辑完全使用Canvas渐变实现,符合不使用内嵌图片的要求
- 额外增加了点击范围校验,点击Canvas四个角的透明区域不会触发取色逻辑
内容的提问来源于stack exchange,提问作者Jurakin
相关产品推荐
相关产品推荐

