• (译)在非IE浏览器中实现“灰阶化”


    原文:“GRAYSCALING” IN NON-IE BROWSERS

    原文作者:JAMES PADOLSEY

    在非IE浏览器中实现“灰阶化[1]

    这个问题看似简单,实际上要付出很大的努力[2]。要的结果很简单:在所有非IE浏览器中模拟Internet Explorer浏览器的grayscale(灰度)滤镜。然而,它的解决方法并非你想得那么简单,这也让我着实大大地吃了一惊。

    在IE中,grayscale滤镜可以应用到任意一个元素中,它会很直观地将元素转变为灰度。可以使用下面这行复杂且专有的CSS来实现grayscale滤镜。

     

    elem{
    filter
    : progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
    /* 元素必须有“布局值”! */
    zoom
    : 1;
    }

        如上所示,在IE中实现这种效果简单是小菜一碟;然而,在其他的浏览器中,需要引起很大的关注。

    需要有两件情况值得考虑:图片元素和非图片元素。“非图片”类元素实现十分简单:在当前文档中遍历每个元素,寻找类似“backgroundColor”和“color”的色彩属性,将它的RGB颜色值转换为灰度值。有不少方法可以实现;注意我们这里不是说降低图片的饱和度;“灰阶化”很明显跟它不一样。

     

    代码
    // 降低饱和度:
    function RGBtoDesat(r,g,b)
    {
    var average = (r + g + b) / 3;
    return {
    r
    : average,
    g: average,
    b: average
    };
    }

    // 灰阶化:
    function RGBtoGrayscale(r,g,b)
    {
    var mono = parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 );
    return {
    r
    : mono,
    g: mono,
    b: mono
    };
    }

    因此,每个带颜色属性的元素要使用它来转为灰阶;初始颜色用来重置属性值。

    我们的图片能否转为灰阶取决于两个因素;一是浏览器必须要支持HTML5 canvas元素和它getImageData方法,二是主机上的所有图片必须位于同一域名下;除此外,主机上的图片不能脱离getImageData方法而不管它是否支持[3]。Google Chrome浏览器和Safari(4以下版本)由于不支持getImageData,先不作讨论。其他的浏览器支持canvas元素,完全可以做到“灰阶化”图片。

    实现这种方式是要“手工”遍历图片中的每一像素,并应用我们用来设置CSS 颜色属性的RGBtoGrayscale函数。真要这样做的话,浏览器绝对吃不消;除非有极其快速的Javascript引擎来承受大图片处理的压力。

    鉴于上面提到的原因,因此在任一个元素需要“灰阶化”前,添加一个“预置”函数去运行显得尤为必要,这个函数可以使用零超时递归技术[4]来避免耗死浏览器。如果仅仅是小图片需要转换的话,不必使用“预置”函数,可以直接使用这种暴力转换。

    为什么呢,这是为什么呢?

    你肯定想知道在“灰阶化”会有哪些应用。那么,比如说:降低色彩以减少用户的视觉焦点,以此来减少用户对你网站上五颜六色东西的关注;比如说,光箱特效。像vBulletin的论坛系统就使用了这种效果,它会你点击离开时,将页面变灰;然后会弹出确认框,这个确认框非很容易识别,因为它是页面中惟一的带色彩的东西。

    “灰阶化”困扰我的真实原因是因为我很想知道是否有可能做到这个目的。我已经知道在IE浏览器里有这个滤镜,我还想看看在其他浏览器中能否模拟实现这种方便的特效。我也知道这种特效可能被认为已经过时了,但这并不重要;我仅仅是对实现它很感兴趣。

    示例

    我做了一个示例页面,上面有几个格斗士[5]的图片,功能已经在这篇文章中说过了。注意,在Safari(小于4)或者Chrome(还有可能在Firefox老版本(V.2以前))不起作用;不要忘了它仅仅是一个试验。

    查看演示

    使用方法

    要对一个元素实现“灰阶化”需要调用grayscale()函数,并将元素作为参数传递,比如:

     

    代码
    var el = document.getElementById( 'myEl' );
    grayscale( el );
    // 也可以传递一个DOM集合
    //
    (这样所有的元素都会得到“灰度效果”)
    grayscale( document.getElementsByTagName('div') );
    //也可以在jQuery对象集合中使用
    grayscale( $('div') );

    若要重置元素(返回到原来的颜色状态)必须调用grayscale.reset(),并将需要重置的元素作为参数传递:

    grayscale.reset( el );
    // reset()同样可以接受DOM对象或jQuery对象集合参数
    grayscale.reset( $('div') );

    其中的prepare函数,上面已经讲过了,在有大图片要处理的情况下需要使用到,或者即使只是几个小图片。注意大图片需要有一会儿的时间去处理(一张300×300的PNG格式图片在“预置”方式下需要耗费3秒钟的时间)。

     

    grayscale.prepare( document.getElementById('myEl') );
    // 同样可以接受DOM对象或jQuery对象集合参数
    grayscale.prepare( $('.gall_img') );

    [完]

    注:

    [1]:灰阶化:原文grayscaling,意为“采取灰度标准”,即灰阶化,将图片由彩色转为灰度;

    [2]原文为”This started out as a little experiment and eventually turned into quite an endeavor.“,可能存在翻译问题;

    [3]原文为“externally hosted images cannot be passed into ‘getImageData’ regardless of whether it’s supported.”,翻译存疑;

    [4]零超时递归技术:原文zero-timeout recursion technique,应为zero-time recursive technique;参见http://en.wikipedia.org/wiki/Recursion_(computer_science)

    [5]格斗士:原文blood-thirsty hunters,嗜血的猎人

  • 相关阅读:
    dynamic 转换实体类
    泛型的简单使用
    winfrom嵌入word
    echart睡眠后台代码,
    echart实现睡眠前台代码
    Mysql时间加一天
    一道关于面向对象面试题所引发的血案(阿里)
    一道面试题让你彻底掌握JS中的EventLoop(头条)
    对象(数组)的深克隆和浅克隆(头条)
    BAT笔试题中几道关于堆栈内存和闭包作用域的题
  • 原文地址:https://www.cnblogs.com/walkingp/p/1717747.html
Copyright © 2020-2023  润新知