摘要:與繪制順序密切相關的概念是層疊上下文。把正常也算上的話,現在網頁里可用的混合模式一共種。因此,正片疊底是一個變暗的混合模式。需要注意的是,其中這個位于最下層的背景該元素無背景色,它的混合模式其實是沒有作用的,可以認為就是默認值。
圖層
在Photoshop等圖像編輯軟件里,圖層是最基礎的概念之一。我們平時看一張照片,就可能想到“遠處的背景”、“近處的人物”這樣的描述,這其實就是在劃分圖層。多個圖層從下到上(從遠到近)依次拼合,就得到完整的圖像。
分圖層很有用。一方面,圖層是獨立的,修改時不會相互影響,另一方面,圖層可以保留原始圖像,便于還原或做其他調整。
網頁里的圖層在網頁里,并沒有明確的圖層的概念,但卻很適合當做圖層去理解。網頁內的每個元素,都可以看做有一個自己的圖層。css里的z-index,也很像是調整圖層順序的工具。
準確地說,決定網頁內元素覆蓋關系的是繪制順序,繪制順序靠后的元素,將覆蓋繪制順序靠前的元素。
與繪制順序密切相關的概念是層疊上下文(stacking context)。在一個層疊上下文內,瀏覽器總是遵循特定的順序去繪制該上下文內的所有元素。
重疊與合成我們有時候會很仔細地去調整z-index,這是因為網頁內的元素會有重疊:
像這樣重疊時,一個元素就擋住另一個元素的一部分。我們可能想改變一下覆蓋關系:
在這里,它們的差異只有元素的重疊部分。如果重疊部分和其中一個元素一致,那么看起來就是這個元素更靠上,覆蓋了另一個元素。
實際上,網頁里的重疊遠不只有這樣一小部分。上面的示例里的兩個元素除了相互重疊外,各自也與本文的背景元素存在重疊。如果在元素上設置一個背景,那么可以說頁面內的所有可見元素的最終顯示效果,都和這個背景關聯了起來。
網頁是如何決定在這樣多的重疊關系下,最終呈現的效果的?這也是一個有一定章法的過程,叫做合成(compositing)。
簡單透明度合成簡單透明度合成(simple alpha compositing)是我們很容易理解的一種合成方式。它是在本文接下來要介紹的混合模式出現之前,唯一在網頁里應用的合成方式。它在當前各類瀏覽器內都可用。
之所以說容易理解,是因為它和我們平時的視覺感受很一致。比如前文的例子里改變一下其中一個元素的透明度:
當一個元素是半透明的,那么即便它遮擋了在它后面的元素的一部分,那一部分也是可見的。透明度越高(opacity越接近0),則重疊區域越偏向于被遮擋的元素。完全透明(opacity為0)時,則看起來沒有元素被遮擋。
新的合成:混合模式混合模式一直是Photoshop等圖像編輯軟件內的圖層面板的重要功能,現在它也存在于w3c的推薦規范。
網頁中可用的混合模式如下:
上圖是對照Photoshop里的混合模式來標注的,其中紫紅色部分是網頁里可用的混合模式,最右邊則是混合模式的群組分類。默認的“正?!保瑢嶋H就是前面說的簡單透明度合成,因此可以認為是新增了15種混合模式。把“正?!币菜闵系脑挘F在網頁里可用的混合模式一共16種。
雖然混合模式種類不少,但最為常用的并不多,它們分別是正片疊底(Multiply)、濾色(Screen)、疊加(Overlay)和柔光(Soft Light)。
混合模式的簡要原理混合模式本質是分別取前景和背景(參與混合的兩個圖層)的像素點,然后用它們的顏色值進行數學運算,從而得到一個新的顏色值。每一個重疊區域的像素點都會經過這個計算過程。
下面以正片疊底為例,說明一下這個過程。
顏色值歸一化混合模式既然拿顏色值來做數學計算,那么顏色值一定是數字的形式。不過,顏色值會對應怎樣的數字呢?在混合模式計算里,所有的顏色值都是從0到1的小數(區間[0, 1])。因此,顏色值在參與計算前,都會轉換為這樣的小數。
顏色都可以用RGB來表示,如純白色在css里可以表示為rgb(255, 255, 255)。注意RGB三通道的最大值為255,最小值為0,因此可以用通道色值÷255的計算式轉換為0到1的數字。比如純白色將是rgb(1, 1, 1)。
分通道進行計算正片疊底(Multiply,日語版寫作“乗算”)的計算式是:
x = a × b
可以看到,這就是一個簡單的乘法。由于都是0到1之間的小數,因此乘法運算會使結果值更接近0(比如0.8 x 0.5 = 0.4)。因此,正片疊底是一個變暗的混合模式。
每一種混合模式,都會對應這樣一個計算式,其中a表示前景圖層(Active Layer),b表示背景圖層(Background Layer)。RGB三通道分別進行一次運算后,就可以得到混合后的顏色值。整個過程如下:
在圖層設置了透明度的情況下,混合的計算式中的數字仍然取圖層原本的像素顏色(也就是opacity: 1;時看到的顏色)。
css用法說明與混合模式有關的一共3個屬性,background-blend-mode、mix-blend-mode和isolation。
background-blend-mode這個屬性一般和多重背景的background-image搭配使用,它和background-image一樣可以指定多個值。這將在某一個元素的多個背景之間形成混合,比如:
.blending-element-0 { background-image: url(1.jpg), url(2.jpg), url(3.jpg); background-blend-mode: multiply, screen; }
可以看到,這個元素指定了多個背景,從上到下依次是1.jpg、2.jpg、3.jpg。下面的background-blend-mode則是與它對應的,它表示1.jpg的混合模式是multiply,2.jpg的混合模式是screen,3.jpg的混合模式是multiply(當background-blend-mode的數目比background-image少時,會按照值列表進行重復)。
需要注意的是,其中3.jpg這個位于最下層的背景(該元素無背景色),它的混合模式multiply其實是沒有作用的,可以認為就是默認值normal。你可以試試在Photoshop里只留一個圖層,然后切換各種混合模式,會發現圖像不會有任何變化。
如果元素指定了背景色(background-color),那么背景色將成為最下層的背景。
如果有使用background這個簡寫屬性,那么background-blend-mode的值將會被重置為默認。
mix-blend-mode與isolation這2個屬性是搭配使用的。相比前面的background-blend-mode是應用在單個元素的多背景之間,mix-blend-mode則是應用于多個元素,而且除背景外,元素內的文字等其他內容也會被混合。
mix-blend-mode比較類似opacity,作用于一個元素的同時也會作用于這個元素的全部子元素。因此,如果不想要子元素內容也受到影響(就像設置半透明時可能希望里面的文字仍是不透明的),改用background-blend-mode會更合適。
使用mix-blend-mode的代碼大致這樣:
.blending-element-1, .blending-element-2{ mix-blend-mode: soft-light; }
在這個例子中,只要div.blending-element-1和div.blending-element-2存在重疊,就可以有混合效果。那么,只是這2個元素之間混合嗎?父元素div.container有背景,甚至前面還有其他的位于下方的元素的話,它們也參與混合嗎?
這就是如何界定哪些元素參與混合的問題。網頁里是這樣做的:以層疊上下文(stacking context)為依據,為元素進行分組,位于同一個層疊上下文內的元素算作同一組,同一組內才能發生混合。
請再看這樣一個例子(只列出了相關的css):
.container { background: gray; } .blending-image { mix-blend-mode: multiply; }
效果是:
可以看到div.container的灰色背景和img.blending-image的圖片內容已經有了混合效果。這時候,再給中間的元素div.inner-wrapper稍作改變:
.inner-wrapper{ isolation: isolate; }
會看到混合模式失效了:
可以看到,在有了isolation: isolate這個屬性后,好像就有了字面上“隔離”的效果。
事實上,并沒有“隔離”這種特殊效果,它的本質是創建新的層疊上下文。在元素合成這一點上,你可以理解為是新開一個分組。分組有什么用呢?請看下圖:
這種層級關系非常像html的DOM樹,只不過,每一個節點(分組)的生成,都需要有對應元素創建新的層疊上下文。如果沒有元素創建新層疊上下文,那么無論DOM樹多么復雜,它們都屬于同一個層疊上下文內(也就是上圖沒有任何group,layer1~6平鋪)。
分組會改變元素參與混合的先后順序。在復雜的DOM樹中,可能有多個元素都設置了混合模式,這時候,總是組內的圖層先相互混合,然后把整個組看作一個整體,再和組外的其他元素混合。由于DOM元素默認的混合方式都是normal,也就是上層遮擋下層的風格,因此看起來就好像組內和組外隔離了開來,這就是isolation的意思。
前面說isolation可以和mix-blend-mode搭配使用,就是因為它可以為元素之間的混合增加一層控制。對于background-blend-mode而言,isolation并沒有用,因為background-blend-mode作用的多個背景都位于同一個元素內部,相當于一定在一個獨立的分組內,和外部的其他元素無關。
關于更多的創建新的層疊上下文的條件,推薦查看MDN的文檔。你可以看到isolation: isolate;只是其中的一種情況。
附帶的一點補充 瀏覽器兼容性background-blend-mode
mix-blend-mode
就本文的時間點而言,瀏覽器的支持范圍還是有些不足。不過,混合模式只是一個視覺效果,要做兼容的話,先看看那些不支持的瀏覽器里的效果吧。如果差得不多,你也許可以接受。如果情況并不能接受,那就做一些調整,比如圖片素材等,直到它看起來不是太難看。
合成的另一個步驟w3c文檔里提到合成(compositing)實際上分為兩步,第一步是混合(blending),緊接著還有第二步叫Porter-Duff compositing。如果你有興趣,可以自行查看。
這個Porter-Duff compositing雖然包含了很多種類,但就css而言,其實只有source-over可用(也就是說,固定的)。這也正是和我們視覺感受最一致的前景覆蓋后景的效果。
前文有提到混合模式的計算式所取的顏色值是不考慮透明度的,但實際我們知道在應用混合模式的同時設置透明度是可以改變效果的。這就是因為透明度會在這第二步合成里參與計算。
更多混合模式的計算原理推薦閱讀Photoshop Blend Modes Explained。
結語一個有趣的事情是,我們在用混合模式的時候,幾乎都是會去一個一個試,直到找到看起來還不錯的效果。而不是說,我能一眼知道應該用哪個混合模式。不過即便如此,了解一點混合模式的原理,也還是應該有助于我們更快地找到那個不錯的混合模式的,大概。
在我看來,網頁的混合模式可以減少某些圖像素材的編輯工作。另外,因為原圖被保留了下來,所以可以在任何需要的時候還原,或者重新參與合成。
(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2016/01/blending-modes-adventure)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/115026.html
摘要:混合式開發做出的手機應用無論在性能還是易用性方面都很接近原生應用。下面介紹幾個流行的混合式開發框架。相比于其他開發框架,更加輕量,體積小巧。 目前混合式開發已經逐漸成熟,混合式app開發只需要要求開發者會使用css和js前端代碼就可以實現手機app應用的開發,而不需要再去學習安卓或蘋果開發,降低了app開發的門檻。混合式開發做出的手機應用無論在性能還是易用性方面都很接近原生app應用。...
摘要:混合式開發做出的手機應用無論在性能還是易用性方面都很接近原生應用。下面介紹幾個流行的混合式開發框架。相比于其他開發框架,更加輕量,體積小巧。 目前混合式開發已經逐漸成熟,混合式app開發只需要要求開發者會使用css和js前端代碼就可以實現手機app應用的開發,而不需要再去學習安卓或蘋果開發,降低了app開發的門檻?;旌鲜介_發做出的手機應用無論在性能還是易用性方面都很接近原生app應用。...
閱讀 3139·2021-09-28 09:36
閱讀 3684·2021-09-08 09:45
閱讀 1792·2021-09-01 10:43
閱讀 3470·2019-08-30 12:44
閱讀 3343·2019-08-29 17:25
閱讀 1368·2019-08-29 11:03
閱讀 1989·2019-08-26 13:36
閱讀 690·2019-08-23 18:24