@@ -6,9 +6,11 @@ import cmykPlugin from 'colord/plugins/cmyk';
6
6
import hwbPlugin from ' colord/plugins/hwb' ;
7
7
import namesPlugin from ' colord/plugins/names' ;
8
8
import lchPlugin from ' colord/plugins/lch' ;
9
+ import xyzPlugin from ' colord/plugins/xyz' ;
10
+ import labPlugin from ' colord/plugins/lab' ;
9
11
import { buildColorFormat } from ' ./color-converter.models' ;
10
12
11
- extend ([cmykPlugin , hwbPlugin , namesPlugin , lchPlugin ]);
13
+ extend ([cmykPlugin , hwbPlugin , namesPlugin , lchPlugin , xyzPlugin , labPlugin ]);
12
14
13
15
const formats = {
14
16
picker: buildColorFormat ({
@@ -46,14 +48,36 @@ const formats = {
46
48
format : (v : Colord ) => v .toCmykString (),
47
49
placeholder: ' e.g. cmyk(0, 100%, 100%, 0)' ,
48
50
}),
51
+ lab: buildColorFormat ({
52
+ label: ' lab' ,
53
+ format : (v : Colord ) => JSON .stringify (v .toLab ()),
54
+ placeholder: ' e.g. { l: 14.89, a: 5.77, b: 14.41, alpha: 0.5 }' ,
55
+ parse : value => colord (JSON .parse (value )),
56
+ }),
57
+ xyz: buildColorFormat ({
58
+ label: ' xyz' ,
59
+ format : (v : Colord ) => JSON .stringify (v .toXyz ()),
60
+ placeholder: ' e.g. { x: 95.047, y: 100, z: 108.883, a: 1 }' ,
61
+ parse : value => colord (JSON .parse (value )),
62
+ }),
49
63
name: buildColorFormat ({
50
64
label: ' name' ,
51
65
format : (v : Colord ) => v .toName ({ closest: true }) ?? ' Unknown' ,
52
66
placeholder: ' e.g. red' ,
53
67
}),
54
68
};
55
69
56
- updateColorValue (colord (' #1ea54c' ));
70
+ const saturation = ref (0 );
71
+ const brightness = ref (0 );
72
+ const grayscale = ref (false );
73
+ const invert = ref (false );
74
+
75
+ let lastColor = colord (' #1ea54c' );
76
+ watch ([saturation , brightness , grayscale , invert ],
77
+ () => updateColorValue (lastColor ),
78
+ );
79
+
80
+ updateColorValue (lastColor );
57
81
58
82
function updateColorValue(value : Colord | undefined , omitLabel ? : string ) {
59
83
if (value === undefined ) {
@@ -64,40 +88,89 @@ function updateColorValue(value: Colord | undefined, omitLabel?: string) {
64
88
return ;
65
89
}
66
90
91
+ lastColor = value ;
92
+
93
+ let correctedValue = value ;
94
+ if (grayscale .value ) {
95
+ correctedValue = correctedValue .grayscale ();
96
+ }
97
+ if (invert .value ) {
98
+ correctedValue = correctedValue .invert ();
99
+ }
100
+
101
+ const saturationFloat = saturation .value / 100.0 ;
102
+ if (saturationFloat > 0 ) {
103
+ correctedValue = correctedValue .saturate (saturationFloat );
104
+ }
105
+ else if (saturationFloat < 0 ) {
106
+ correctedValue = correctedValue .desaturate (- saturationFloat );
107
+ }
108
+
109
+ const brightnessFloat = brightness .value / 100.0 ;
110
+ if (brightnessFloat > 0 ) {
111
+ correctedValue = correctedValue .lighten (brightnessFloat );
112
+ }
113
+ else if (brightnessFloat < 0 ) {
114
+ correctedValue = correctedValue .darken (- brightnessFloat );
115
+ }
116
+
67
117
_ .forEach (formats , ({ value : valueRef , format }, key ) => {
68
118
if (key !== omitLabel ) {
69
- valueRef .value = format (value );
119
+ valueRef .value = format (correctedValue );
70
120
}
71
121
});
72
122
}
73
123
</script >
74
124
75
125
<template >
76
- <c-card >
77
- <template v-for =" ({ label , parse , placeholder , validation , type }, key ) in formats " :key =" key " >
78
- <input-copyable
79
- v-if =" type === 'text'"
80
- v-model:value =" formats[key].value.value"
81
- :test-id =" `input-${key}`"
82
- :label =" `${label}:`"
83
- label-position =" left"
84
- label-width =" 100px"
85
- label-align =" right"
86
- :placeholder =" placeholder"
87
- :validation =" validation"
88
- raw-text
89
- clearable
90
- mt-2
91
- @update:value =" (v:string) => updateColorValue(parse(v), key)"
92
- />
93
-
94
- <n-form-item v-else-if =" type === 'color-picker'" :label =" `${label}:`" label-width =" 100" label-placement =" left" :show-feedback =" false" >
95
- <n-color-picker
126
+ <div >
127
+ <c-card title =" Transformations" >
128
+ <n-form-item label =" Saturation" label-placement =" left" >
129
+ <n-slider v-model:value =" saturation" :step =" 1" :min =" -100" :max =" 100" mr-2 />
130
+ <n-input-number v-model:value =" saturation" size =" small" />
131
+ </n-form-item >
132
+
133
+ <n-form-item label =" Brightness" label-placement =" left" >
134
+ <n-slider v-model:value =" brightness" :step =" 1" :min =" -100" :max =" 100" mr-2 />
135
+ <n-input-number v-model:value =" brightness" size =" small" />
136
+ </n-form-item >
137
+
138
+ <n-space >
139
+ <n-form-item label =" Grayscale" label-placement =" left" >
140
+ <n-checkbox v-model:checked =" grayscale" mr-2 />
141
+ </n-form-item >
142
+
143
+ <n-form-item label =" Invert" label-placement =" left" >
144
+ <n-checkbox v-model:checked =" invert" mr-2 />
145
+ </n-form-item >
146
+ </n-space >
147
+ </c-card >
148
+ <c-card >
149
+ <template v-for =" ({ label , parse , placeholder , validation , type }, key ) in formats " :key =" key " >
150
+ <input-copyable
151
+ v-if =" type === 'text'"
96
152
v-model:value =" formats[key].value.value"
97
- placement =" bottom-end"
153
+ :test-id =" `input-${key}`"
154
+ :label =" `${label}:`"
155
+ label-position =" left"
156
+ label-width =" 100px"
157
+ label-align =" right"
158
+ :placeholder =" placeholder"
159
+ :validation =" validation"
160
+ raw-text
161
+ clearable
162
+ mt-2
98
163
@update:value =" (v:string) => updateColorValue(parse(v), key)"
99
164
/>
100
- </n-form-item >
101
- </template >
102
- </c-card >
165
+
166
+ <n-form-item v-else-if =" type === 'color-picker'" :label =" `${label}:`" label-width =" 100" label-placement =" left" :show-feedback =" false" >
167
+ <n-color-picker
168
+ v-model:value =" formats[key].value.value"
169
+ placement =" bottom-end"
170
+ @update:value =" (v:string) => updateColorValue(parse(v), key)"
171
+ />
172
+ </n-form-item >
173
+ </template >
174
+ </c-card >
175
+ </div >
103
176
</template >
0 commit comments