|
|

楼主 |
发表于 2025-11-20 19:37
|
显示全部楼层
源码
- <style>
- .pa { margin: 10px auto; width: 740px; height: 740px; font-size: 16px; position: relative; }
- #msvg { position: absolute; width: 100%; height: 90%; }
- #msvg circle { cursor: pointer; }
- #msvg text { font-size: 10px; text-anchor: middle; dominant-baseline: middle; }
- #msvg line { cursor: pointer; stroke: silver; stroke-width: 4; }
- .pa h1 { margin: 0; padding: 20px; font-size: 2em; text-align: center; }
- </style>
- <div id="pa" class="pa">
- <h1 class="txtCenter">颜色转换</h1>
- <svg id="msvg" viewBox="-200 -200 400 400">
- <marker id="arrow" viewBox="0 0 5 5" refX="3.5" refY="2.5" markerWidth="3" markerHeight="3" orient="auto">
- <path d="M 0 0 L 5 2.5 L 0 5 z" fill="gray" />
- </marker>
- <circle id="cHex" cx="-120" cy="-100" r="75" fill="transparent" stroke="silver">
- <title>十六进制 : 点击生成随机颜色</title>
- </circle>
- <circle id="cRgb" cx="120" cy="-100" r="75" fill="transparent" stroke="silver">
- <title>RGB : 点击生成随机颜色</title>
- </circle>
- <circle id="cHsl" cx="0" cy="100" r="75" fill="transparent" stroke="silver">
- <title>HSL : 点击生成随机颜色</title>
- </circle>
- <line id="lHex2Rgb" x1="-10" y1="-110" x2="10" y2="-110" marker-end="url(#arrow)">
- <title>十六进制转RGB</title>
- </line>
- <line id="lRgb2Hex" x1="10" y1="-90" x2="-10" y2="-90" marker-end="url(#arrow)">
- <title>RGB转十六进制</title>
- </line>
- <line id="lHex2Hsl" x1="-80" y1="-10" x2="-70" y2="10" marker-end="url(#arrow)">
- <title>十六进制转HSL</title>
- </line>
- <line id="lHsl2Hex" x1="-50" y1="10" x2="-60" y2="-10" marker-end="url(#arrow)">
- <title>HSL转十六进制</title>
- </line>
- <line id="lRgb2Hsl" x1="70" y1="-10" x2="60" y2="10" marker-end="url(#arrow)">
- <title>RGB转HSL</title>
- </line>
- <line id="lHsl2Rgb" x1="40" y1="10" x2="50" y2="-10" marker-end="url(#arrow)">
- <title>HSL转RGB</title>
- </line>
- <text id="tHex" x="-120" y="0">HEX</text>
- <text id="tRgb" x="120" y="0">RGB</text>
- <text id="tHsl" x="0" y="190">HSL</text>
- </svg>
- </div>
- <script type="module">
- const getRanHex = () => `#${Math.random().toString(16).substring(2,8)}`;
- const getRanRgb = () => {
- const r = Math.floor(Math.random() * 256);
- const g = Math.floor(Math.random() * 256);
- const b = Math.floor(Math.random() * 256);
- return `rgb(${r}, ${g}, ${b})`;
- };
- const getRanHsl = () => `hsl(${Math.floor(Math.random() * 361)}, 100%, 50%)`;
- const HexColor2Rgb = (str) => {
- const fullHex = (str) => {
- let newStr = str.replace('#', '');
- if (newStr.length === 3) {
- return newStr.split('').map(i => i.repeat(2)).join('');
- }
- return newStr;
- };
- const Hex2Dec = (str) => parseInt(str, 16);
- const ar = fullHex(str).match(/.{2}/g).map(a => Hex2Dec(a));
- return 'rgb(' + ar.join(', ') + ')';
- };
- const RgbColor2Hex = (str) => {
- const regex = /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([0-9.]+))?\s*\)/i;
- const matches = str.match(regex);
- if (!matches) return null;
- let r = Math.min(255, Math.max(0, parseInt(matches[1], 10)));
- let g = Math.min(255, Math.max(0, parseInt(matches[2], 10)));
- let b = Math.min(255, Math.max(0, parseInt(matches[3], 10)));
- const toHex = (n) => n.toString(16).padStart(2, '0');
- let hex = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
- return hex;
- };
- const RgbColor2Hsl = (str) => {
- const rgb2Hsl = (r, g, b) => {
- r /= 255;
- g /= 255;
- 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;
- }
- return [h, s, l];
- };
- const regex = /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*([0-9.]+))?\s*\)/i;
- const matches = str.match(regex);
- if (!matches) return null;
- let r = Math.min(255, Math.max(0, parseInt(matches[1], 10)));
- let g = Math.min(255, Math.max(0, parseInt(matches[2], 10)));
- let b = Math.min(255, Math.max(0, parseInt(matches[3], 10)));
- const colors = rgb2Hsl(r, g, b);
- const h = Math.round(colors[0] * 360);
- const s = Math.round(colors[1] * 100) + '%';
- const l = Math.round(colors[2] * 100) + '%';
- return `hsl(${h}, ${s}, ${l})`;
- };
- const HslColor2Rgb = (str) => {
- const hsl2Rgb = (h, s, l) => {
- let r, g, b;
- if(s === 0) {
- r = g = b = l;
- } else {
- const hue2rgb = function 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);
- }
- return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
- };
- const regex = /hsla?\((\d+),\s*([\d.]+)%,\s*([\d.]+)%(\s*,\s*[\d.]+)?\)/i;
- const matches = str.match(regex);
- if (!matches) return null;
- const h = parseInt(matches[1], 10) / 360;
- const s = parseFloat(matches[2]) / 100;
- const l = parseFloat(matches[3]) / 100;
- const colors = hsl2Rgb(h, s, l);
- const r = colors[0];
- const g = colors[1];
- const b = colors[2];
- return `rgb(${r}, ${g}, ${b})`;
- };
- cHex.onclick = () => {
- const color = getRanHex();
- cHex.setAttribute('fill', color);
- tHex.textContent = color;
- }
- cRgb.onclick = () => {
- const color = getRanRgb();
- cRgb.setAttribute('fill', color);
- tRgb.textContent = color;
- };
- cHsl.onclick = () => {
- const color = getRanHsl();
- cHsl.setAttribute('fill', color);
- tHsl.textContent = color;
- };
- lHex2Rgb.onclick = () => {
- const color = HexColor2Rgb(tHex.textContent);
- cRgb.setAttribute('fill', color);
- tRgb.textContent = color;
- };
- lRgb2Hex.onclick = () => {
- const color = RgbColor2Hex(tRgb.textContent);
- cHex.setAttribute('fill', color);
- tHex.textContent = color;
- };
- lRgb2Hsl.onclick = () => {
- const color = RgbColor2Hsl(tRgb.textContent)
- cHsl.setAttribute('fill', color);
- tHsl.textContent = color;
- };
- lHsl2Rgb.onclick = () => {
- const color = HslColor2Rgb(tHsl.textContent);
- cRgb.setAttribute('fill', color);
- tRgb.textContent = color;
- };
- lHsl2Hex.onclick = () => {
- const color = RgbColor2Hex(HslColor2Rgb(tHsl.textContent));
- cHex.setAttribute('fill', color);
- tHex.textContent = color;
- };
- lHex2Hsl.onclick = () => {
- const color = RgbColor2Hsl(HexColor2Rgb(tHex.textContent));
- cHsl.setAttribute('fill', color);
- tHsl.textContent = color;
- };
- window.onload = () => {
- const hexColor = getRanHex();
- const rgbColor = getRanRgb();
- const hslColor = getRanHsl();
- cHex.setAttribute('fill', hexColor);
- tHex.textContent = hexColor;
- cRgb.setAttribute('fill', rgbColor);
- tRgb.textContent = rgbColor;
- cHsl.setAttribute('fill', hslColor);
- tHsl.textContent = hslColor;
- };
- </script>
复制代码
|
|