【问题标题】:Calculate color HEX having 2 colors and percent/position计算具有 2 种颜色和百分比/位置的颜色 HEX
【发布时间】:2013-04-27 22:52:06
【问题描述】:

是否可以计算渐变中间的颜色?

var color1 = 'FF0000';
var color2 = '00FF00';

// 50% between the two colors, should return '808000'
var middle = gradient(color1, color2, 0.5); 

我只有两个十六进制字符串,我想要一个作为回报。

【问题讨论】:

标签: javascript jquery colors gradient


【解决方案1】:

这应该可行:

它基本上涉及将它们转换为十进制,找到一半,将结果转换回十六进制,然后将它们连接起来。

var color1 = 'FF0000';
var color2 = '00FF00';
var ratio = 0.5;
var hex = function(x) {
    x = x.toString(16);
    return (x.length == 1) ? '0' + x : x;
};

var r = Math.ceil(parseInt(color1.substring(0,2), 16) * ratio + parseInt(color2.substring(0,2), 16) * (1-ratio));
var g = Math.ceil(parseInt(color1.substring(2,4), 16) * ratio + parseInt(color2.substring(2,4), 16) * (1-ratio));
var b = Math.ceil(parseInt(color1.substring(4,6), 16) * ratio + parseInt(color2.substring(4,6), 16) * (1-ratio));

var middle = hex(r) + hex(g) + hex(b);

【讨论】:

  • 注意第三个参数 -> 0.5color1color2 的比率
  • 嗯,这确实很接近,但是如果比率为 0,则颜色为黑色,而应该为 color1。此外,r.toString 等不会用零填充,对吗?
  • var r1 = parseInt(color1.substring(0,1), 16), r2 = parseInt(color2.substring(0,1), 16); var r = Math.ceil(r1 + (r2-r1)*ratio); ??
  • 子串错误,参数为:(0, 2) - (2, 4) - (4, 6)
  • 十六进制函数返回应该是:return (x.length == 1) ? x + x : x;
【解决方案2】:

上面的答案我无法评论,所以写在这里:

我发现在 Javascript 子字符串方法中,to 参数索引不包含在返回的字符串中。这意味着:

var string = "test";
//index:      0123
alert(string.substring(1,3));

//will alert es and NOT est

编辑:应该是这样的:

parseInt(color1.substring(0,2), 16);
parseInt(color1.substring(2,4), 16);

parseInt(color1.substring(4,6), 16);

【讨论】:

    【解决方案3】:

    带有推导的 ES6 版本:

    function interpolateColor(c0, c1, f){
        c0 = c0.match(/.{1,2}/g).map((oct)=>parseInt(oct, 16) * (1-f))
        c1 = c1.match(/.{1,2}/g).map((oct)=>parseInt(oct, 16) * f)
        let ci = [0,1,2].map(i => Math.min(Math.round(c0[i]+c1[i]), 255))
        return ci.reduce((a,v) => ((a << 8) + v), 0).toString(16).padStart(6, "0")
    }
    

    在接受的答案中,c0,c1 是颜色代码(没有前导 #),f 是两个值之间的“进度”。 (在f=0 这最终返回c0,在f=1 这将返回c1)。

    • 前两行将颜色代码转换为按比例缩放的整数数组
    • 第三行:
      • “压缩”两个整数数组
      • 对相应的值求和
      • 对总和进行四舍五入并将其限制为 0-255
    • 第四行:
      • 将整数数组转换为单个整数(减少和位移)
      • 将整数转换为十六进制字符串形式
      • 确保生成的字符串长度为 6 个字符并返回它

    【讨论】:

      【解决方案4】:

      你可以使用这个准备好的函数(ES6):

      const calculateMiddleColor = ({
        color1 = 'FF0000',
        color2 = '00FF00',
        ratio,
      }) => {
        const hex = (color) => {
          const colorString = color.toString(16);
          return colorString.length === 1 ? `0${colorString}` : colorString;
        };
      
        const r = Math.ceil(
          parseInt(color2.substring(0, 2), 16) * ratio
            + parseInt(color1.substring(0, 2), 16) * (1 - ratio),
        );
        const g = Math.ceil(
          parseInt(color2.substring(2, 4), 16) * ratio
            + parseInt(color1.substring(2, 4), 16) * (1 - ratio),
        );
        const b = Math.ceil(
          parseInt(color2.substring(4, 6), 16) * ratio
            + parseInt(color1.substring(4, 6), 16) * (1 - ratio),
        );
      
        return hex(r) + hex(g) + hex(b);
      };
      //////////////////////////////////////////////////////////////////////
      console.log(calculateMiddleColor({ ratio: 0 / 5 })); // ff0000
      console.log(calculateMiddleColor({ ratio: 5 / 5 })); // 00ff00
      console.log(calculateMiddleColor({ ratio: 2.5 / 5 })); // 808000
      console.log(calculateMiddleColor({ ratio: 4.2 / 5 })); // 29d700
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-23
        • 2023-03-14
        • 2013-09-16
        • 1970-01-01
        • 2016-08-03
        • 1970-01-01
        • 1970-01-01
        • 2014-02-18
        相关资源
        最近更新 更多