今天咱們想向您展現如何使用CSS Masks建立一個有趣的過渡效果。 與剪切相似,遮罩是定義可見性和與元素複合的另外一種方式。 在下面的教程中,咱們將向您展現如何在簡單輪播圖中爲過渡效果應用新屬性。 咱們將使用steps()計時功能動畫,並在圖像上移動遮罩PNG以實現有趣的過渡效果。html
注意:請記住,這種效果還處於實驗階段,只有現代瀏覽器支持(Chrome,Safari和Opera)。web
使用所選圖像來遮蓋元素的一部分的方法spring
W3C候選人推薦瀏覽器
支持如下版本:bash
桌面應用app
移動端應用框架
能夠在caniuse.com上查看詳細的支持狀況dom
請記住,Firefox只有部分支持(它只支持內聯SVG遮罩元素)因此咱們會有一個回退版本。 但願CSS Masks能儘快獲得全部現代瀏覽器的支持。 請注意,咱們正在添加Modernizr以檢查是否支持。ide
讓咱們一塊兒愉快的開始吧!
在本教程中,咱們將介紹第一個示例(演示1)。
爲了使遮罩過渡效果起做用,咱們須要一個圖像,用於隱藏/顯示基礎圖像的某些部分。 該遮罩圖像將是一個PNG,上面有透明部分。 這個PNG將是一個雪碧圖,它看起來以下:
黑色部分將顯示當前圖像,但白色部分(其實是透明的)將是咱們圖像的遮罩部分,將顯示第二個圖像。
爲了建立雪碧圖,咱們將使用此視頻。 咱們將其導入Adobe After Effects以減小視頻的時間,刪除白色部分並將其導出爲PNG序列。
要將持續時間縮短到1.4秒(咱們但願轉換的時間),咱們將使用時間拉伸效果(Time stretch effect)。
要刪除白色部分,咱們將使用Keying -> extract並將白點設置爲0.在下面的屏幕截圖中,藍色部分是咱們合成的背景,即視頻的透明部分。
最後,咱們能夠將合成的視頻保存爲PNG序列,而後使用Photoshop或CSS sprite生成單個圖像:
這是一個雪碧圖,具備很是連貫的外觀效果。 咱們將爲另外一種效果建立另外一個「反向」雪碧圖。 您將在演示文件的img文件夾中找到全部不一樣的雪碧圖。
如今,咱們已經建立了遮罩圖像,讓咱們簡單實現示例輪播圖的HTML結構。
咱們將建立一個簡單的輪播圖,以顯示遮罩效果。 咱們的輪播圖將填滿整個屏幕,咱們將添加一些將觸發輪播圖切換的箭頭。 想法是覆蓋輪播圖,而後在動畫結束時更改輪播圖的z-index。 輪播圖的結構以下:
<div class="page-view">
<div class="project">
<div class="text">
<h1>「All good things are <br> wild & free」</h1>
<p>Photo by Andreas Rønningen</p>
</div>
</div>
<div class="project">
<div class="text">
<h1>「Into the wild」</h1>
<p>Photo by John Price</p>
</div>
</div>
<div class="project">
<div class="text">
<h1>「Is spring coming?」</h1>
<p>Photo by Thomas Lefebvre</p>
</div>
</div>
<div class="project">
<div class="text">
<h1>「Stay curious」</h1>
<p>Photo by Maria</p>
</div>
</div>
<nav class="arrows">
<div class="arrow previous">
<svg viewBox="208.3 352 4.2 6.4">
<polygon class="st0" points="212.1,357.3 211.5,358 208.7,355.1 211.5,352.3 212.1,353 209.9,355.1"/>
</svg>
</div>
<div class="arrow next">
<svg viewBox="208.3 352 4.2 6.4">
<polygon class="st0" points="212.1,357.3 211.5,358 208.7,355.1 211.5,352.3 212.1,353 209.9,355.1"/>
</svg>
</div>
</nav>
</div>
複製代碼
page view是咱們的全局容器,它將包含咱們的全部輪播圖(project); 每個都包含一個標題和一個圖例。 此外,咱們將爲每張輪播圖設置單獨的背景圖像。
箭頭將做爲下一個或上一個動畫的觸發器,並在輪播圖中導航。
咱們來看看這個風格吧。
在這部分中,咱們將爲咱們的效果添加CSS。
咱們將設置佈局,其中包含一些居中的標題和頁面左下角的導航。 此外,咱們將定義一些媒體查詢來兼容移動設備的展現。
此外,咱們將雪碧圖設置爲全局容器中的不可見背景,以便咱們在打開頁面時開始加載它們。
.demo-1 {
background: url(../img/nature-sprite.png) no-repeat -9999px -9999px;
background-size: 0;
}
.demo-1 .page-view {
background: url(../img/nature-sprite-2.png) no-repeat -9999px -9999px;
background-size: 0;
}
複製代碼
每頁輪播圖都有一個不一樣的背景圖像:
.demo-1 .page-view .project:nth-child(1) {
background-image: url(../img/nature-1.jpg);
}
.demo-1 .page-view .project:nth-child(2) {
background-image: url(../img/nature-2.jpg);
}
.demo-1 .page-view .project:nth-child(3) {
background-image: url(../img/nature-3.jpg);
}
.demo-1 .page-view .project:nth-child(4) {
background-image: url(../img/nature-4.jpg);
}
複製代碼
這固然是你將動態實現的東西,但咱們對效果感興趣,因此讓咱們保持簡單。
咱們定義一個名爲hide的類,只要咱們想隱藏某個元素就能夠添加它。 類定義包含咱們用做遮罩的雪碧圖。
知道一個幀是100%的屏幕,咱們的動畫包含23個圖像,咱們須要將寬度設置爲23 * 100%= 2300%。
如今咱們使用步驟添加CSS動畫。 咱們但願咱們的雪碧圖在最後一幀的開頭中止。 所以,要實現這一目標,咱們須要比總數少一步,即22步:
.demo-1 .page-view .project:nth-child(even).hide {
-webkit-mask: url(../img/nature-sprite.png);
mask: url(../img/nature-sprite.png);
-webkit-mask-size: 2300% 100%;
mask-size: 2300% 100%;
-webkit-animation: mask-play 1.4s steps(22) forwards;
animation: mask-play 1.4s steps(22) forwards;
}
.demo-1 .page-view .project:nth-child(odd).hide {
-webkit-mask: url(../img/nature-sprite-2.png);
mask: url(../img/nature-sprite-2.png);
-webkit-mask-size: 7100% 100%;
mask-size: 7100% 100%;
-webkit-animation: mask-play 1.4s steps(70) forwards;
animation: mask-play 1.4s steps(70) forwards;
}
複製代碼
最後,咱們定義動畫關鍵幀:
@-webkit-keyframes mask-play {
from {
-webkit-mask-position: 0% 0;
mask-position: 0% 0;
}
to {
-webkit-mask-position: 100% 0;
mask-position: 100% 0;
}
}
@keyframes mask-play {
from {
-webkit-mask-position: 0% 0;
mask-position: 0% 0;
}
to {
-webkit-mask-position: 100% 0;
mask-position: 100% 0;
}
}
複製代碼
如今咱們有了輪播圖的結構和樣式。 讓咱們給它添加一些動效吧!
咱們將使用zepto.js進行此演示,這是一個很是輕量級的JavaScript框架,相似於jQuery。
首先聲明全部變量,設置持續時間和元素。
而後咱們初始化事件,獲取當前和下一張輪播圖,設置正確的z-index。
function Slider() {
// Durations
this.durations = {
auto: 5000,
slide: 1400
};
// DOM
this.dom = {
wrapper: null,
container: null,
project: null,
current: null,
next: null,
arrow: null
};
// Misc stuff
this.length = 0;
this.current = 0;
this.next = 0;
this.isAuto = true;
this.working = false;
this.dom.wrapper = $('.page-view');
this.dom.project = this.dom.wrapper.find('.project');
this.dom.arrow = this.dom.wrapper.find('.arrow');
this.length = this.dom.project.length;
this.init();
this.events();
this.auto = setInterval(this.updateNext.bind(this), this.durations.auto);
}
/**
* Set initial z-indexes & get current project
*/
Slider.prototype.init = function () {
this.dom.project.css('z-index', 10);
this.dom.current = $(this.dom.project[this.current]);
this.dom.next = $(this.dom.project[this.current + 1]);
this.dom.current.css('z-index', 30);
this.dom.next.css('z-index', 20);
};
複製代碼
咱們在箭頭上監聽點擊事件,若是當前輪播圖沒有涉及動畫,咱們會檢查點擊是否在下一個或上一個箭頭上。 咱們在調整「下一個」變量的值的時候切換輪播圖。
/**
* Initialize events
*/
Slider.prototype.events = function () {
var self = this;
this.dom.arrow.on('click', function () {
if (self.working)
return;
self.processBtn($(this));
});
};
Slider.prototype.processBtn = function (btn) {
if (this.isAuto) {
this.isAuto = false;
clearInterval(this.auto);
}
if (btn.hasClass('next'))
this.updateNext();
if (btn.hasClass('previous'))
this.updatePrevious();
};
/**
* Update next global index
*/
Slider.prototype.updateNext = function () {
this.next = (this.current + 1) % this.length;
this.process();
};
/**
* Update next global index
*/
Slider.prototype.updatePrevious = function () {
this.next--;
if (this.next < 0)
this.next = this.length - 1;
this.process();
};
複製代碼
這個函數是咱們輪播圖放映的核心:咱們將類「hide」添加到當前輪播圖,一旦動畫結束,咱們減小上一張輪播圖的z-index,增長當前輪播圖中的一個,而後刪除隱藏 上一張輪播圖的類。
/**
* Process, calculate and switch between slides
*/
Slider.prototype.process = function () {
var self = this;
this.working = true;
this.dom.next = $(this.dom.project[this.next]);
this.dom.current.css('z-index', 30);
self.dom.next.css('z-index', 20);
// Hide current
this.dom.current.addClass('hide');
setTimeout(function () {
self.dom.current.css('z-index', 10);
self.dom.next.css('z-index', 30);
self.dom.current.removeClass('hide');
self.dom.current = self.dom.next;
self.current = self.next;
self.working = false;
}, this.durations.slide);
};
複製代碼
添加相應的類將觸發咱們的動畫,而後遮罩圖像應用於咱們的輪播圖。 主要思想是在動畫功能中移動遮罩圖像以建立過渡流。
就是這樣! 我但願這個教程對你有用,而且在建立你本身的酷遮罩效果時感覺到樂趣! 不要猶豫,分享你的做品,我很樂意看到他們!