ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

antd ColorPicker 渐变色模式实战:用 `mode` 在单色与线性渐变之间自由切换

antd ColorPicker 渐变色模式实战:用 `mode` 在单色与线性渐变之间自由切换 antd ColorPicker 渐变色模式实战用mode在单色与线性渐变之间自由切换【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design导读ColorPicker 组件默认只能选取单一颜色而通过 5.20.0 版本新增的mode配置可以让同一个选择器同时支持单色single与渐变gradient两种取值形态甚至在两者之间动态切换。本文以官方演示 line-gradient 为主线结合仓库源码讲解mode的完整用法、渐变色值的数据结构、Color.toCssString()的输出格式以及模式切换背后状态同步的实现原理读完后你可以直接在自己的表单与设计工具类场景中落地渐变取色能力。mode到底是什么single 与 gradient 两种选择器模式按官方 API 文档见 index.zh-CN.md的定义ColorPicker 的mode属性用于配置选择器是单色还是渐变参数说明类型默认值引入版本mode选择器模式用于配置单色与渐变single \| gradient \| (single \| gradient)[]single5.20.0要点如下不传mode等效于single面板内只出现单色取色器饱和度/明度面与色相滑块这是组件默认行为传modegradient面板直接呈现渐变编辑态可拖拽色标、调整位置百分比传mode{[single, gradient]}面板顶部会出现单色 / 渐变两个 Tab允许用户在使用过程中自行切换两种形态适合需求不确定或要兼顾两种取色能力的场景。其类型定义位于 interface.tsexport type ModeType single | gradient;。此外面板切换按钮所用的文案也来自组件国际化配置在 locale 文件中对应singleColor单色与gradientColor渐变两项。逐行拆解官方 demoline-gradient.tsx官方演示的完整源码见 line-gradient.tsx核心代码如下import React from react; import { ColorPicker, Space } from antd; const DEFAULT_COLOR [ { color: rgb(16, 142, 233), percent: 0, }, { color: rgb(135, 208, 104), percent: 100, }, ]; const Demo () ( Space vertical ColorPicker defaultValue{DEFAULT_COLOR} allowClear showText mode{[single, gradient]} onChangeComplete{(color) { console.log(color.toCssString()); }} / ColorPicker defaultValue{DEFAULT_COLOR} allowClear showText modegradient onChangeComplete{(color) { console.log(color.toCssString()); }} / /Space ); export default Demo;这个 demo 里其实同时示范了四条核心能力默认值即是一个渐变defaultValue传的是{ color, percent }数组percent: 0表示渐变起点percent: 100表示渐变终点组件据此识别出这是一个渐变颜色与单色字符串/Color对象区分开来模式选择第一个 ColorPicker 允许用户在单色/渐变间切换第二个则锁定为modegradient可清除allowClear允许清空所选颜色结果输出showText在触发器上展示颜色文本onChangeComplete在用户完成选择时回调其参数是包装后的Color实例通过color.toCssString()得到可直接用于 CSS 的字符串。onChangeComplete与单色模式下的onChange(value, css)回调不同其回调签名在 index.zh-CN.md 中定义为(value: Color) void并且受控使用value时拖拽过程中展示的中间颜色不会被即时回写从而避免受控场景下拖拽卡顿。渐变色值的内部结构ColorType 与颜色停靠点defaultValue之所以能表示渐变是因为官方在ColorType类型中专门定义了颜色数组这一分支见 index.zh-CN.mdtype ColorType | string | Color | { color: string; percent: number; }[];也就是说ColorPicker 的取值状态分为三种形态普通色字符串、选择器生成的Color对象、以及由若干颜色 百分比组成的渐变停靠点gradient stops数组。数组中的每一项都包含color该停靠点的颜色值示例中用的是rgb(16, 142, 233)这类 RGB 写法percent该停靠点在渐变线上的位置百分比取值范围通常为0起点到100终点。内部实现中这一数组会被包装为AggregationColor定义在 color.ts。AggregationColor对外暴露了几个与渐变强相关的实例方法isGradient()返回true/false用于判断当前颜色是否为渐变实现见 color.tsgetColors()返回内部停靠点数组非渐变时则退化为自身作为唯一停靠点、percent 为 0的单元素数组见 color.tstoCssString()将颜色序列化成 CSS 字符串。toCssString()的输出linear-gradient(90deg, ...)toCssString()是官方在 5.20.0 加入并写进 API 文档的方法见 index.zh-CN.md其职责是转换成 CSS 支持的格式。对于渐变值底层实现见 color.ts会先按百分比升序把各停靠点格式化为rgb(...) X%再拼接成标准线性渐变字符串// color.ts 中 toCssString 的核心逻辑示意 const colorsStr colors.map((c) ${c.color.toRgbString()} ${c.percent}%).join(, ); return linear-gradient(90deg, ${colorsStr});因此 demo 中DEFAULT_COLOR蓝色 → 绿色0% → 100%经color.toCssString()得到的实际输出形如linear-gradient(90deg, rgb(16, 142, 233) 0%, rgb(135, 208, 104) 100%)这条字符串可以直接赋给 CSS 的background/background-image属性从而让组件与业务样式无缝衔接。而非渐变的单色值走的是另一分支直接返回this.metaColor.toRgbString()形式的rgb(r, g, b)字符串。模式与颜色如何保持同步useModeColor 的内部逻辑当mode允许两种模式而用户又改了颜色形态时组件必须保证当前展示的模式与当前颜色值的形态始终一致这一职责由自定义 Hook useModeColor.ts 承担。从源码可以归纳出以下关键设计模式列表归一化入参mode被统一归一化为数组过滤空值若为空则回退为[single]对应默认值single随后按single、gradient的顺序生成面板 Tab 的可选项见 useModeColor.ts模式跟随颜色自动对齐每当颜色值变化都会执行setModeState(postColor.isGradient() ? gradient : single)即渐变值出现 → 面板自动切到渐变模式清成单色 → 自动切回单色模式见 useModeColor.ts受限模式下的兜底如果外部传入的mode不允许当前内部 modeState例如只允许gradient却被切到了singlepostMode会回退到可选项中的第一个从而保证渲染的模式永远落在合法集合内见 useModeColor.ts。也就是说即使你只传modegradient而不关心颜色形态组件内部也会用颜色自身的渐变/单色状态去对齐当前激活的 Tab开发者无需自己维护两套状态。单色 ↔ 渐变切换时的体验细节颜色缓存策略在 ColorPicker.tsx 中还有一个值得注意的体验优化当用户在单色与渐变间切换模式时源码注释明确写道To enhance user experience, we cache the gradient color when switch from gradient to single. If user not modify single color, we will use the cached gradient color.对应的实现逻辑是见 ColorPicker.tsx 附近的处理从渐变切到单色时会取渐变第一个停靠点的颜色作为单色值onInternalChange(new AggregationColor(mergedColor.getColors()[0].color))但从单色切回渐变时如果用户没有手动修改过单色组件会优先恢复之前缓存的渐变颜色cachedGradientColor避免切换后渐变配置丢失拖拽渐变过程中的中间态由gradientDragging状态标记配合onChangeComplete保证拖拽预览与完成提交两种语义的分离。进阶用 presets 提供预设渐变如果你希望把渐变作为可一键选中的预设提供给用户可以参考同一主题下的 presets-line-gradient 演示 及其源码 presets-line-gradient.tsx。其做法是把若干组两个颜色停靠点组合成预设项const PRESET_COLORS [ [rgb(42, 188, 191), rgb(56, 54, 221)], [rgb(34, 73, 254), rgb(199, 74, 168)], [rgb(255, 111, 4), rgb(243, 48, 171)], [rgb(244, 170, 6), rgb(229, 70, 49)], ]; ColorPicker mode{[single, gradient]} presets{[ { label: Liner, defaultOpen: true, colors: PRESET_COLORS.map((colors) [ { color: colors[0], percent: 0 }, { color: colors[1], percent: 100 }, ]), }, ]} /presets的类型为 PresetColorTypetype PresetColorType { label: React.ReactNode; defaultOpen?: boolean; key?: React.Key; colors: ColorType[]; };其中每个分组的colors直接复用ColorType因此既可以放单色字符串也可以放颜色 percent数组构成的渐变。defaultOpen: true让该预设分组在面板打开时默认展开用户点击即可应用渐变通常和mode{[single, gradient]}搭配使用更顺手。测试与行为验证仓库的 gradient.test.tsx 对渐变行为给出了可验证的断言例如当选择结果由渐变完成时color.toCssString()返回linear-gradient(90deg, rgb(255, 0, 0) 0%)这类标准字符串多停靠点渐变同样会被正确序列化为完整的linear-gradient(...)表达式。此外color.ts 中equals()的实现说明两个渐变颜色的相等判断是逐停靠点比较的要求停靠点数量一致且每个停靠点的percent与颜色逐一相等。这也提醒开发者若在受控场景下想判断渐变是否发生变化不能只比较toCssString()之外的非规范化字符串应统一使用组件生成的Color对象进行比对。受控使用与 FAQ为什么推荐用 Color 对象赋值渐变涉及多个停靠点若受控值来自手工拼接的颜色字符串再做格式互转会引入精度误差。官方 FAQ见 index.zh-CN.md明确建议受控场景推荐直接使用选择器生成的Color对象来赋值而不是字符串色值这样可以避免不同格式间的换算精度问题保证取值精准、选择器按预期工作。综合来看mode与渐变能力使得 antd ColorPicker 从单一取色器升级为可承载设计稿色板的取值控件给defaultValue一组{ color, percent }即可回填渐变配合mode控制切换自由度再用onChangeComplete的toCssString()把结果无缝注入业务样式。相关源码文件useModeColor.ts、color.ts、ColorPicker.tsx与测试gradient.test.tsx都可以作为进一步深入研读的起点。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表