1
1
<script setup>
2
- import { ref } from ' vue'
2
+ import { ref , watch } from ' vue'
3
3
4
4
const r2h = ref ({ r: 255 , g: 180 , b: 0 })
5
5
const hex = ref (' #ffb400' )
6
6
const h = ref (' #cc00ff' )
7
7
const rgb = ref ([204 , 0 , 255 ])
8
+ const showColorPicker = ref (false )
9
+ const activeColorPicker = ref (' ' ) // 'rgb' 或 'hex'
8
10
9
11
/**
10
12
* rgb转16进制
@@ -14,37 +16,167 @@ function rgb2hex() {
14
16
const rgb = (r << 16 ) | (g << 8 ) | b
15
17
hex .value = ` #${ rgb .toString (16 ).padStart (6 , ' 0' )} `
16
18
}
19
+
17
20
// 16进制转rgb
18
21
function hex2rgb () {
19
22
rgb .value = h .value .replace (' #' , ' ' ).match (/ .. / g ).map (n => Number .parseInt (n, 16 ))
20
23
}
24
+
25
+ // 打开颜色选择器
26
+ function openColorPicker (type ) {
27
+ activeColorPicker .value = type
28
+ showColorPicker .value = true
29
+ }
30
+
31
+ // 处理颜色选择
32
+ function handleColorSelect (color ) {
33
+ if (activeColorPicker .value === ' rgb' ) {
34
+ hex .value = color
35
+ const hexValue = color .replace (' #' , ' ' )
36
+ const r = parseInt (hexValue .substring (0 , 2 ), 16 )
37
+ const g = parseInt (hexValue .substring (2 , 4 ), 16 )
38
+ const b = parseInt (hexValue .substring (4 , 6 ), 16 )
39
+ r2h .value = { r, g, b }
40
+ } else if (activeColorPicker .value === ' hex' ) {
41
+ h .value = color
42
+ hex2rgb ()
43
+ }
44
+ showColorPicker .value = false
45
+ }
46
+
47
+ // 实时更新颜色
48
+ watch (() => [r2h .value .r , r2h .value .g , r2h .value .b ], () => {
49
+ rgb2hex ()
50
+ })
51
+
52
+ watch (() => h .value , () => {
53
+ if (h .value .startsWith (' #' ) && (h .value .length === 4 || h .value .length === 7 )) {
54
+ hex2rgb ()
55
+ }
56
+ })
21
57
</script >
22
58
23
59
<template >
24
- <main flex =" ~ col" items-center justify-center bg-gray-100 p-4 py-8 rounded-md >
25
- <div flex =" ~" >
26
- RGB颜色值转换成十六进制颜色码:<div mr4 inline-block w-10 px4 :style =" { backgroundColor: hex }" />
27
- <input v-model =" hex" type =" text" w-40 border border-base px2 >
60
+ <main flex =" ~ col" items-center justify-center bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 p-6 rounded-xl shadow-sm max-w-2xl mx-auto >
61
+ <div text =" 2xl gray-800 dark:gray-100" font-bold mb-6 >RGB/HEX 颜色转换工具</div >
62
+
63
+ <!-- RGB to HEX 转换部分 -->
64
+ <div w-full bg-white dark:bg-gray-800 rounded-lg p-5 shadow-sm mb-6 >
65
+ <div flex items-center justify-between mb-4 >
66
+ <h3 text =" lg gray-700 dark:gray-200" font-medium >RGB → HEX</h3 >
67
+ <div flex items-center gap-2 >
68
+ <div
69
+ h-10 w-10 rounded-md shadow-inner cursor-pointer
70
+ :style =" { backgroundColor: hex }"
71
+ @click =" openColorPicker('rgb')"
72
+ class =" hover:ring-2 hover:ring-blue-300 transition-all"
73
+ />
74
+ <div text-sm text =" gray-500 dark:gray-300" >{{ hex }}</div >
75
+ </div >
76
+ </div >
77
+
78
+ <div flex =" ~ col sm:row" gap-4 >
79
+ <div flex =" ~ gap-2" items-center >
80
+ <label text =" sm gray-600 dark:gray-300" w-6 >R:</label >
81
+ <input
82
+ v-model.number =" r2h.r"
83
+ type =" number"
84
+ min =" 0"
85
+ max =" 255"
86
+ class =" w-full sm:w-20 h-10 rounded border border-gray-400 bg-gray-50 text-gray-800 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 px-2 focus:(ring-2 ring-blue-300 outline-none)"
87
+ >
88
+ </div >
89
+ <div flex =" ~ gap-2" items-center >
90
+ <label text =" sm gray-600 dark:gray-300" w-6 >G:</label >
91
+ <input
92
+ v-model.number =" r2h.g"
93
+ type =" number"
94
+ min =" 0"
95
+ max =" 255"
96
+ class =" w-full sm:w-20 h-10 rounded border border-gray-400 bg-gray-50 text-gray-800 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 px-2 focus:(ring-2 ring-blue-300 outline-none)"
97
+ >
98
+ </div >
99
+ <div flex =" ~ gap-2" items-center >
100
+ <label text =" sm gray-600 dark:gray-300" w-6 >B:</label >
101
+ <input
102
+ v-model.number =" r2h.b"
103
+ type =" number"
104
+ min =" 0"
105
+ max =" 255"
106
+ class =" w-full sm:w-20 h-10 rounded border border-gray-400 bg-gray-50 text-gray-800 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 px-2 focus:(ring-2 ring-blue-300 outline-none)"
107
+ >
108
+ </div >
109
+ <button
110
+ bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded transition-colors
111
+ flex items-center justify-center
112
+ @click =" rgb2hex"
113
+ >
114
+ 转换
115
+ </button >
116
+ </div >
28
117
</div >
29
- <div flex =" ~ col" mt4 >
30
- <div flex =" ~ gap4" >
31
- <input v-model =" r2h.r" type =" number" w-20 border-1 border-style-solid border-color-gray-300 bg-white px2 >
32
- <input v-model =" r2h.g" type =" number" w-20 border-1 border-style-solid border-color-gray-300 bg-white px2 >
33
- <input v-model =" r2h.b" type =" number" w-20 border-1 border-style-solid border-color-gray-300 bg-white px2 >
34
- <button btn-primary flex items-center justify-center rounded-full @click =" rgb2hex" >
118
+
119
+ <!-- HEX to RGB 转换部分 -->
120
+ <div w-full bg-white dark:bg-gray-800 rounded-lg p-5 shadow-sm >
121
+ <div flex items-center justify-between mb-4 >
122
+ <h3 text =" lg gray-700 dark:gray-200" font-medium >HEX → RGB</h3 >
123
+ <div flex items-center gap-2 >
124
+ <div
125
+ h-10 w-10 rounded-md shadow-inner cursor-pointer
126
+ :style =" { backgroundColor: `rgb(${rgb})` }"
127
+ @click =" openColorPicker('hex')"
128
+ class =" hover:ring-2 hover:ring-blue-300 transition-all"
129
+ />
130
+ <div text-sm text =" gray-500 dark:gray-300" >rgb({{ rgb.join(', ') }})</div >
131
+ </div >
132
+ </div >
133
+
134
+ <div flex =" ~ col sm:row" gap-4 >
135
+ <div flex =" ~ gap-2" items-center flex-1 >
136
+ <label text =" sm gray-600 dark:gray-300" w-10 >HEX:</label >
137
+ <input
138
+ v-model =" h"
139
+ type =" text"
140
+ placeholder =" #000000"
141
+ class =" w-full h-10 rounded border border-gray-400 bg-gray-50 text-gray-800 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 px-2 focus:(ring-2 ring-blue-300 outline-none)"
142
+ >
143
+ </div >
144
+ <button
145
+ bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded transition-colors
146
+ flex items-center justify-center
147
+ @click =" hex2rgb"
148
+ >
35
149
转换
36
150
</button >
37
151
</div >
38
152
</div >
39
- <div flex =" ~" mt8 >
40
- 十六进制颜色码转换成RGB颜色值:<div mr4 inline-block w-10 px4 :style =" { backgroundColor: `rgb(${rgb})` }" />
41
- <input v-model =" rgb" type =" text" w-30 border-1 border-style-solid border-color-gray-300 bg-white px2 >
153
+
154
+ <!-- 颜色选择器弹窗 -->
155
+ <div v-if =" showColorPicker" class =" fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" @click.self =" showColorPicker = false" >
156
+ <div class =" bg-white dark:bg-gray-800 p-5 rounded-lg shadow-lg max-w-md w-full" >
157
+ <h3 text =" lg gray-700 dark:gray-200" font-medium mb-4 >选择颜色</h3 >
158
+ <div class =" grid grid-cols-8 gap-2" >
159
+ <div
160
+ v-for =" color in ['#ff0000', '#ff8000', '#ffff00', '#80ff00', '#00ff00', '#00ff80', '#00ffff', '#0080ff', '#0000ff', '#8000ff', '#ff00ff', '#ff0080', '#000000', '#808080', '#c0c0c0', '#ffffff', '#800000', '#804000', '#808000', '#408000', '#008000', '#008040', '#008080', '#004080', '#000080', '#400080', '#800080', '#800040', '#4d3319', '#ffcc99', '#009933', '#660066']"
161
+ :key =" color"
162
+ class =" h-8 w-8 rounded cursor-pointer hover:ring-2 hover:ring-blue-300 transition-all"
163
+ :style =" { backgroundColor: color }"
164
+ @click =" handleColorSelect(color)"
165
+ ></div >
166
+ </div >
167
+ <div class =" mt-4 flex justify-end" >
168
+ <button
169
+ class =" bg-gray-300 dark:bg-gray-600 hover:bg-gray-400 dark:hover:bg-gray-500 text-gray-800 dark:text-gray-200 px-4 py-2 rounded transition-colors"
170
+ @click =" showColorPicker = false"
171
+ >
172
+ 取消
173
+ </button >
174
+ </div >
175
+ </div >
42
176
</div >
43
- <div flex =" ~ gap4" mt4 >
44
- <input v-model =" h" type =" text" border-1 border-style-solid border-color-gray-300 bg-white px2 >
45
- <button btn-primary flex items-center justify-center rounded-full @click =" hex2rgb" >
46
- 转换
47
- </button >
177
+
178
+ <div mt-6 text-xs text =" gray-500 dark:gray-400" >
179
+ 提示:RGB转HEX部分支持实时预览,修改RGB值后会自动更新HEX值。点击颜色块可以打开颜色选择器。
48
180
</div >
49
181
</main >
50
182
</template >
0 commit comments