refactor: using "color-convert" in ColorConverter

Signed-off-by: Corentin Thomasset <corentin.thomasset74@gmail.com>
This commit is contained in:
Corentin Thomasset 2020-06-06 13:51:39 +02:00
parent d4f57fde34
commit db189b4bcb
4 changed files with 102 additions and 135 deletions

23
package-lock.json generated
View file

@ -2002,6 +2002,14 @@
"dev": true, "dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
},
"dependencies": {
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}
} }
} }
} }
@ -3298,6 +3306,14 @@
"dev": true, "dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
},
"dependencies": {
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}
} }
} }
} }
@ -3318,10 +3334,9 @@
} }
}, },
"color-name": { "color-name": {
"version": "1.1.3", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
"dev": true
}, },
"color-string": { "color-string": {
"version": "1.5.3", "version": "1.5.3",

View file

@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"axios": "^0.19.2", "axios": "^0.19.2",
"color-convert": "^2.0.1", "color-convert": "^2.0.1",
"color-name": "^1.1.4",
"core-js": "^3.6.4", "core-js": "^3.6.4",
"register-service-worker": "^1.7.1", "register-service-worker": "^1.7.1",
"roboto-fontface": "*", "roboto-fontface": "*",

View file

@ -27,7 +27,6 @@
<script> <script>
import {toolsComponentsFlat} from '../router' import {toolsComponentsFlat} from '../router'
console.log(toolsComponentsFlat);
export default { export default {
name: "SearchBar", name: "SearchBar",
data() { data() {

View file

@ -10,47 +10,44 @@
canvas-height="300" canvas-height="300"
hide-inputs hide-inputs
mode="rgba" mode="rgba"
v-model="rgba" v-model="rgb"
/> />
</v-col> </v-col>
<v-col cols="12" sm="6" align="center"> <v-col cols="12" sm="6" align="center">
<v-form v-model="valid" ref="form">
<v-text-field <v-text-field
outlined outlined
ref="hex"
label="hex" label="hex"
v-model="_hex" v-model="_hex"
:rules="rules.hex" :rules="rules.hex"
dense dense
/> />
<v-text-field
outlined
label="hexa"
:rules="rules.hexa"
v-model="_hexa"
dense
/>
<v-text-field <v-text-field
outlined outlined
label="rgb" label="rgb"
ref="rgb"
v-model="_rgb" v-model="_rgb"
:rules="rules.rgb" :rules="rules.rgb"
dense dense
/> />
<v-text-field
outlined
label="rgba"
v-model="_rgba"
:rules="rules.rgba"
dense
/>
<v-text-field <v-text-field
outlined outlined
label="hsl" label="hsl"
ref="hsl"
v-model="_hsl" v-model="_hsl"
:rules="rules.hsl"
dense
/>
<v-autocomplete
v-model="_keyword"
outlined
label="css keyword"
ref="keyword"
:items="colorsName"
:rules="rules.keyword"
no-data-text="This is not an authorized color name."
dense dense
/> />
</v-form>
</v-col> </v-col>
</v-row> </v-row>
</v-card-text> </v-card-text>
@ -58,137 +55,90 @@
</template> </template>
<script> <script>
import convert from "color-convert";
import colors from "color-name";
const required = v => !!v || 'A value is required' const required = v => !!v || 'A value is required'
const intToHex = (int) => Math.floor(int).toString(16).toUpperCase().padStart(2, '0');
const hexToInt = (hex) => parseInt(hex, 16);
const rgbToHSL = ({r, g, b}) => {
r /= 255, g /= 255, b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return {h: h * 360, s: s * 100, l: l * 100};
}
export default { export default {
name: "ColorConverter", name: "ColorConverter",
data: () => ({ data: () => ({
rgba: { rgb: {
"r": 76, "r": 76,
"g": 175, "g": 175,
"b": 80, "b": 80
"a": 1
}, },
console: console, colorsName: Object.keys(colors).sort(),
valid: true, valid: true,
rules: { rules: {
hexa: [
required,
v => /^#(?:[0-9a-fA-F]{8})$/.test(v) || 'Format should be like #112233aa'
],
hex: [ hex: [
required, required,
v => /^#([0-9a-fA-F]{3}){1,2}$/.test(v) || 'Format should be like #112233' v => /^#(?:[0-9a-fA-F]{6})$/.test(v) || 'Format should be like #112233'
], ],
rgb: [ rgb: [
required, required,
v => /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(v) || 'Format should be like rgb(255, 0, 0)' v => /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(v) || 'Format should be like rgb(255, 0, 0)'
], ],
rgba: [ hsl: [
required, required,
v => /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(?:\.\d+)?)\)$/.test(v) || 'Format should be like rgb(255, 0, 0, 1)' v => /^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/.test(v) || 'Format should be like hsl(360, 100%, 50%)'
],
keywords: [
required,
v => !!colors[v] || 'Value should be from the list'
] ]
} }
}), }),
computed: { computed: {
_hex: { _hex: {
get() { get() {
return `#${intToHex(this.rgba.r)}${intToHex(this.rgba.g)}${intToHex(this.rgba.b)}` const result = convert.rgb.hex(this.rgb.r, this.rgb.g, this.rgb.b)
return `#${result}`
}, },
set(value) { set(value) {
if (this.$refs.form.validate()) { if (this.$refs.hex.validate()) {
value = value.replace(/#/, ''); const [r, g, b] = convert.hex.rgb(value.replace(/#/g, ''))
value = value.length === 3 ? value.split('').map(v => v + v) : value.match(/.{2}/g); this.rgb = {r, g, b}
console.log(value);
this.rgba = {
r: hexToInt(value[0]),
g: hexToInt(value[1]),
b: hexToInt(value[2]),
a: '1'
}
}
}
},
_hexa: {
get() {
return `#${intToHex(this.rgba.r)}${intToHex(this.rgba.g)}${intToHex(this.rgba.b)}${intToHex((this.rgba.a ?? 0) * 255)}`
},
set(value) {
if (this.$refs.form.validate()) {
value = value.replace(/#/, '');
value = value.match(/.{2}/g);
this.rgba = {
r: hexToInt(value[0]),
g: hexToInt(value[1]),
b: hexToInt(value[2]),
a: hexToInt(value[3]) / 255,
}
} }
} }
}, },
_rgb: { _rgb: {
get() { get() {
return `rgb(${this.rgba.r}, ${this.rgba.g}, ${this.rgba.b})` return `rgb(${this.rgb.r}, ${this.rgb.g}, ${this.rgb.b})`
}, },
set(value) { set(value) {
if (this.$refs.form.validate()) { if (this.$refs.rgb.validate()) {
const [, r, g, b] = value.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); const [r, g, b] = value.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/).slice(1).map(v => parseInt(v));
this.rgb = {r, g, b}
this.rgba = {r, g, b, a: 1}
}
}
},
_rgba: {
get() {
return `rgba(${this.rgba.r}, ${this.rgba.g}, ${this.rgba.b}, ${parseFloat((this.rgba.a ?? 0).toFixed(2))})`
},
set(value) {
if (this.$refs.form.validate()) {
const [, r, g, b, a] = value.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(?:\.\d+)?)\)$/);
this.rgba = {r, g, b, a: parseFloat(a)}
} }
} }
}, },
_hsl: { _hsl: {
get() { get() {
const {h, s, l} = rgbToHSL(this.rgba) const [h, s, l] = convert.rgb.hsl(this.rgb.r, this.rgb.g, this.rgb.b)
return `hsl(${Math.floor(h)}, ${Math.floor(s)}%, ${Math.floor(l)}%)`
return `hsl(${Math.floor(h)}, ${Math.floor(s )}%, ${Math.floor(l)}%)`
}, },
set(value) { set(value) {
if (this.$refs.form.validate()) { if (this.$refs.hsl.validate()) {
const [, r, g, b, a] = value.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(?:\.\d+)?)\)$/); const [h, s, l] = value.match(/^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/).slice(1).map(v => parseInt(v));
const [r, g, b] = convert.hsl.rgb(h, s, l)
this.rgba = {r, g, b, a: parseFloat(a)} this.rgb = {r, g, b}
}
}
},
_keyword: {
get() {
return convert.rgb.keyword(this.rgb.r, this.rgb.g, this.rgb.b)
},
set(value) {
if (this.$refs.keyword.validate()) {
try {
const [r, g, b] = convert.keyword.rgb(value)
this.rgb = {r, g, b}
} catch (ignored) {
// ignored
}
} }
} }
} }
@ -196,6 +146,8 @@
} }
</script> </script>
<style scoped> <style scoped lang="less">
::v-deep .v-input__icon {
height: 18px !important;
}
</style> </style>