醉美水芙蓉 发表于 2026-3-11 21:23:20

马黑黑老师《生成可控范围16进制随机颜色》


<style>
        .artBox { font: normal 18px/1.2 sans-serif; overflow: auto; position: relative; }
        .artBox p { margin: 10px 0; }
        .artBox h1, .artBox h2 { margin: 4px 0; }
        .artBox code, .artBox pre { background: rgba(0,128,128,.25); padding: 2px 6px; tab-size: 4; }
        .artBox pre { padding: 10px 20px; white-space: pre-wrap; word-wrap: break-word; }
        .artBox pre code { padding: 0; background: none; }
        .artBox blockquote { margin: 10px 20px; padding: 2px 15px; border-left: 3px solid skyblue; background: rgba(240,248,255,.65); }
        .artBox table { border-collapse: collapse; white-space: pre-wrap; box-sizing: border-box; }
        .artBox th, .artBox td { padding: 8px 10px; border: 1px solid #999; }
        .artBox th { text-align: center; background: #eee; }
        .tMid { text-align: center; }
        .artBox iframe { width: 500px; height: 300px; border: none; outline: none; }
</style>

<div class="artBox">
<p>JS 生成16进制随机颜色可以非常简单,就一句代码:</p>
<pre><code>const color = '#' + Math.random().toString(16).substring(2, 8);
console.log(color); // → 类似结果:#33ed1f</code></pre>
<p>但当需要可控范围的16进制随机颜色,上述方法无能为力。要实现此功能——</p>
<p><strong>首先</strong>,需要理解16进制颜色的内部结构。本质上,16进制颜色由 R、G、B 即红、蓝、绿三种颜色按一定比例混合而成,每一种单色用16进制两位数表示,不足两位数的前面补零。完整的16进制颜色的表达方式如下:</p>
<blockquote>
<p><strong>#a6cc9f</strong></p>
<p>其中:</p>
<p><code>#</code> 是用来表示16进制的前缀;</p>
<p><code>a6</code> 是 R(红)、<code>cc</code> 是 G(绿)、<code>9f</code> 是B(蓝)</p>
</blockquote>
<p><strong>其次</strong>,需要了解单色分量取值范围,<code>0~255</code>,包含头尾数值。</p>
<p>下面是实现方法:</p>
<p>(一)设计一个取范围值函数,允许设定单色值范围:</p>
<pre><code>const getRdNumFromAr = (ar = ) =&gt; {
    ar.sort((a, b) =&gt; b &gt; a);
    const n1 = Math.min(Math.max(ar, 0), 255), n2 = Math.min(Math.max(ar, 0), 255);
    return Math.round(Math.random() * (n2 - n1) + n1);
};
</code></pre>
<p>此函数预设了取值范围为 ,没有传参时使用它。函数内部,先排序传参数组,以确保小数在前、大数在后;接着处理数组里面两个数值元素,用 Math.min 和 Math.max 方法确保数值不越界(0~255);最后,用 Math.random() 和 Math.round 方法取得最两个数值之间的随机数、四舍五入,并返回结果给调用者。</p>
<p>(二)设计一个创建16进制颜色的函数,允许配置 RGB 范围:</p>
<pre><code>const rdHexColor = (option) =&gt; {
    if (!option) option = { r: , g: , b: };
    const r = getRdNumFromAr(option.r).toString(16).padStart(2, '0');
    const g = getRdNumFromAr(option.g).toString(16).padStart(2, '0');
    const b = getRdNumFromAr(option.b).toString(16).padStart(2, '0');
    return `#${r}${g}${b}`;
};
</code></pre>
<p>函数首先检测是否有传参,如果没有,创建 RGB 缺省配置;接着分别处理三种单色值,以红色 r 为例加以说明:调用 getRdNumFromAr() 函数处理配置值 r(<code>getRdNumFromAr(option.r)</code>),将其变为16进制(<code>toString(16)</code> 方法),得到的结果如果不足两位的前面补零(<code>patStart()</code> 方法);最后拼凑字串并返回结果。</p>
<p>完整的示例代码:</p>
<pre><code id="hexCode">&lt;style&gt;
    #myDiv { margin: auto; margin-top: 40px; width: 400px; height: 240px; border: 1px solid gray; position: relative; }
    #myDiv::before { position: absolute; content: attr(data-c); top: -40px; }
&lt;/style&gt;

&lt;div id="myDiv" data-c="点击下方矩形生成随机颜色"&gt;&lt;/div&gt;

&lt;script&gt;
    const rdHexColor = (option) =&gt; {
      if (!option) option = { r: , g: , b: };
      const r = getRdNumFromAr(option.r).toString(16).padStart(2, '0');
      const g = getRdNumFromAr(option.g).toString(16).padStart(2, '0');
      const b = getRdNumFromAr(option.b).toString(16).padStart(2, '0');
      return `#${r}${g}${b}`;
    };
   
    const getRdNumFromAr = (ar = ) =&gt; {
      ar.sort((a, b) =&gt; b &gt; a);
      const n1 = Math.min(Math.max(ar, 0), 255), n2 = Math.min(Math.max(ar, 0), 255);
      return Math.round(Math.random() * (n2 - n1) + n1);
    };

    const setting = {
      r: ,
      g: ,
      b:
    };

    myDiv.onclick = () =&gt; myDiv.style.background = myDiv.dataset.c = rdHexColor(setting);
&lt;/script&gt;
</code></pre>
<p>效果如下:</p>
<div id="showDiv" class="tMid"></div>
<p>修改红蓝绿单色分量配置即 setting 对象,就可以拿到预期的颜色范围。</p>
</div>

<script>
        const preView = (htmlCode, targetBox) => {
                if (targetBox.innerHTML) return;
                const iframe = document.createElement('iframe');
                iframe.srcdoc = htmlCode;
                targetBox.appendChild(iframe);
                targetBox.style.display = 'block';
                targetBox.onclick = () => {
                        targetBox.innerHTML = '';
                        targetBox.style.display = 'none';
                }
        };
       
        preView(hexCode.innerText, showDiv);
</script>

klxf 发表于 2026-3-11 23:35:29

很实用的知识,谢谢精彩分享

醉美水芙蓉 发表于 2026-3-12 07:06:18

klxf 发表于 2026-3-11 23:35
很实用的知识,谢谢精彩分享

谢谢友友支持!

岩新新 发表于 2026-3-12 20:24:44

感谢分享,充满生活智慧呀

avomyh 发表于 2026-3-13 12:45:49

感谢分享,充满人生哲理

aqady 发表于 2026-3-14 20:37:37

赞,顶帖真的超有水平

zhongshishenti 发表于 2026-3-17 21:47:32

支持发布,内容超有质量

pzqyhkor 发表于 2026-3-17 21:48:46

纳兰叶 发表于 2026-3-19 00:30:19

感谢分享,收获满满幸福

ZessImpunse 发表于 2026-3-19 03:26:31

支持博主,分享太精彩咯
页: [1] 2 3 4
查看完整版本: 马黑黑老师《生成可控范围16进制随机颜色》