@techui/colors 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/UPDATE.md ADDED
@@ -0,0 +1,55 @@
1
+ # @techui/colors Update Log | 更新日志
2
+
3
+ [English](#english) | [中文](#中文)
4
+
5
+ ---
6
+
7
+ ## English
8
+
9
+ ### v1.0.3 (2026-04-16)
10
+
11
+ - Added `$c.resolve` — resolves preset color names, `@`-prefixed names, and raw Hex/RGB values
12
+ - Added `$c.valid` — validates whether a color name or value is recognized
13
+ - Added `$c.expr` — expression syntax with pipe-based color transforms (e.g. `@bll5|.3`, `@bll5|lighten(2)`)
14
+ - Added `$c.genColors` — generates a semantic color scale from a base color or array
15
+ - Added `$c.genColorObj` — converts a color scale array into a semantic object (`weak/base/strong`) with optional opacity variants
16
+
17
+ ### v1.0.2 (2025-11-09)
18
+
19
+ - Added preview.html, which allows filtering, querying, and matching operations on the current color table.
20
+
21
+ ### v1.0.1 (2025-11-08)
22
+
23
+ - Internal file update, expand.less renamed to extended.less
24
+ - Minor iteration of index.js
25
+
26
+ ### v1.0.0 (2025-10-15 Removed)
27
+
28
+ - First release
29
+ - Renamed from ayin-color to @techui/colors
30
+
31
+ ---
32
+
33
+ ## 中文
34
+
35
+ ### v1.0.3 (2026-04-16)
36
+
37
+ - 新增 `$c.resolve` — 解析预定义颜色名、`@` 前缀写法及原始 Hex/RGB 值
38
+ - 新增 `$c.valid` — 校验颜色名或颜色值是否有效
39
+ - 新增 `$c.expr` — 表达式语法,支持管道式颜色变换(如 `@bll5|.3`、`@bll5|lighten(2)`)
40
+ - 新增 `$c.genColors` — 根据基础色或颜色数组生成语义色阶
41
+ - 新增 `$c.genColorObj` — 将色阶数组转换为 `weak/base/strong` 语义对象,支持附加透明度变体
42
+
43
+ ### v1.0.2 (2025-11-9)
44
+
45
+ - 新增preview.html可以对当前颜色表进行筛选查询以及匹配操作
46
+
47
+ ### v1.0.1 (2025-11-8)
48
+
49
+ - 内部文件更新,expand.less更名为extended.less
50
+ - index.js进行轻微迭代
51
+
52
+ ### v1.0.0 (2025-10-15 已移除)
53
+
54
+ - 首次发布
55
+ - 从ayin-color更名为@techui/colors
package/index.js CHANGED
@@ -1,181 +1,228 @@
1
- import chroma from "@techui/libs/chroma";
2
- import json from "./all.json";
3
- /*
4
- code by ayin86cn@gmail.com
5
- chsname:["红","红橙","橙","橙黄","黄","黄草","草绿","草绿-绿","绿","绿-水绿","水绿","水绿-青","青","青蓝","蓝","蓝靛","靛","靛紫","紫","紫粉","粉","粉-洋红","洋红","洋红-红","灰"],
6
- engname:["red","red-orange","orange","orange-yellow","yellow","yellow-chartreuse","chartreuse","chartreuse-green","green","green-aquamarine","aquamarine","aquamarine-cyan","cyan","cyan-blue","blue","blue-indigo","indigo","indigo-purple","purple","purple-pink","pink","pink-violetred","violetred","violetred-red","gray"],
7
- colors:["re","ro","or","oy","ye","yc","ch","cg","gr","ga","aq","ac","cy","cb","bl","bi","in","ip","pu","pp","pi","pv","vi","vr","gy"],
8
- */
9
- //chroma.hsl(hue, saturation, lightness)
10
- //chroma.hsv(hue, saturation, value)
11
- //chroma.lab(Lightness, a, b)
12
- //chroma.lch(Lightness, chroma, hue)
13
- //chroma.hcl(hue, chroma, lightness)
14
- //chroma.cmyk(cy, magenta, ye, black)
15
- //chroma.gl(re, gr, bl, [alpha])
16
- let illegal="Illegal color !"
17
- const coFuncs={
18
- fade:(color,num)=>{
19
- let a=json[color]?json[color]:color
20
- if(chroma.valid(a)){
21
- return chroma(a).alpha(num).hex();
22
- }else{
23
- console.warn(illegal,color,num)
24
- }
25
- },
26
- //hue色相,saturation饱和度,lightness明暗
27
- hslh:(color,num)=>{//hue色相调整
28
- let a=json[color]?json[color]:color
29
- if(chroma.valid(a)){
30
- return chroma(a).set('hsl.h', num).hex();
31
- }else{
32
- console.warn(illegal,color,num)
33
- }
34
- },
35
- hsls:(color,num)=>{//saturation饱和度
36
- let a=json[color]?json[color]:color
37
- if(chroma.valid(a)){
38
- return chroma(a).set('hsl.s', num).hex();
39
- }else{
40
- console.warn(illegal,color,num)
41
- }
42
- },
43
- hsll:(color,num)=>{//lightness明暗
44
- let a=json[color]?json[color]:color
45
- if(chroma.valid(a)){
46
- return chroma(a).set('hsl.l', num).hex();
47
- }else{
48
- console.warn(illegal,color,num)
49
- }
50
- },
51
- darken:(color,num)=>{
52
- let a=json[color]?json[color]:color
53
- if(chroma.valid(a)){
54
- return chroma(a).darken(num).hex();
55
- }else{
56
- console.warn(illegal,color,num)
57
- }
58
- },
59
- lighten:(color,num)=>{
60
- let a=json[color]?json[color]:color
61
- if(chroma.valid(a)){
62
- return chroma(a).brighten(num).hex();
63
- }else{
64
- console.warn(illegal,color,num)
65
- }
66
- },
67
- scale:(arry,num=7,mode="lch")=>{//mode=lch,hsl,lab,lrgb
68
- const newArray=[];
69
- arry.forEach((item,index)=>{
70
- if(chroma.valid(item)){
71
- newArray.push(item)
72
- }else if(chroma.valid(json[item])){
73
- newArray.push(json[item])
74
- }else{
75
- console.warn("The color set contains illegal color ",arry,index)
76
- }
77
- })
78
- if(newArray.length>0){
79
- return chroma.scale(newArray).mode(mode).colors(num)
80
- }else{
81
- console.error("The color set initialization failed ",arry)
82
- }
83
- },
84
- genColors(coIpt, count = 7, diff = 50, satReduce=true) {//,DkSatReduce=true
85
- if (!coIpt) throw new Error('The color parameter cannot be empty !');
86
- count = Math.max(2, count);
87
-
88
- if (typeof coIpt === 'string') {// 处理单个颜色
89
- if (!chroma.valid(coIpt)) throw new Error(`Invalid Color: ${coIpt}`);
90
- const color = chroma(coIpt);
91
- // 获取Lab色彩空间中的L通道值
92
- const labL = color.get('lab.l');
93
- // const colorL = color.brighten(diff);
94
- // const colorD = color.darken(diff);
95
- const lchColor = chroma(color).lch();
96
- const lchC = lchColor[1];
97
- let colorL = color.set('lab.l', Math.min(100, labL + diff));
98
- let colorD = color.set('lab.l', Math.max(0, labL - diff));
99
-
100
- if(satReduce){
101
- colorL=colorL.set('lch.c', lchC * 0.2)
102
- colorD=colorD.set('lch.c', lchC * 0.1)
103
- }
104
- const scaleC=this.scale([colorL,color,colorD], count);
105
- return scaleC
106
- }
107
- // 处理颜色数组
108
- else if (Array.isArray(coIpt)) {
109
- const validColors = coIpt.filter(c => chroma.valid(c));
110
- if (validColors.length === 0) throw new Error('No valid color value');
111
- return this.scale(coIpt, count);
112
- }
113
- throw new Error('Color parameter must be a string or array');
114
- },
115
- genColorObj(
116
- colors, //颜色值,浅色主题必须由浅入深,深色主题由深入浅
117
- opacities,
118
- names = ['weakest', 'weaker', 'weak', 'base', 'strong', 'stronger', 'strongest'],
119
- ){
120
- if (!colors || !Array.isArray(colors) || colors.length < names.length) {
121
- throw new Error(`The colors array must contain at least${names.length}`);
122
- }
123
- const result = {};
124
- names.forEach((name, index) => {
125
- result[name] = colors[index];
126
- });
127
- if (opacities) {
128
- names.forEach((name, colorIndex) => {
129
- opacities.forEach(opacity => {
130
- const opacitySuffix = `op${Math.floor(opacity * 10)}`;
131
- const propertyName = `${name}_${opacitySuffix}`;
132
- result[propertyName] = $c.fade(colors[colorIndex], opacity);
133
- });
134
- });
135
- }
136
- return result;
137
- },
138
- sort(colors) {
139
- return colors.sort((a, b) => chroma(b).luminance() - chroma(a).luminance());
140
- },
141
- viewColor(arr){
142
- console.info("viewColor",arr);
143
- arr.forEach(co => {
144
- console.info('%c ■■■■■■■■','color:'+co)
145
- });
146
- },
147
- analysis(co) {
148
- const color = chroma(co);
149
- // 获取颜色亮度 (0是黑色,1是白色)
150
- const luminance = color.luminance();
151
- // 判断颜色是深色还是浅色 (通常0.5作为分界线)
152
- const isDark = luminance < 0.5;
153
- // 计算深浅程度 (0表示最深,1表示最浅)
154
- const colorDepth = isDark ? (0.5 - luminance) * 2 : (luminance - 0.5) * 2;
155
- // 生成中间深浅度的颜色
156
- let middleColor;
157
- if (isDark) {
158
- // 如果是深色,向浅色方向调整
159
- middleColor = color.luminance(0.5 - colorDepth / 4);
160
- } else {
161
- // 如果是浅色,向深色方向调整
162
- middleColor = color.luminance(0.5 + colorDepth / 4);
163
- }
164
-
165
- return {
166
- originalColor: color.hex(),
167
- isDark: isDark,
168
- luminance: luminance,
169
- colorDepth: colorDepth,
170
- middleColor: middleColor.hex()
171
- };
172
- }
173
- }
174
- const $c = Object.assign(coFuncs, json);
175
-
176
- export default (Vue)=>{
177
- window.$c=$c
178
- window.$chroma=chroma
179
- };
1
+ import chroma from "@techui/libs/chroma";
2
+ import json from "./all.json";
3
+ /*
4
+ code by ayin86cn@gmail.com
5
+ chsname:["红","红橙","橙","橙黄","黄","黄草","草绿","草绿-绿","绿","绿-水绿","水绿","水绿-青","青","青蓝","蓝","蓝靛","靛","靛紫","紫","紫粉","粉","粉-洋红","洋红","洋红-红","灰"],
6
+ engname:["red","red-orange","orange","orange-yellow","yellow","yellow-chartreuse","chartreuse","chartreuse-green","green","green-aquamarine","aquamarine","aquamarine-cyan","cyan","cyan-blue","blue","blue-indigo","indigo","indigo-purple","purple","purple-pink","pink","pink-violetred","violetred","violetred-red","gray"],
7
+ colors:["re","ro","or","oy","ye","yc","ch","cg","gr","ga","aq","ac","cy","cb","bl","bi","in","ip","pu","pp","pi","pv","vi","vr","gy"],
8
+ */
9
+ // chroma.hsl(hue, saturation, lightness)
10
+ // chroma.hsv(hue, saturation, value)
11
+ // chroma.lab(Lightness, a, b)
12
+ // chroma.lch(Lightness, chroma, hue)
13
+ // chroma.hcl(hue, chroma, lightness)
14
+ // chroma.cmyk(cy, magenta, ye, black)
15
+ // chroma.gl(re, gr, bl, [alpha])
16
+ const illegal = "Illegal color !";
17
+ const transformFns = ["fade", "lighten", "darken", "hslh", "hsls", "hsll"];
18
+
19
+ const stripColorPrefix = (color) => {
20
+ if (typeof color !== "string") return color;
21
+ const trimmed = color.trim();
22
+ return trimmed.startsWith("@") ? trimmed.slice(1) : trimmed;
23
+ };
24
+
25
+ const resolveColor = (color) => {
26
+ if (typeof color !== "string") return color;
27
+ const name = stripColorPrefix(color);
28
+ return json[name] || name;
29
+ };
30
+
31
+ const isValidColor = (color) => chroma.valid(resolveColor(color));
32
+
33
+ const warnInvalidColor = (...args) => {
34
+ console.warn(illegal, ...args);
35
+ };
36
+
37
+ const normalizeNumber = (value) => {
38
+ const num = Number(String(value).trim());
39
+ return Number.isFinite(num) ? num : null;
40
+ };
41
+
42
+ const parseTransform = (rawTransform) => {
43
+ if (!rawTransform) return null;
44
+
45
+ const text = rawTransform.trim();
46
+ const defaultValue = normalizeNumber(text);
47
+ if (defaultValue !== null) {
48
+ return { name: "fade", value: defaultValue };
49
+ }
50
+
51
+ const matched = text.match(/^([a-zA-Z]\w*)\((.*)\)$/);
52
+ if (!matched) return null;
53
+
54
+ const name = matched[1];
55
+ const value = normalizeNumber(matched[2]);
56
+ if (!transformFns.includes(name) || value === null) return null;
57
+
58
+ return { name, value };
59
+ };
60
+
61
+ const splitExpression = (expression) => {
62
+ const pipeIndex = expression.indexOf("|");
63
+ if (pipeIndex < 0) {
64
+ return [expression.trim(), ""];
65
+ }
66
+
67
+ return [expression.slice(0, pipeIndex).trim(), expression.slice(pipeIndex + 1).trim()];
68
+ };
69
+
70
+ const coFuncs = {
71
+ resolve: resolveColor,
72
+ valid: isValidColor,
73
+ expr: (expression) => {
74
+ if (typeof expression !== "string") return expression;
75
+
76
+ const [rawColor, rawTransform] = splitExpression(expression);
77
+ const color = resolveColor(rawColor);
78
+ const transform = parseTransform(rawTransform);
79
+
80
+ if (!transform) return color;
81
+ return coFuncs[transform.name](color, transform.value);
82
+ },
83
+ fade: (color, num) => {
84
+ const resolved = resolveColor(color);
85
+ if (chroma.valid(resolved)) {
86
+ return chroma(resolved).alpha(num).hex();
87
+ }
88
+ warnInvalidColor(color, num);
89
+ },
90
+ // hue色相,saturation饱和度,lightness明暗
91
+ hslh: (color, num) => {
92
+ const resolved = resolveColor(color);
93
+ if (chroma.valid(resolved)) {
94
+ return chroma(resolved).set("hsl.h", num).hex();
95
+ }
96
+ warnInvalidColor(color, num);
97
+ },
98
+ hsls: (color, num) => {
99
+ const resolved = resolveColor(color);
100
+ if (chroma.valid(resolved)) {
101
+ return chroma(resolved).set("hsl.s", num).hex();
102
+ }
103
+ warnInvalidColor(color, num);
104
+ },
105
+ hsll: (color, num) => {
106
+ const resolved = resolveColor(color);
107
+ if (chroma.valid(resolved)) {
108
+ return chroma(resolved).set("hsl.l", num).hex();
109
+ }
110
+ warnInvalidColor(color, num);
111
+ },
112
+ darken: (color, num) => {
113
+ const resolved = resolveColor(color);
114
+ if (chroma.valid(resolved)) {
115
+ return chroma(resolved).darken(num).hex();
116
+ }
117
+ warnInvalidColor(color, num);
118
+ },
119
+ lighten: (color, num) => {
120
+ const resolved = resolveColor(color);
121
+ if (chroma.valid(resolved)) {
122
+ return chroma(resolved).brighten(num).hex();
123
+ }
124
+ warnInvalidColor(color, num);
125
+ },
126
+ scale: (arry, num = 7, mode = "lch") => {
127
+ const newArray = [];
128
+ arry.forEach((item, index) => {
129
+ const color = resolveColor(item);
130
+ if (chroma.valid(color)) {
131
+ newArray.push(color);
132
+ } else {
133
+ console.warn("The color set contains illegal color ", arry, index);
134
+ }
135
+ });
136
+ if (newArray.length > 0) {
137
+ return chroma.scale(newArray).mode(mode).colors(num);
138
+ }
139
+ console.error("The color set initialization failed ", arry);
140
+ },
141
+ genColors(coIpt, count = 7, diff = 50, satReduce = true) {
142
+ if (!coIpt) throw new Error("The color parameter cannot be empty !");
143
+ count = Math.max(2, count);
144
+
145
+ if (typeof coIpt === "string") {
146
+ const resolvedColor = resolveColor(coIpt);
147
+ if (!chroma.valid(resolvedColor)) throw new Error(`Invalid Color: ${coIpt}`);
148
+ const color = chroma(resolvedColor);
149
+ const labL = color.get("lab.l");
150
+ const lchColor = chroma(color).lch();
151
+ const lchC = lchColor[1];
152
+ let colorL = color.set("lab.l", Math.min(100, labL + diff));
153
+ let colorD = color.set("lab.l", Math.max(0, labL - diff));
154
+
155
+ if (satReduce) {
156
+ colorL = colorL.set("lch.c", lchC * 0.2);
157
+ colorD = colorD.set("lch.c", lchC * 0.1);
158
+ }
159
+ return coFuncs.scale([colorL, color, colorD], count);
160
+ }
161
+
162
+ if (Array.isArray(coIpt)) {
163
+ const validColors = coIpt.map(resolveColor).filter((color) => chroma.valid(color));
164
+ if (validColors.length === 0) throw new Error("No valid color value");
165
+ return coFuncs.scale(coIpt, count);
166
+ }
167
+ throw new Error("Color parameter must be a string or array");
168
+ },
169
+ genColorObj(
170
+ colors,
171
+ opacities,
172
+ names = ["weakest", "weaker", "weak", "base", "strong", "stronger", "strongest"]
173
+ ) {
174
+ if (!colors || !Array.isArray(colors) || colors.length < names.length) {
175
+ throw new Error(`The colors array must contain at least${names.length}`);
176
+ }
177
+ const result = {};
178
+ names.forEach((name, index) => {
179
+ result[name] = colors[index];
180
+ });
181
+ if (opacities) {
182
+ names.forEach((name, colorIndex) => {
183
+ opacities.forEach((opacity) => {
184
+ const opacitySuffix = `op${Math.floor(opacity * 10)}`;
185
+ const propertyName = `${name}_${opacitySuffix}`;
186
+ result[propertyName] = coFuncs.fade(colors[colorIndex], opacity);
187
+ });
188
+ });
189
+ }
190
+ return result;
191
+ },
192
+ sort(colors) {
193
+ return [...colors].sort((a, b) => chroma(resolveColor(b)).luminance() - chroma(resolveColor(a)).luminance());
194
+ },
195
+ viewColor(arr) {
196
+ console.info("viewColor", arr);
197
+ arr.forEach((co) => {
198
+ console.info("%c ■■■■■■■■", "color:" + co);
199
+ });
200
+ },
201
+ analysis(co) {
202
+ const color = chroma(resolveColor(co));
203
+ const luminance = color.luminance();
204
+ const isDark = luminance < 0.5;
205
+ const colorDepth = isDark ? (0.5 - luminance) * 2 : (luminance - 0.5) * 2;
206
+ let middleColor;
207
+ if (isDark) {
208
+ middleColor = color.luminance(0.5 - colorDepth / 4);
209
+ } else {
210
+ middleColor = color.luminance(0.5 + colorDepth / 4);
211
+ }
212
+
213
+ return {
214
+ originalColor: color.hex(),
215
+ isDark,
216
+ luminance,
217
+ colorDepth,
218
+ middleColor: middleColor.hex(),
219
+ };
220
+ },
221
+ };
222
+ const $c = Object.assign(coFuncs, json);
223
+
224
+ export default (Vue) => {
225
+ window.$c = $c;
226
+ window.$chroma = chroma;
227
+ };
180
228
  export { $c, chroma as $chroma };
181
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techui/colors",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Color tables for js and less versions developed by ayin.",
5
5
  "license": "MIT",
6
6
  "author": "aYin <ayin86cn@gmail.com> <wechat:jay1986cn>",
@@ -25,9 +25,6 @@
25
25
  "chroma",
26
26
  "chroma.js"
27
27
  ],
28
- "dependencies": {
29
- "@techui/lessmixins": "^1.0.0"
30
- },
31
28
  "devDependencies":{
32
29
  "less": "*",
33
30
  "less-loader": "*"