Skip to content

Commit 473c05f

Browse files
authored
Create ys.html
1 parent 3679455 commit 473c05f

1 file changed

Lines changed: 293 additions & 0 deletions

File tree

tool/ys.html

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
<!DOCTYPE html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>色彩魔法实验室</title>
7+
<style>
8+
:root {
9+
--primary: #FFD700; /* 黄色 */
10+
--secondary: #7CFC00; /* 绿色 */
11+
}
12+
13+
body {
14+
margin: 0;
15+
min-height: 100vh;
16+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
17+
font-family: 'Segoe UI', sans-serif;
18+
display: flex;
19+
flex-direction: column;
20+
align-items: center;
21+
padding: 2rem;
22+
}
23+
24+
.lab-container {
25+
background: rgba(255, 255, 255, 0.9);
26+
padding: 2rem;
27+
border-radius: 20px;
28+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
29+
max-width: 800px;
30+
width: 90%;
31+
}
32+
33+
.color-picker {
34+
display: grid;
35+
grid-template-columns: 1fr 1fr;
36+
gap: 2rem;
37+
margin-bottom: 2rem;
38+
}
39+
40+
#colorWheel {
41+
width: 250px;
42+
height: 250px;
43+
border-radius: 50%;
44+
border: 3px solid #fff;
45+
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
46+
cursor: crosshair;
47+
}
48+
49+
.color-info {
50+
display: flex;
51+
flex-direction: column;
52+
gap: 1rem;
53+
}
54+
55+
.color-preview {
56+
width: 100%;
57+
height: 80px;
58+
border-radius: 10px;
59+
transition: all 0.3s;
60+
border: 2px solid #fff;
61+
}
62+
63+
.value-box {
64+
background: white;
65+
padding: 1rem;
66+
border-radius: 8px;
67+
display: flex;
68+
align-items: center;
69+
gap: 1rem;
70+
}
71+
72+
input[type="text"] {
73+
padding: 8px;
74+
border: 1px solid #ddd;
75+
border-radius: 5px;
76+
width: 120px;
77+
}
78+
79+
button {
80+
background: var(--secondary);
81+
color: white;
82+
border: none;
83+
padding: 10px 20px;
84+
border-radius: 25px;
85+
cursor: pointer;
86+
transition: all 0.3s;
87+
}
88+
89+
button:hover {
90+
transform: translateY(-2px);
91+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
92+
}
93+
94+
.palette {
95+
display: grid;
96+
grid-template-columns: repeat(5, 1fr);
97+
gap: 1rem;
98+
margin-top: 2rem;
99+
}
100+
101+
.color-card {
102+
height: 60px;
103+
border-radius: 8px;
104+
cursor: pointer;
105+
transition: all 0.3s;
106+
position: relative;
107+
overflow: hidden;
108+
}
109+
110+
.color-card:hover {
111+
transform: scale(1.05);
112+
}
113+
114+
.color-card::after {
115+
content: attr(data-value);
116+
position: absolute;
117+
bottom: 0;
118+
left: 0;
119+
right: 0;
120+
background: rgba(0, 0, 0, 0.6);
121+
color: white;
122+
padding: 3px;
123+
font-size: 0.8rem;
124+
text-align: center;
125+
opacity: 0;
126+
transition: opacity 0.3s;
127+
}
128+
129+
.color-card:hover::after {
130+
opacity: 1;
131+
}
132+
</style>
133+
</head>
134+
<body>
135+
<h1>🎨 色彩魔法实验室</h1>
136+
137+
<div class="lab-container">
138+
<div class="color-picker">
139+
<canvas id="colorWheel"></canvas>
140+
141+
<div class="color-info">
142+
<div class="color-preview" id="colorPreview"></div>
143+
<div class="value-box">
144+
<input type="text" id="hexValue" readonly>
145+
<button onclick="copyHex()">复制HEX</button>
146+
</div>
147+
<div class="value-box">
148+
<input type="text" id="rgbValue" readonly>
149+
<button onclick="copyRGB()">复制RGB</button>
150+
</div>
151+
<button onclick="generateRandom()">随机颜色</button>
152+
</div>
153+
</div>
154+
155+
<h3>配色方案推荐</h3>
156+
<div class="palette" id="palette"></div>
157+
</div>
158+
159+
<script>
160+
const canvas = document.getElementById('colorWheel');
161+
const ctx = canvas.getContext('2d');
162+
let currentColor = '#FFD700';
163+
164+
// 创建色轮
165+
function createColorWheel() {
166+
const radius = canvas.width / 2;
167+
const imageData = ctx.createImageData(canvas.width, canvas.height);
168+
169+
for (let x = 0; x < canvas.width; x++) {
170+
for (let y = 0; y < canvas.height; y++) {
171+
const dx = x - radius;
172+
const dy = y - radius;
173+
const distance = Math.sqrt(dx * dx + dy * dy);
174+
175+
if (distance > radius) continue;
176+
177+
const angle = Math.atan2(dy, dx);
178+
const hue = angle * 180 / Math.PI + 180;
179+
const saturation = distance / radius * 100;
180+
181+
const rgb = hslToRgb(hue, saturation, 50);
182+
const index = (x + y * canvas.width) * 4;
183+
184+
imageData.data[index] = rgb[0];
185+
imageData.data[index + 1] = rgb[1];
186+
imageData.data[index + 2] = rgb[2];
187+
imageData.data[index + 3] = 255;
188+
}
189+
}
190+
ctx.putImageData(imageData, 0, 0);
191+
}
192+
193+
// HSL转RGB
194+
function hslToRgb(h, s, l) {
195+
h /= 360;
196+
s /= 100;
197+
l /= 100;
198+
199+
let r, g, b;
200+
if (s === 0) {
201+
r = g = b = l;
202+
} else {
203+
const hue2rgb = (p, q, t) => {
204+
if (t < 0) t += 1;
205+
if (t > 1) t -= 1;
206+
if (t < 1/6) return p + (q - p) * 6 * t;
207+
if (t < 1/2) return q;
208+
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
209+
return p;
210+
};
211+
212+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
213+
const p = 2 * l - q;
214+
r = hue2rgb(p, q, h + 1/3);
215+
g = hue2rgb(p, q, h);
216+
b = hue2rgb(p, q, h - 1/3);
217+
}
218+
219+
return [
220+
Math.round(r * 255),
221+
Math.round(g * 255),
222+
Math.round(b * 255)
223+
];
224+
}
225+
226+
// 更新颜色信息
227+
function updateColor(rgb) {
228+
currentColor = `#${rgb.map(v => v.toString(16).padStart(2, '0')).join('')}`;
229+
document.getElementById('colorPreview').style.backgroundColor = currentColor;
230+
document.getElementById('hexValue').value = currentColor;
231+
document.getElementById('rgbValue').value = `rgb(${rgb.join(', ')})`;
232+
generatePalette(rgb);
233+
}
234+
235+
// 生成配色方案
236+
function generatePalette(baseRGB) {
237+
const palette = document.getElementById('palette');
238+
palette.innerHTML = '';
239+
240+
const variations = [
241+
[0, 0, 30], // 更暗
242+
[30, 0, 0], // 更亮
243+
[0, 30, 0], // 增加饱和度
244+
[0, -30, 0], // 降低饱和度
245+
[120, 0, 0] // 互补色
246+
];
247+
248+
variations.forEach(v => {
249+
const newColor = baseRGB.map((c, i) =>
250+
Math.min(255, Math.max(0, c + v[i]))
251+
);
252+
const colorCard = document.createElement('div');
253+
colorCard.className = 'color-card';
254+
colorCard.style.backgroundColor = `rgb(${newColor.join(',')})`;
255+
colorCard.dataset.value = `rgb(${newColor.join(',')})`;
256+
colorCard.onclick = () => updateColor(newColor);
257+
palette.appendChild(colorCard);
258+
});
259+
}
260+
261+
// 随机颜色生成
262+
function generateRandom() {
263+
const randomRGB = [
264+
Math.floor(Math.random() * 256),
265+
Math.floor(Math.random() * 256),
266+
Math.floor(Math.random() * 256)
267+
];
268+
updateColor(randomRGB);
269+
}
270+
271+
// 复制功能
272+
function copyHex() {
273+
navigator.clipboard.writeText(currentColor);
274+
}
275+
276+
function copyRGB() {
277+
navigator.clipboard.writeText(document.getElementById('rgbValue').value);
278+
}
279+
280+
// 初始化
281+
createColorWheel();
282+
canvas.addEventListener('click', (e) => {
283+
const rect = canvas.getBoundingClientRect();
284+
const x = e.clientX - rect.left;
285+
const y = e.clientY - rect.top;
286+
const pixel = ctx.getImageData(x, y, 1, 1).data;
287+
updateColor([pixel[0], pixel[1], pixel[2]]);
288+
});
289+
290+
generateRandom();
291+
</script>
292+
</body>
293+
</html>

0 commit comments

Comments
 (0)