颜色选择器
响应式设计的颜色选择器,适配各种屏幕尺寸
支持色相滑块和RGB数值两种调色方式
点击颜色值或复制按钮即可复制十六进制颜色代码
自动根据背景色调整文字颜色确保可读性
包含复制成功提示动画效果
现代化UI设计,采用圆角、阴影和渐变背景
完全原生JavaScript实现,无外部依赖
支持键盘输入RGB数值实时更新颜色

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>颜色选择器</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #6366f1;
--secondary: #8b5cf6;
--dark: #1e293b;
--light: #f8fafc;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Inter', system-ui, sans-serif;
background: linear-gradient(135deg, #f5f7fa, #e4e8f0);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.color-picker-container {
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 400px;
padding: 25px;
text-align: center;
}
.color-picker-title {
color: var(--dark);
margin-bottom: 20px;
font-size: 24px;
font-weight: 600;
}
.color-display {
width: 100%;
height: 150px;
border-radius: 10px;
margin-bottom: 20px;
transition: background-color 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
}
.color-value {
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 15px;
border-radius: 20px;
font-family: monospace;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
}
.color-value:hover {
transform: scale(1.05);
}
.color-controls {
display: flex;
flex-direction: column;
gap: 15px;
}
.color-slider {
width: 100%;
height: 10px;
-webkit-appearance: none;
appearance: none;
background: linear-gradient(to right, red, yellow, lime, cyan, blue, magenta, red);
border-radius: 5px;
outline: none;
margin: 10px 0;
}
.color-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: white;
border: 2px solid var(--dark);
cursor: pointer;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.rgb-controls {
display: flex;
gap: 10px;
margin-top: 10px;
}
.rgb-input {
flex: 1;
padding: 8px;
border: 1px solid #ddd;
border-radius: 5px;
text-align: center;
font-family: monospace;
}
.copy-btn {
background: var(--primary);
color: white;
border: none;
padding: 12px 20px;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 15px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.copy-btn:hover {
background: var(--secondary);
transform: translateY(-2px);
}
.toast {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 12px 24px;
border-radius: 8px;
font-size: 14px;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 1000;
}
.toast.show {
opacity: 1;
}
@media (max-width: 480px) {
.color-picker-container {
padding: 20px;
}
.rgb-controls {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="color-picker-container">
<h1 class="color-picker-title">颜色选择器</h1>
<div class="color-display" id="colorDisplay">
<span class="color-value" id="colorValue">#FFFFFF</span>
</div>
<div class="color-controls">
<input type="range" class="color-slider" id="hueSlider" min="0" max="360" value="0">
<div class="rgb-controls">
<input type="number" class="rgb-input" id="redInput" min="0" max="255" value="255" placeholder="R">
<input type="number" class="rgb-input" id="greenInput" min="0" max="255" value="255" placeholder="G">
<input type="number" class="rgb-input" id="blueInput" min="0" max="255" value="255" placeholder="B">
</div>
<button class="copy-btn" id="copyBtn">
<i class="fas fa-copy"></i> 复制颜色代码
</button>
</div>
</div>
<div class="toast" id="toast">已复制到剪贴板</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const colorDisplay = document.getElementById('colorDisplay');
const colorValue = document.getElementById('colorValue');
const hueSlider = document.getElementById('hueSlider');
const redInput = document.getElementById('redInput');
const greenInput = document.getElementById('greenInput');
const blueInput = document.getElementById('blueInput');
const copyBtn = document.getElementById('copyBtn');
const toast = document.getElementById('toast');
let currentColor = {
h: 0,
s: 100,
l: 50,
r: 255,
g: 255,
b: 255
};
// 初始化颜色
updateColor();
// 色相滑块事件
hueSlider.addEventListener('input', function() {
currentColor.h = parseInt(this.value);
hslToRgb();
updateColor();
});
// RGB输入事件
[redInput, greenInput, blueInput].forEach(input => {
input.addEventListener('input', function() {
const value = Math.min(255, Math.max(0, parseInt(this.value) || 0));
this.value = value;
if (this.id === 'redInput') currentColor.r = value;
if (this.id === 'greenInput') currentColor.g = value;
if (this.id === 'blueInput') currentColor.b = value;
rgbToHsl();
updateColor();
});
});
// 复制按钮事件
copyBtn.addEventListener('click', function() {
const hexColor = rgbToHex(currentColor.r, currentColor.g, currentColor.b);
navigator.clipboard.writeText(hexColor).then(() => {
showToast();
});
});
// 点击颜色值也可以复制
colorValue.addEventListener('click', function() {
const hexColor = rgbToHex(currentColor.r, currentColor.g, currentColor.b);
navigator.clipboard.writeText(hexColor).then(() => {
showToast();
});
});
// 更新颜色显示
function updateColor() {
const hexColor = rgbToHex(currentColor.r, currentColor.g, currentColor.b);
colorDisplay.style.backgroundColor = hexColor;
colorValue.textContent = hexColor;
// 根据亮度调整文字颜色
const brightness = (currentColor.r * 299 + currentColor.g * 587 + currentColor.b * 114) / 1000;
colorValue.style.color = brightness > 128 ? 'black' : 'white';
colorValue.style.background = brightness > 128 ? 'rgba(255, 255, 255, 0.7)' : 'rgba(0, 0, 0, 0.7)';
// 更新RGB输入框
redInput.value = currentColor.r;
greenInput.value = currentColor.g;
blueInput.value = currentColor.b;
// 更新色相滑块
hueSlider.value = currentColor.h;
}
// HSL转RGB
function hslToRgb() {
const h = currentColor.h / 360;
const s = currentColor.s / 100;
const l = currentColor.l / 100;
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
currentColor.r = Math.round(r * 255);
currentColor.g = Math.round(g * 255);
currentColor.b = Math.round(b * 255);
}
// RGB转HSL
function rgbToHsl() {
const r = currentColor.r / 255;
const g = currentColor.g / 255;
const b = currentColor.b / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} 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;
}
currentColor.h = Math.round(h * 360);
currentColor.s = Math.round(s * 100);
currentColor.l = Math.round(l * 100);
}
// RGB转十六进制
function rgbToHex(r, g, b) {
return '#' + [r, g, b].map(x => {
const hex = x.toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('');
}
// 显示提示
function showToast() {
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 2000);
}
});
</script>
</body>
</html>