You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用前端技术创建类似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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 23:54:03