大多数浏览器支持的方法来改变简单PNG图像的颜色?

时间:2015-01-19 21:33:25

标签: html css svg mask

在网站构建期间,我在设计中遇到了鼠标悬停样式的这个方向(由我解释):

paraphrased comp style

这很简单,可以用js(甚至是css)图像交换......但它让我思考。整个网站上会有几十个这样的图标链接 - 每个都与文本配对,每个都可能需要额外的颜色,或者调整蓝色。为任何其他颜色创建每个图像的新版本将是一个令人头痛的问题,如果需要调整任何颜色,那将是一场噩梦。如果你能用css在一个地方控制文字和图像颜色,那不是很好吗?

我做了一些研究,影响图像颜色的流行观点似乎是在使用CSS3蒙版或将整个作品放在SVG之间。 CSS掩码是一个非常有吸引力的选项,因为它们简单,但有one glaring support gap - 而SVG is recommended by W3C但似乎依赖于.svg格式的图像(.png解决方案变得复杂且有点支持)。 / p>

那么,是否有人知道一种解决方案可以让我有效地改变平面.png图像的颜色,从而提供足够的浏览器支持?简单/优雅的奖励点,但我会接受任何只需要.png图像和十六进制颜色的路径的东西。谢谢!


编辑1: 为了记录,IE9-10超出了范围 - 我们只看8和11.谢谢!


编辑2:其他(失败)注意事项

我考虑过简单地为每个图标创建一个倒置的“模板”并将其覆盖在背景颜色上。然而,这对我们的用户和内容编辑者来说是一个问题,因为这些图标将在其他地方使用,白色背景上的白色模板是无用的。

同时阅读答案on this related question,但过滤器似乎不接受十六进制值,也不完全支持它们。图标字体可能有效,但不容易扩展/修改为非精明的用户 - 这里非常需要“上传到cms”功能。

1 个答案:

答案 0 :(得分:1)

答案&演示

  

我已经解决了问题,这是一个JSFiddle

赞成

  • 它非常易于使用。
  • 您可以选择JavaScript已知的任何格式的任何颜色。
  • 您的图标可以是除白色外的任何颜色。

缺点

  • 为了与所有颜色格式兼容,它需要tinycolor.js库作为依赖项。 (但是:如果您创建自己的颜色转换函数,则可以删除)

  • 它仅适用于 IE9 + ,因为它使用HTML5 canvas。 (虽然说实话,IE的编码总是很痛苦。)

  • 源图像必须位于同一服务器中,因为画布无法从跨源源获取污染,并且您无法从中获取数据,这就是源图像的原因在演示中位于Data URI。 (但是:如果您有兴趣,可以solution。)

HTML

<input type="text" value="#669dbb">
<button>Change color</button>
<img src="data:image/png;base64,(..)">

很简单,您希望图像更改为的颜色为<input>,而<button>则应用更改。 (顺便说一句,原始值是您在默认图标上的淡淡蓝色。)

的JavaScript

var img = document.querySelector("img");
var button = document.querySelector("button");
var text = document.querySelector("input");
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");

button.onclick = function () {
    changeColor(text.value);
};

changeColor = function (inputColor) {
    canvas.setAttribute("width", img.width);
    canvas.setAttribute("height", img.height);
    context.drawImage(img, 0, 0);
    var dataObject = context.getImageData(0, 0, canvas.width, canvas.height);
    var data = dataObject.data;
    for (var i = 0; i < data.length; i += 4) {
        var r = data[i],
            g = data[i + 1],
            b = data[i + 2],
            a = data[i + 3];
        var notTransparent = a != 0;
        var nonBackground = ( notTransparent && r != 255 && g != 255 && b != 255 );
        if ( nonBackground ) {
            var input = tinycolor(inputColor);
            var rgb = input.toRgb();
            data[i] = rgb.r;
            data[i + 1] = rgb.g;
            data[i + 2] = rgb.b;
            data[i + 3] = a;
        }
    }
    context.putImageData(dataObject, 0, 0);
    img.src = canvas.toDataURL();
}

说明

Okey,这里发生了什么,我将把我的解释集中在changeColor()函数上,因为其他代码块只是后台工作。

  • 首先,我们匹配<img>的宽度&amp;高度为<canvas>
  • 然后,我们将图像绘制到画布上。
  • 然后,我们从整个画布中获取像素数组数据。 (更多关于canvas pixel manipulation
  • 然后我们读取数据(这是一个loooong数组)并获取每个像素值。
    • 数组[0] =红色
    • 数组[1] =绿色
    • 数组[2] =蓝色
    • 数组[3] = Alpha。
  • 然后,我们通过确保不透明也不是白色来检查像素是否不是背景像素。
  • 如果不是,我们会得到输入颜色并将其设为RGB。
  • 然后,我们修改像素数据并更新画布。
  • 最后,我们从画布中获取<img>来源,将其转换为Data URI,然后更新<img>

还有一件事

现在,虽然这可能很酷而且所有这些都需要花费大量的工作才能开始,所以我已经让你更容易了,这里有一个图书馆可以让你做你想做的事情:AmazingIcon.js (Github)

它不是很完美,但是它会起作用,这就是它的工作原理。

HTML(头)

<script src=tinycolor.js></script>
<script src=amazingicon.js></script>

HTML(体)

<a class="amazingIcon" href="some-url" data-src="icon-image-url">icon-label</a>

相当简单,我们使用data-src创建伪自定义属性。

的JavaScript

AmazingIcon.parseDocument();

AmazingIcon.hover(function(icon,ev){
    icon.setColor("lightblue");
});

AmazingIcon.parseDocument()函数会将具有类amazingIcon的任何锚转换为惊人的图标。

AmazingIcon.hover(callback)函数将悬停事件应用于所有令人惊叹的图标,悬停事件函数将接收两个(icon,event)参数,您可以相应地操作它们。 (有关文档的更多信息)

CSS

.AmazingIconObject{
    /* Display icons in the same row */
      display: inline-block;
    /* Aligning icons vertically inside parent */
      vertical-align: top;
    /* Centering labels */
      text-align: center;
    /* Sepparation between the icons */
      margin-right: 5px;
    /* Break label to fit icon width */
      word-wrap: break-word;
    /* Sets the width of the anchor (not the icon) */
      width: 100px;
    /* The following properties are design-subjective */
      font-family: Verdana;
      font-weight: bold;
      color: lightcoral;
      margin-right: 5px;
      text-decoration: none;
}

非常简单,如果您想了解它的工作原理当然是github中的所有内容,请随意重复和修改代码,就像您和其他任何读者一样。

笔画演示

由于难以使用非交叉源的演示,我只会向您展示一个看起来像什么的图像。

Demonstration of the AmazingIcon.js library.

希望这有帮助,看到你!