feat: added color-picker-converter.vue
This commit is contained in:
		
							parent
							
								
									f1d8d55cce
								
							
						
					
					
						commit
						4fdc09a787
					
				
							
								
								
									
										50
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										50
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -2765,6 +2765,12 @@ | ||||
|         "source-map": "^0.6.0" | ||||
|       } | ||||
|     }, | ||||
|     "@types/color-name": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", | ||||
|       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/compression": { | ||||
|       "version": "1.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.0.tgz", | ||||
| @ -3842,6 +3848,21 @@ | ||||
|       "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", | ||||
|       "requires": { | ||||
|         "color-convert": "^1.9.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "color-convert": { | ||||
|           "version": "1.9.3", | ||||
|           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||||
|           "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||||
|           "requires": { | ||||
|             "color-name": "1.1.3" | ||||
|           } | ||||
|         }, | ||||
|         "color-name": { | ||||
|           "version": "1.1.3", | ||||
|           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||||
|           "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "anymatch": { | ||||
| @ -5198,20 +5219,35 @@ | ||||
|       "requires": { | ||||
|         "color-convert": "^1.9.1", | ||||
|         "color-string": "^1.5.4" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "color-convert": { | ||||
|           "version": "1.9.3", | ||||
|           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||||
|           "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||||
|           "requires": { | ||||
|             "color-name": "1.1.3" | ||||
|           } | ||||
|         }, | ||||
|         "color-name": { | ||||
|           "version": "1.1.3", | ||||
|           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||||
|           "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "color-convert": { | ||||
|       "version": "1.9.3", | ||||
|       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", | ||||
|       "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | ||||
|       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | ||||
|       "requires": { | ||||
|         "color-name": "1.1.3" | ||||
|         "color-name": "~1.1.4" | ||||
|       } | ||||
|     }, | ||||
|     "color-name": { | ||||
|       "version": "1.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", | ||||
|       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" | ||||
|       "version": "1.1.4", | ||||
|       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | ||||
|       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" | ||||
|     }, | ||||
|     "color-string": { | ||||
|       "version": "1.5.4", | ||||
|  | ||||
| @ -17,6 +17,8 @@ | ||||
|     "@nuxtjs/pwa": "^3.0.2", | ||||
|     "@nuxtjs/toast": "^3.3.1", | ||||
|     "bip39": "^3.0.3", | ||||
|     "color-convert": "^2.0.1", | ||||
|     "color-name": "^1.1.4", | ||||
|     "core-js": "^3.6.5", | ||||
|     "crypto-js": "^4.0.0", | ||||
|     "nuxt": "^2.14.12", | ||||
| @ -32,6 +34,8 @@ | ||||
|     "@nuxtjs/eslint-module": "^2.0.0", | ||||
|     "@nuxtjs/svg": "^0.1.12", | ||||
|     "@nuxtjs/vuetify": "^1.11.2", | ||||
|     "@types/color-convert": "^2.0.0", | ||||
|     "@types/color-name": "^1.1.1", | ||||
|     "@types/crypto-js": "^4.0.1", | ||||
|     "@vue/test-utils": "^1.1.0", | ||||
|     "babel-core": "7.0.0-bridge.0", | ||||
|  | ||||
							
								
								
									
										190
									
								
								pages/tools/converter/color-picker-converter.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								pages/tools/converter/color-picker-converter.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,190 @@ | ||||
| <template> | ||||
|   <ToolWrapper :config="config()"> | ||||
|     <v-row no-gutters align="center" align-content="center" justify="center"> | ||||
|       <v-col cols="12" sm="6" align="center"> | ||||
|         <v-color-picker | ||||
|           v-model="rgbPicker" | ||||
|           flat | ||||
|           canvas-height="300" | ||||
|           hide-inputs | ||||
|           mode="rgba" | ||||
|           @input="(v) => updateColors(v, 'picker')" | ||||
|         /> | ||||
|       </v-col> | ||||
|       <v-col cols="12" sm="6" align="center"> | ||||
|         <v-text-field | ||||
|           ref="hex" | ||||
|           outlined | ||||
|           label="hex" | ||||
|           :value="hex" | ||||
|           :rules="rules.hex" | ||||
|           append-icon="mdi-content-copy" | ||||
|           @input="(v) => updateColors(v, 'hex')" | ||||
|           @click:append="copy(hex)" | ||||
|         /> | ||||
|         <v-text-field | ||||
|           ref="rgb" | ||||
|           outlined | ||||
|           label="rgb" | ||||
|           :value="rgb" | ||||
|           :rules="rules.rgb" | ||||
|           append-icon="mdi-content-copy" | ||||
|           @input="(v) => updateColors(v, 'rgb')" | ||||
|           @click:append="copy(rgb)" | ||||
|         /> | ||||
|         <v-text-field | ||||
|           ref="hsl" | ||||
|           outlined | ||||
|           label="hsl" | ||||
|           :value="hsl" | ||||
|           :rules="rules.hsl" | ||||
|           append-icon="mdi-content-copy" | ||||
|           @input="(v) => updateColors(v, 'hsl')" | ||||
|           @click:append="copy(hsl)" | ||||
|         /> | ||||
|         <v-combobox | ||||
|           ref="keyword" | ||||
|           :value="keyword" | ||||
|           outlined | ||||
|           label="css keyword" | ||||
|           :items="colorsName" | ||||
|           :rules="rules.keyword" | ||||
|           no-data-text="This is not an authorized color name." | ||||
|           append-icon="mdi-content-copy" | ||||
|           @change="(v) => updateColors(v, 'keyword')" | ||||
|           @click:append="copy(keyword)" | ||||
|         /> | ||||
|       </v-col> | ||||
|     </v-row> | ||||
|   </ToolWrapper> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| 
 | ||||
| import {Component} from 'nuxt-property-decorator' | ||||
| import colors from 'color-name' | ||||
| import convert from 'color-convert' | ||||
| import {CopyableMixin} from '~/mixins/copyable.mixin' | ||||
| import Tool from '~/components/Tool.vue' | ||||
| import {ToolConfig} from '~/types/ToolConfig' | ||||
| import type {VForm} from '~/types/VForm' | ||||
| 
 | ||||
| const required = (v: unknown) => !!v || 'A value is required' | ||||
| 
 | ||||
| @Component({ | ||||
|   mixins: [CopyableMixin] | ||||
| }) | ||||
| export default class ColorPickerConverter extends Tool { | ||||
|   config(): ToolConfig { | ||||
|     return { | ||||
|       title: 'Color picker/converter', | ||||
|       description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Delectus distinctio dolor dolorum eaque eligendi, facilis impedit laboriosam odit placeat.', | ||||
|       icon: 'mdi-palette', | ||||
|       keywords: ['rgb', 'hsl', 'hex', 'keyword', 'css', 'picker'] | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   rgbPicker = { | ||||
|     r: 76, | ||||
|     g: 175, | ||||
|     b: 80 | ||||
|   } | ||||
| 
 | ||||
|   colorsName = Object.keys(colors).sort() | ||||
|   valid = true | ||||
|   rules = { | ||||
|     hex: [ | ||||
|       required, | ||||
|       (v: string) => /^#(?:[0-9a-fA-F]{6})$/.test(v) || 'Format should be like #112233' | ||||
|     ], | ||||
|     rgb: [ | ||||
|       required, | ||||
|       (v: string) => /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.test(v) || 'Format should be like rgb(255, 0, 0)' | ||||
|     ], | ||||
|     hsl: [ | ||||
|       required, | ||||
|       (v: string) => /^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/.test(v) || 'Format should be like hsl(360, 100%, 50%)' | ||||
|     ], | ||||
|     keywords: [ | ||||
|       required, | ||||
|       (v: string) => this.colorsName.includes(v) || 'Value should be from the list' | ||||
|     ] | ||||
|   } | ||||
| 
 | ||||
|   hex = '#4CAF50' | ||||
|   rgb = 'rgb(76, 175, 80)' | ||||
|   hsl = 'hsl(122, 39%, 49%)' | ||||
|   keyword = 'mediumseagreen' | ||||
| 
 | ||||
|   setHSL(r: number, g: number, b: number) { | ||||
|     const [h, s, l] = convert.rgb.hsl(r, g, b) | ||||
|     this.hsl = `hsl(${Math.floor(h)}, ${Math.floor(s)}%, ${Math.floor(l)}%)` | ||||
|   } | ||||
| 
 | ||||
|   setRGB(r: number, g: number, b: number) { | ||||
|     this.rgb = `rgb(${r}, ${g}, ${b})` | ||||
|   } | ||||
| 
 | ||||
|   setHEX(r: number, g: number, b: number) { | ||||
|     const result = convert.rgb.hex(r, g, b) | ||||
|     this.hex = `#${result}` | ||||
|   } | ||||
| 
 | ||||
|   setKeyword(r: number, g: number, b: number) { | ||||
|     this.keyword = convert.rgb.keyword(r, g, b) | ||||
|   } | ||||
| 
 | ||||
|   updateColors(value: string, fromType: string) { | ||||
|     if (fromType === 'picker' || (this.$refs[fromType] as VForm)?.validate()) { | ||||
|       if (fromType === 'rgb') { | ||||
|         const [r, g, b] = value.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/)?.slice(1).map(v => parseInt(v)) ?? [0, 0, 0] | ||||
|         this.rgbPicker = {r, g, b} | ||||
|         this.setHEX(r, g, b) | ||||
|         this.setHSL(r, g, b) | ||||
|         this.setKeyword(r, g, b) | ||||
|       } else if (fromType === 'hex') { | ||||
|         const [r, g, b] = convert.hex.rgb(value.replace(/#/g, '')) | ||||
|         this.rgbPicker = {r, g, b} | ||||
|         this.setRGB(r, g, b) | ||||
|         this.setHSL(r, g, b) | ||||
|         this.setKeyword(r, g, b) | ||||
|       } else if (fromType === 'hsl') { | ||||
|         const [h, s, l] = value.match(/^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/)?.slice(1).map(v => parseInt(v)) ?? [0, 0, 0] | ||||
|         // @ts-ignore | ||||
|         const [r, g, b] = convert.hsl.rgb(h, s, l) | ||||
|         this.rgbPicker = {r, g, b} | ||||
|         this.setRGB(r, g, b) | ||||
|         this.setHEX(r, g, b) | ||||
|         this.setKeyword(r, g, b) | ||||
|       } else if (fromType === 'keyword') { | ||||
|         try { | ||||
|           // @ts-ignore | ||||
|           const [r, g, b] = convert.keyword.rgb(value) | ||||
|           this.rgbPicker = {r, g, b} | ||||
|           this.setRGB(r, g, b) | ||||
|           this.setHEX(r, g, b) | ||||
|           this.setHSL(r, g, b) | ||||
|         } catch (ignored) { | ||||
|           // ignored | ||||
|         } | ||||
|       } else if (fromType === 'picker') { | ||||
|         const {r, g, b} = value as unknown as { r: number, g: number, b: number } | ||||
|         this.setRGB(r, g, b) | ||||
|         this.setHEX(r, g, b) | ||||
|         this.setHSL(r, g, b) | ||||
|         this.setKeyword(r, g, b) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   mounted() { | ||||
|     this.updateColors(this.hex, 'hex') | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style scoped lang="less"> | ||||
| ::v-deep .v-input__icon { | ||||
|   height: 18px !important; | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user