npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dp-color-picker

v1.0.4

Published

A color picker component with gradient support for Vue 3

Downloads

211

Readme

dp-color-picker 是一款基于 Vue 3 + TypeScript 开发的高级颜色选择器组件。它不仅支持标准的单色(Solid)选择,还内置了强大的渐变色(Gradient)编辑功能。组件集成了透明度调节、HSV/RGB/HEX 格式切换、系统预设颜色面板以及智能的“最近使用颜色”记录功能。其设计目标是为开发者提供一个开箱即用、交互流畅且高度可配置的色彩解决方案,适用于各类设计工具、后台管理系统及个性化配置场景。

技术依赖:

  • Vue: ^3.5.24

效果预览

| 单色模式 | 渐变模式 | | :---: | :---: | | | |


2. 能力说明

| 功能模块 | 功能点 | 说明 | |:--------|:-------|:-----| | 色彩模式 | 单色/渐变切换 | 支持纯色、线性渐变(Linear Gradient)及径向渐变(Radial Gradient)的无缝切换与编辑。 | | 色彩空间 | 多格式支持 | 支持 HEX、RGB(A)、CSS 格式输入输出;内部使用 HSV 模型保证色彩计算精度。 | | 透明度 | Alpha 通道 | 提供独立的透明度滑块,支持 0-100% 透明度调节。 | | 交互体验 | 拖拽操作 | 饱和度面板、色相带、透明度带及渐变轴均支持流畅的拖拽交互,采用 RAF 优化性能。 | | 预设管理 | 系统预设 | 内置 20 种常用标准色,支持通过 Props 自定义。 | | 历史记录 | 最近使用颜色 | 自动记录用户最近选择的颜色,支持去重、持久化存储(LocalStorage)、最大数量限制及一键清除。 | | 渐变编辑 | 多色标支持 | 支持添加(双击)、删除(右击)、拖拽渐变色标(Stop),可调节渐变角度(仅线性)或切换渐变类型。 |

性能特征:

  • 高性能渲染: 拖拽交互均使用 requestAnimationFrame 进行节流处理,避免高频 DOM 操作导致的卡顿。
  • 按需更新: 仅在必要时更新 DOM 和触发计算属性。

限制条件:

  • 即使关闭 enableAlpha,内部计算仍保留 Alpha 通道,输出时会根据格式自动截断。
  • 径向渐变(Radial Gradient)目前默认使用 circle at center 形状和位置,暂不支持复杂的形状/位置自定义配置(但可正确解析和显示)。

3. Props 规范

| 参数名 | 类型 | 必填 | 默认值 | 说明 | |:-------|:-----|:-----|:-------|:-----| | modelValue | string | 是 | '#000000' | 绑定的颜色值,支持 v-model。可以是 HEX、RGBA 或 CSS 渐变字符串。 | | defaultColor | string | 否 | '#000000' | 当 modelValue 为空时的回退颜色。 | | enableAlpha | boolean | 否 | true | 是否启用透明度(Alpha)滑块及输出支持。 | | format | 'HEX' \| 'RGB' | 否 | 'HEX' | 颜色输出格式。⚠️ 注意:渐变模式下始终输出 CSS 渐变字符串。 | | swatchColors | string[] | 否 | [...] | 系统预设颜色列表。默认包含 20 种常用色。 | | recentColors | string[] | 否 | [] | 初始最近使用颜色列表。 | | enableRecentColors| boolean | 否 | true | 是否启用“最近使用颜色”功能。 | | maxCount | number | 否 | 10 | 最近使用颜色的最大记录数量(1-20)。 | | clearable | boolean | 否 | false | 是否显示清除按钮,点击可将颜色值重置为空字符串。 | | zIndex | number | 否 | 2000 | 弹出面板的 z-index 层级。 | | placement | string | 否 | 'bottom-start' | 弹出面板位置。可选:bottom-start, bottom-end, top-start, top-end。 | | threshold | number | 否 | 20 | 边缘检测阈值(像素),用于自动调整弹出位置。 | | animationDuration | number | 否 | 200 | 面板显示/隐藏动画时长(毫秒)。 | | overlay | boolean | 否 | false | 是否显示全局遮罩层。 | | showText | boolean | 否 | true | 触发器是否显示颜色文本值。 |

复杂 Props 示例

swatchColors:

const mySwatches = [
  '#FF0000', 
  'rgba(0, 255, 0, 0.5)', 
  'linear-gradient(90deg, #000 0%, #fff 100%)' // 支持渐变预设
];

4. Emit 事件说明

| 事件名 | 回调参数 | 触发时机 | |:-------|:---------|:---------| | update:modelValue | (value: string) | 当颜色发生任何变化时实时触发(拖拽、输入、点击预设)。 | | change | (value: string) | 当颜色选择面板关闭时触发。通常用于提交最终选择结果。 | | clear | () | 点击清除按钮时触发。 |


5. 使用指南

基础使用

<script setup lang="ts">
import { ref } from 'vue';
import { DpColorPicker } from 'dp-color-picker';
import 'dp-color-picker/dist/dp-color-picker.css'; // 引入样式

const color = ref('#4096ff');

const handleChange = (val: string) => {
  console.log('最终选择颜色:', val);
};
</script>

<template>
  <DpColorPicker 
    v-model="color" 
    @change="handleChange"
  />
</template>

高级配置

启用 RGB 格式输出并自定义最近使用记录数量:

<DpColorPicker 
  v-model="color"
  format="RGB"
  :enable-alpha="true"
  :enable-recent-colors="true"
  :max-count="15"
/>

常见问题

Q: 渐变色字符串无法解析? A: 组件支持标准的 CSS linear-gradientradial-gradient 格式。请确保传入的字符串格式规范,例如 linear-gradient(90deg, ...)radial-gradient(circle at center, ...)

Q: 如何禁用最近使用颜色? A: 设置 :enable-recent-colors="false" 即可隐藏该区域并停止记录。


扩展接口

组件导出了内部工具函数,可供二次开发使用:

import { 
  rgb2hex, 
  hsv2rgb, 
  parseGradient, 
  formatGradient 
} from 'dp-color-picker';

6. ECharts 图表颜色适配

组件提供了专门的 ECharts 渐变色转换工具函数,可以将选择器输出的 CSS 渐变字符串与 ECharts 的渐变对象格式互相转换,实现选择器与 ECharts 图表的无缝集成。

核心问题

dp-color-picker 输出的渐变色是 CSS 格式字符串:

"linear-gradient(180deg, rgba(84,112,198,0.8) 0%, rgba(84,112,198,0.05) 100%)"

而 ECharts 使用自己的渐变对象格式:

{
  type: 'linear',
  x: 0.5, y: 0, x2: 0.5, y2: 1,
  colorStops: [
    { offset: 0, color: 'rgba(84,112,198,0.8)' },
    { offset: 1, color: 'rgba(84,112,198,0.05)' }
  ]
}

两者方向表示方式不同:CSS 使用角度(0-360°),ECharts 使用 x/y/x2/y2 坐标对(0-1)。转换函数会自动处理这个差异。

导入方式

import {
  cssGradientToECharts,    // CSS 字符串 → ECharts 对象
  echartsGradientToCss,    // ECharts 对象 → CSS 字符串
  toEChartsGradient,       // GradientColor → ECharts 对象
  fromEChartsGradient,     // ECharts 对象 → GradientColor
} from 'dp-color-picker';

import type {
  EChartsGradient,
  EChartsLinearGradient,
  EChartsRadialGradient,
  EChartsColorStop,
} from 'dp-color-picker';

API 说明

| 函数 | 参数 | 返回值 | 说明 | |:-----|:-----|:-------|:-----| | cssGradientToECharts | (css: string) | EChartsGradient \| null | 将 CSS 渐变字符串转为 ECharts 渐变对象。解析失败返回 null。 | | echartsGradientToCss | (echarts: EChartsGradient) | string | 将 ECharts 渐变对象转为 CSS 渐变字符串。 | | toEChartsGradient | (grad: GradientColor) | EChartsGradient | 将内部 GradientColor 对象转为 ECharts 渐变对象。 | | fromEChartsGradient | (echarts: EChartsGradient) | GradientColor | 将 ECharts 渐变对象转为内部 GradientColor 对象。 |

类型定义

interface EChartsColorStop {
  offset: number;  // 0 ~ 1
  color: string;
}

interface EChartsLinearGradient {
  type: 'linear';
  x: number;   // 0 ~ 1,起点 X
  y: number;   // 0 ~ 1,起点 Y
  x2: number;  // 0 ~ 1,终点 X
  y2: number;  // 0 ~ 1,终点 Y
  colorStops: EChartsColorStop[];
}

interface EChartsRadialGradient {
  type: 'radial';
  x: number;   // 0 ~ 1,圆心 X
  y: number;   // 0 ~ 1,圆心 Y
  r: number;   // 0 ~ 1,半径
  colorStops: EChartsColorStop[];
}

type EChartsGradient = EChartsLinearGradient | EChartsRadialGradient;

方向转换规则

CSS 角度与 ECharts 坐标的对应关系:

| CSS 角度 | 渐变方向 | ECharts (x, y) → (x2, y2) | |:---------|:---------|:---------------------------| | 0deg | 下 → 上 | (0.5, 1.0) → (0.5, 0.0) | | 90deg | 左 → 右 | (0.0, 0.5) → (1.0, 0.5) | | 180deg | 上 → 下 | (0.5, 0.0) → (0.5, 1.0) | | 270deg | 右 → 左 | (1.0, 0.5) → (0.0, 0.5) | | 45deg | 左下 → 右上 | 约 (0.15, 0.85) → (0.85, 0.15) |

完整示例:折线图渐变面积

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import * as echarts from 'echarts';
import { DpColorPicker, cssGradientToECharts } from 'dp-color-picker';
import 'dp-color-picker/dist/dp-color-picker.css';

const chartRef = ref<HTMLDivElement>();
let chart: echarts.ECharts | null = null;

// 颜色选择器绑定的 CSS 渐变字符串
const areaColor = ref('linear-gradient(180deg, rgba(84,112,198,0.8) 0%, rgba(84,112,198,0.05) 100%)');

function updateChart() {
  if (!chart) return;

  // 核心:将 CSS 渐变字符串转为 ECharts 渐变对象
  const gradient = cssGradientToECharts(areaColor.value);

  chart.setOption({
    xAxis: {
      type: 'category',
      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    },
    yAxis: { type: 'value' },
    series: [{
      type: 'line',
      smooth: true,
      data: [820, 932, 901, 934, 1290, 1330, 1320],
      areaStyle: {
        color: gradient,  // 直接使用转换后的 ECharts 渐变对象
      },
    }],
  });
}

// 颜色变化时实时更新图表
watch(areaColor, updateChart);

onMounted(() => {
  if (chartRef.value) {
    chart = echarts.init(chartRef.value);
    updateChart();
  }
});
</script>

<template>
  <div style="display: flex; gap: 24px; align-items: flex-start;">
    <DpColorPicker v-model="areaColor" border />
    <div ref="chartRef" style="width: 600px; height: 400px;" />
  </div>
</template>

完整示例:柱状图渐变

<script setup lang="ts">
import { ref } from 'vue';
import * as echarts from 'echarts';
import { DpColorPicker, cssGradientToECharts } from 'dp-color-picker';
import 'dp-color-picker/dist/dp-color-picker.css';

const barColor = ref('linear-gradient(0deg, rgba(145,204,117,1) 0%, rgba(145,204,117,0.3) 100%)');

// 在构建 ECharts option 时使用
const gradient = computed(() => cssGradientToECharts(barColor.value));

const option = computed(() => ({
  xAxis: { type: 'category', data: ['A', 'B', 'C', 'D'] },
  yAxis: { type: 'value' },
  series: [{
    type: 'bar',
    data: [120, 200, 150, 80],
    itemStyle: {
      borderRadius: [4, 4, 0, 0],
      color: gradient.value,  // 柱状图渐变填充
    },
  }],
}));
</script>

完整示例:从 ECharts 配置反向加载到选择器

当你需要编辑已有的 ECharts 图表配置时,可以将 ECharts 渐变对象反向转为 CSS 字符串:

<script setup lang="ts">
import { ref } from 'vue';
import { DpColorPicker, echartsGradientToCss } from 'dp-color-picker';
import 'dp-color-picker/dist/dp-color-picker.css';

// 已有的 ECharts 渐变配置(例如从后端获取或已保存的配置)
const existingGradient = {
  type: 'linear' as const,
  x: 0, y: 0, x2: 0, y2: 1,
  colorStops: [
    { offset: 0, color: 'rgba(255, 0, 0, 0.8)' },
    { offset: 1, color: 'rgba(255, 0, 0, 0.1)' },
  ],
};

// 反向转换为 CSS 字符串,绑定到选择器
const color = ref(echartsGradientToCss(existingGradient));

// 用户修改后,再转回 ECharts 格式
import { cssGradientToECharts } from 'dp-color-picker';
// const echartsGradient = cssGradientToECharts(color.value);
</script>

<template>
  <DpColorPicker v-model="color" border />
</template>

多图表场景:组合使用

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue';
import * as echarts from 'echarts';
import { DpColorPicker, cssGradientToECharts } from 'dp-color-picker';
import 'dp-color-picker/dist/dp-color-picker.css';

const chartRef = ref<HTMLDivElement>();
let chart: echarts.ECharts | null = null;

// 分别控制折线面积和柱状图的渐变
const lineGradient = ref('linear-gradient(180deg, rgba(84,112,198,0.6) 0%, rgba(84,112,198,0.02) 100%)');
const barGradient = ref('linear-gradient(0deg, rgba(145,204,117,1) 0%, rgba(145,204,117,0.3) 100%)');

function updateChart() {
  if (!chart) return;
  chart.setOption({
    tooltip: { trigger: 'axis' },
    legend: { data: ['Revenue', 'Expenses'] },
    xAxis: {
      type: 'category',
      data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    },
    yAxis: { type: 'value' },
    series: [
      {
        name: 'Revenue',
        type: 'line',
        smooth: true,
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        itemStyle: { color: '#5470c6' },
        areaStyle: {
          color: cssGradientToECharts(lineGradient.value),
        },
      },
      {
        name: 'Expenses',
        type: 'bar',
        data: [620, 732, 701, 734, 1090, 1130, 1120],
        itemStyle: {
          borderRadius: [4, 4, 0, 0],
          color: cssGradientToECharts(barGradient.value),
        },
      },
    ],
  });
}

watch([lineGradient, barGradient], updateChart);

onMounted(() => {
  if (chartRef.value) {
    chart = echarts.init(chartRef.value);
    updateChart();
  }
});
</script>

<template>
  <div>
    <div style="display: flex; gap: 16px; margin-bottom: 16px;">
      <div>
        <label style="font-size: 14px; color: #666;">折线面积渐变</label>
        <DpColorPicker v-model="lineGradient" border />
      </div>
      <div>
        <label style="font-size: 14px; color: #666;">柱状图渐变</label>
        <DpColorPicker v-model="barGradient" border />
      </div>
    </div>
    <div ref="chartRef" style="width: 100%; height: 400px;" />
  </div>
</template>

已知限制

  • 径向渐变信息丢失:dp-color-picker 的径向渐变始终输出 circle at center。将 ECharts 径向渐变(含自定义 x/y/r)转为 CSS 再转回时,原始的位置和半径信息会丢失。
  • 角度精度:由于 atan2 浮点计算,CSS ↔ ECharts 往返转换时角度可能有 ±1° 的误差。