请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WCAG兼容随机渐变背景生成器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: background 0.5s ease;
padding: 20px;
}
.container {
/*background: rgba(255, 255, 255, 0.95);*/
background: none;
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
max-width: 800px;
width: 100%;
text-align: center;
}
h1 {
margin-bottom: 30px;
font-size: 2.5rem;
font-weight: 700;
}
.controls {
display: flex;
gap: 15px;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 30px;
}
button {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.primary-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.primary-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}
.secondary-btn {
background: #f8f9fa;
color: #333;
border: 2px solid #e9ecef;
}
.secondary-btn:hover {
background: #e9ecef;
transform: translateY(-2px);
}
.demo-text {
margin: 30px 0;
padding: 30px;
border-radius: 15px;
font-size: 1.2rem;
line-height: 1.6;
font-weight: 500;
transition: all 0.5s ease;
}
.info-panel {
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
margin-top: 30px;
text-align: left;
}
.color-info {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-top: 15px;
}
.color-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.color-preview {
width: 30px;
height: 30px;
border-radius: 50%;
border: 2px solid #ddd;
}
.contrast-info {
margin-top: 20px;
padding: 15px;
border-radius: 10px;
font-weight: 600;
}
.contrast-pass {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.contrast-fail {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.gradient-code {
background: #2d3748;
color: #e2e8f0;
padding: 20px;
border-radius: 10px;
font-family: 'Courier New', monospace;
font-size: 14px;
margin-top: 20px;
text-align: left;
overflow-x: auto;
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
h1 {
font-size: 2rem;
}
.controls {
flex-direction: column;
align-items: center;
}
button {
width: 100%;
max-width: 300px;
}
}
</style>
</head>
<body>
<div class="container">
<h1>WCAG兼容随机渐变背景生成器</h1>
<div class="controls">
<button class="primary-btn" onclick="generateGradient()">生成随机渐变</button>
<button class="secondary-btn" onclick="toggleGradientType()">
<span id="gradient-type">切换至三色渐变</span>
</button>
<button class="secondary-btn" onclick="copyCSS()">复制CSS代码</button>
</div>
<div class="demo-text" id="demo-text">
<h2>示例文本</h2>
<p>这是一段用于测试文本可读性的示例内容。好的颜色对比度应该让这段文字在任何背景下都清晰可读,符合WCAG无障碍标准。</p>
<p>This is a sample text to test readability. Good color contrast should make this text clearly readable against any background, meeting WCAG accessibility standards.</p>
</div>
<div class="info-panel">
<h3>当前渐变信息</h3>
<div class="color-info" id="color-info"></div>
<div class="contrast-info" id="contrast-info"></div>
<div class="gradient-code" id="gradient-code"></div>
</div>
</div>
<script>
let isThreeColor = false;
let currentGradient = '';
let currentTextColor = '';
// 生成随机颜色
function randomColor() {
const hue = Math.floor(Math.random() * 360);
const saturation = Math.floor(Math.random() * 50) + 50; // 50-100%
const lightness = Math.floor(Math.random() * 40) + 30; // 30-70%
return { hue, saturation, lightness };
}
// HSL转RGB
function hslToRgb(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
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;
const r = hue2rgb(p, q, h + 1/3);
const g = hue2rgb(p, q, h);
const b = hue2rgb(p, q, h - 1/3);
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
// RGB转HEX
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 getLuminance(r, g, b) {
const [rs, gs, bs] = [r, g, b].map(c => {
c = c / 255;
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
});
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}
// 计算对比度
function getContrastRatio(color1, color2) {
const rgb1 = hslToRgb(color1.hue, color1.saturation, color1.lightness);
const rgb2 = hslToRgb(color2.hue, color2.saturation, color2.lightness);
const lum1 = getLuminance(...rgb1);
const lum2 = getLuminance(...rgb2);
const brightest = Math.max(lum1, lum2);
const darkest = Math.min(lum1, lum2);
return (brightest + 0.05) / (darkest + 0.05);
}
// 获取最佳文本颜色
function getOptimalTextColor(bgColors) {
// 计算背景平均亮度
const avgLuminance = bgColors.reduce((sum, color) => {
const rgb = hslToRgb(color.hue, color.saturation, color.lightness);
return sum + getLuminance(...rgb);
}, 0) / bgColors.length;
// 根据背景亮度选择文本颜色
if (avgLuminance > 0.5) {
// 背景较亮,使用深色文本
return { hue: 0, saturation: 0, lightness: 15 }; // 深灰色
} else {
// 背景较暗,使用浅色文本
return { hue: 0, saturation: 0, lightness: 95 }; // 浅灰色
}
}
// 生成渐变
function generateGradient() {
const angle = Math.floor(Math.random() * 360);
let colors = [];
let colorStops = [];
if (isThreeColor) {
// 三色渐变
colors = [randomColor(), randomColor(), randomColor()];
colorStops = [0, 50, 100];
} else {
// 两色渐变
colors = [randomColor(), randomColor()];
colorStops = [0, 100];
}
// 获取最佳文本颜色
const textColor = getOptimalTextColor(colors);
// 生成CSS渐变
const colorHexes = colors.map(c => rgbToHex(...hslToRgb(c.hue, c.saturation, c.lightness)));
const textColorHex = rgbToHex(...hslToRgb(textColor.hue, textColor.saturation, textColor.lightness));
let gradientCSS;
if (isThreeColor) {
gradientCSS = `linear-gradient(${angle}deg, ${colorHexes[0]} 0%, ${colorHexes[1]} 50%, ${colorHexes[2]} 100%)`;
} else {
gradientCSS = `linear-gradient(${angle}deg, ${colorHexes[0]} 0%, ${colorHexes[1]} 100%)`;
}
// 应用样式
document.body.style.background = gradientCSS;
document.getElementById('demo-text').style.color = textColorHex;
// 计算对比度
const contrastRatio = getContrastRatio(colors[0], textColor);
const contrastAAA = getContrastRatio(colors[Math.floor(colors.length/2)], textColor);
// 更新信息面板
updateInfoPanel(colors, textColor, colorHexes, textColorHex, gradientCSS, contrastRatio, contrastAAA);
currentGradient = gradientCSS;
currentTextColor = textColorHex;
}
// 更新信息面板
function updateInfoPanel(colors, textColor, colorHexes, textColorHex, gradientCSS, contrastRatio, contrastAAA) {
const colorInfo = document.getElementById('color-info');
const contrastInfo = document.getElementById('contrast-info');
const gradientCode = document.getElementById('gradient-code');
// 颜色信息
colorInfo.innerHTML = '';
colors.forEach((color, index) => {
const div = document.createElement('div');
div.className = 'color-item';
div.innerHTML = `
<div class="color-preview" style="background: ${colorHexes[index]}"></div>
<div>
<strong>颜色 ${index + 1}</strong><br>
<small>${colorHexes[index]}</small>
</div>
`;
colorInfo.appendChild(div);
});
// 添加文本颜色
const textDiv = document.createElement('div');
textDiv.className = 'color-item';
textDiv.innerHTML = `
<div class="color-preview" style="background: ${textColorHex}"></div>
<div>
<strong>文本颜色</strong><br>
<small>${textColorHex}</small>
</div>
`;
colorInfo.appendChild(textDiv);
// 对比度信息
const minContrast = Math.min(contrastRatio, contrastAAA);
let contrastClass, contrastText;
if (minContrast >= 7) {
contrastClass = 'contrast-pass';
contrastText = `✅ WCAG AAA级通过 (对比度: ${minContrast.toFixed(2)}:1)`;
} else if (minContrast >= 4.5) {
contrastClass = 'contrast-pass';
contrastText = `✅ WCAG AA级通过 (对比度: ${minContrast.toFixed(2)}:1)`;
} else {
contrastClass = 'contrast-fail';
contrastText = `❌ 对比度不足 (对比度: ${minContrast.toFixed(2)}:1)`;
}
contrastInfo.className = `contrast-info ${contrastClass}`;
contrastInfo.innerHTML = contrastText;
// CSS代码
gradientCode.textContent = `background: ${gradientCSS};
color: ${textColorHex};`;
}
// 切换渐变类型
function toggleGradientType() {
isThreeColor = !isThreeColor;
document.getElementById('gradient-type').textContent =
isThreeColor ? '切换至两色渐变' : '切换至三色渐变';
generateGradient();
}
// 复制CSS代码
function copyCSS() {
const cssCode = `background: ${currentGradient};
color: ${currentTextColor};`;
navigator.clipboard.writeText(cssCode).then(() => {
alert('CSS代码已复制到剪贴板!');
}).catch(() => {
// 降级方案
const textArea = document.createElement('textarea');
textArea.value = cssCode;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
alert('CSS代码已复制到剪贴板!');
});
}
// 页面加载时生成第一个渐变
window.onload = () => {
generateGradient();
};
</script>
</body>
</html>
|