網(wǎng)頁最麻煩的就是配色。
更麻煩的就是你好不容易配色好了本刽,結(jié)果圖片一換鲸湃,顏色還得重來。子寓。暗挑。
如果要求不高的話,能讓字看出來就好了斜友,但這個目的在遇到奇葩換圖的時候還是會蛋疼炸裆。
比如說,今天的背景圖是深色鲜屏,你來一個白色的字烹看,結(jié)果第二天換圖成了白色圖片,立刻抓瞎洛史。
所以惯殊,要用JS來實現(xiàn)自動簡單配色的話,事情就簡單多了——大概吧也殖。土思。。
要做到這個工作忆嗜,需要三個步驟己儒。
第一,找出目標文字的“背景圖”捆毫。
第二闪湾,找出背景圖在文字所在區(qū)域的顏色范圍。
第三冻璃,修改文字的顏色响谓,按照一定的規(guī)則。
這里只講大致的思路省艳,熟悉JS和HTML5的話娘纷,有了思路很快就能出成果了。
第一步跋炕,找出圖片赖晶。
document.querySelectorAll('img')這個是最先想到的。
但你要知道,背景圖可以不單單是img標簽所給的圖遏插,還可能是div等的background捂贿,所以光有這個還不行。
你需要搜索所有含有background或者background-image這兩個style字段的標簽胳嘲,找到以后讀取字段中的url部分厂僧,并解析獲得圖片實際路徑。如果是填充色或者漸變色的了牛,也可以通過css獲得具體的值颜屠,很容易。
這部分還要注意repeat屬性和size屬性鹰祸,這個都考驗計算的功力——涉及到的和尺寸計算所要的量都可以通過對象的getBoudingClientRect來獲得甫窟。
因此,無論是背景圖蛙婴,還是背景背景圖粗井,現(xiàn)在就都能獲得了。
接下來街图,就是根據(jù)對象的實際位置和大小浇衬,來判斷是否成為了指定文字的“背景”。
這里還是使用getBoundingClientRect來判斷各元素的位置餐济,并由此得到“背景”——需要注意的是径玖,opacity為0的,display為none的颤介,visibility為hidden的梳星,都可以不用考慮在內(nèi)。
如果有多個圖片都在指定區(qū)域范圍內(nèi)——準確地說滚朵,是圖片和文字所在區(qū)塊有交集——那么你還要通過層級關(guān)系冤灾、z-index、transform的translateZ屬性來獲得上下關(guān)系辕近,后者的話還要考慮父容器是否設(shè)置了perspective啟用3D韵吨。繁瑣是繁瑣了點,但只要仔細移宅,都不是什么大問題归粉。
第二步,找圖出片中和文字相關(guān)的區(qū)域漏峰。
找到了圖片糠悼,有了圖片的位置和尺寸,接下來就是找到區(qū)域浅乔。
不單單是找到區(qū)域倔喂,還要找出這個區(qū)域的像素铝条。
這里使用的就是HTML5中的Canvas對象了。
將圖片載入Canvas對象席噩,Canvas的大小和圖片的實際尺寸相當——如果是background屬性調(diào)用的話要注意repeat和size這兩個屬性班缰,然后所用都要注意是否使用了zoom(2D的CSS3屬性)或者scale(3D的CSS3屬性,而且這貨還分scaleX和scaleY)悼枢。根據(jù)實際CSS來控制Canvas的大小和縱橫比埠忘,然后在Canvas中繪制圖片。
接著馒索,利用文字區(qū)塊的所在區(qū)域——還是那個getBoundingClientRect给梅,計算和圖片的相對位置,從而取得要截取的Canvas位置双揪,使用getData獲得數(shù)據(jù)——是RGBA值。
此外要注意的是圖片本身設(shè)置的和透明度相關(guān)的css屬性——在現(xiàn)代瀏覽器上還有變色的filter這個css3屬性包帚,這兩個要注意渔期。好在無論是反色還是灰度還是黑白等等變化都可以通過簡單的算法來對最后的像素結(jié)果做處理。
接下來的是就容易了渴邦。
如果是多個圖片的合成區(qū)域疯趟,就根據(jù)圖片之間的疊加關(guān)系來除了getData的像素結(jié)果,最后生成一塊Data谋梭。
有了像素數(shù)據(jù)信峻,做一個平均,或者根據(jù)你個人的喜好或者美工需求來獲得一個數(shù)字瓮床。
打完收工盹舞。
第三步,設(shè)置圖片顏色隘庄。
有了第二部獲得RGBA值得踢步,接下來就是根據(jù)反色或者別的需求來獲得文字的RGBA值。
可以通過一定的數(shù)據(jù)分析來判斷上述背景區(qū)域是否需要分塊處理丑掺,比如左面是白色获印,右面是黑色,這個就看你數(shù)據(jù)處理的能力了街州,一般使用像素值的剃度變化量就可以做到這件事兼丰。
如果需要分塊的,那么使用不可見的span套用和目標文字塊相同的css屬性唆缴,然后通過試錯法來獲得分塊鳍征。
有了分塊,有了背景色面徽,接下來就是CSS設(shè)置文字顏色的事了蟆技,這部分輕松愉快,不廢話。
上面就是一個自動設(shè)置背景的JS插件的基本思路质礼,有興趣的朋友可以自己做哦~~~~
------------
當然旺聚,需要注意的是:這個方法本身是“泛用型”的,也就是說眶蕉,不管是什么網(wǎng)頁砰粹,丟上去就能用(只要瀏覽器達到現(xiàn)代水平)。
但造挽,對于一些特定類型的網(wǎng)站其實不需要這么泛用碱璃,可以是具有很強針對性的方案。
比如說饭入,這個網(wǎng)頁是我做的嵌器,背景在哪里我知道,只不過背景圖片是隨機抽的一張圖片谐丢。如果是這樣的話爽航,上述尋找圖片和繪制區(qū)域的過程都可以省略,直接寫成參數(shù)就可以了乾忱,這樣可以節(jié)約很多工作量讥珍。
所以,推薦是有針對性地使用背景自動匹配窄瘟,而不是泛用型的衷佃,畢竟我們也要為別人的瀏覽器考慮考慮,不是么蹄葱?
==================
當然氏义,上面是將工作放到前段來完成的方法,工作壓力都在前段图云。
但觅赊,事實上也可以把這個自動化的工作交給后端來完成——
使用PhantomJS繪制一個沒有指定文字區(qū)域的頁面截圖,然后NodeJS使用成熟的圖形庫(以前我自己做過一個基于Cairo的NodeJS的圖像處理插件琼稻,也有成熟的NodeCanvas庫或者NodeWebkit解決方案)來獲得像素吮螺,最后算出文字的顏色——下面是關(guān)鍵——將顏色寫在文件名里,然后前段根據(jù)URL中的背景圖片的文件名就知道自己應(yīng)該是什么顏色了帕翻。
這個操作僅僅在圖片入庫的時候進行一次鸠补,之后前后段都沒有工作量,而且也可以不用考慮前段瀏覽器居然是老舊的IE這樣的非人類問題嘀掸。
當然紫岩,現(xiàn)代瀏覽器的話結(jié)合LocalStorage也可以做到僅入庫的時候做一次自動抓取背景色的工作,但總是比較麻煩的睬塌。