From a25a69e773b4632eba3e9b24f134b9e39d70f954 Mon Sep 17 00:00:00 2001 From: sharevb Date: Sun, 28 Apr 2024 12:47:43 +0200 Subject: [PATCH] feat(Color Converter): Many enhancements Add XYZ and Lab colors values Add Saturation/Bightness sliders Add Grayscale/Invert options --- components.d.ts | 5 + src/tools/color-converter/color-converter.vue | 125 ++++++++++++++---- 2 files changed, 104 insertions(+), 26 deletions(-) diff --git a/components.d.ts b/components.d.ts index e31119b3..e31f86ad 100644 --- a/components.d.ts +++ b/components.d.ts @@ -127,8 +127,10 @@ declare module '@vue/runtime-core' { MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] + NCheckbox: typeof import('naive-ui')['NCheckbox'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] + NColorPicker: typeof import('naive-ui')['NColorPicker'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NDivider: typeof import('naive-ui')['NDivider'] NEllipsis: typeof import('naive-ui')['NEllipsis'] @@ -144,6 +146,8 @@ declare module '@vue/runtime-core' { NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NMenu: typeof import('naive-ui')['NMenu'] NScrollbar: typeof import('naive-ui')['NScrollbar'] + NSlider: typeof import('naive-ui')['NSlider'] + NSpace: typeof import('naive-ui')['NSpace'] NSpin: typeof import('naive-ui')['NSpin'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] @@ -159,6 +163,7 @@ declare module '@vue/runtime-core' { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default'] + SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default'] SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default'] SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default'] SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default'] diff --git a/src/tools/color-converter/color-converter.vue b/src/tools/color-converter/color-converter.vue index a7d6139f..e94b2cb4 100644 --- a/src/tools/color-converter/color-converter.vue +++ b/src/tools/color-converter/color-converter.vue @@ -6,9 +6,11 @@ import cmykPlugin from 'colord/plugins/cmyk'; import hwbPlugin from 'colord/plugins/hwb'; import namesPlugin from 'colord/plugins/names'; import lchPlugin from 'colord/plugins/lch'; +import xyzPlugin from 'colord/plugins/xyz'; +import labPlugin from 'colord/plugins/lab'; import { buildColorFormat } from './color-converter.models'; -extend([cmykPlugin, hwbPlugin, namesPlugin, lchPlugin]); +extend([cmykPlugin, hwbPlugin, namesPlugin, lchPlugin, xyzPlugin, labPlugin]); const formats = { picker: buildColorFormat({ @@ -46,6 +48,18 @@ const formats = { format: (v: Colord) => v.toCmykString(), placeholder: 'e.g. cmyk(0, 100%, 100%, 0)', }), + lab: buildColorFormat({ + label: 'lab', + format: (v: Colord) => JSON.stringify(v.toLab()), + placeholder: 'e.g. { l: 14.89, a: 5.77, b: 14.41, alpha: 0.5 }', + parse: value => colord(JSON.parse(value)), + }), + xyz: buildColorFormat({ + label: 'xyz', + format: (v: Colord) => JSON.stringify(v.toXyz()), + placeholder: 'e.g. { x: 95.047, y: 100, z: 108.883, a: 1 }', + parse: value => colord(JSON.parse(value)), + }), name: buildColorFormat({ label: 'name', format: (v: Colord) => v.toName({ closest: true }) ?? 'Unknown', @@ -53,7 +67,17 @@ const formats = { }), }; -updateColorValue(colord('#1ea54c')); +const saturation = ref(0); +const brightness = ref(0); +const grayscale = ref(false); +const invert = ref(false); + +let lastColor = colord('#1ea54c'); +watch([saturation, brightness, grayscale, invert], + () => updateColorValue(lastColor), +); + +updateColorValue(lastColor); function updateColorValue(value: Colord | undefined, omitLabel?: string) { if (value === undefined) { @@ -64,40 +88,89 @@ function updateColorValue(value: Colord | undefined, omitLabel?: string) { return; } + lastColor = value; + + let correctedValue = value; + if (grayscale.value) { + correctedValue = correctedValue.grayscale(); + } + if (invert.value) { + correctedValue = correctedValue.invert(); + } + + const saturationFloat = saturation.value / 100.0; + if (saturationFloat > 0) { + correctedValue = correctedValue.saturate(saturationFloat); + } + else if (saturationFloat < 0) { + correctedValue = correctedValue.desaturate(-saturationFloat); + } + + const brightnessFloat = brightness.value / 100.0; + if (brightnessFloat > 0) { + correctedValue = correctedValue.lighten(brightnessFloat); + } + else if (brightnessFloat < 0) { + correctedValue = correctedValue.darken(-brightnessFloat); + } + _.forEach(formats, ({ value: valueRef, format }, key) => { if (key !== omitLabel) { - valueRef.value = format(value); + valueRef.value = format(correctedValue); } }); }