- 原文地址:codrops
- 原文作者:Robin Delaporte
今天我們想向您展示如何使用CSS Masks建立一個有趣的過渡效果。 與剪下類似,遮罩是定義可見性和與元素複合的另一種方式。 在下面的教程中,我們將向您展示如何在簡單輪播圖中為過渡效果應用新屬性。 我們將使用steps()計時功能動畫,並在影象上移動遮罩PNG以實現有趣的過渡效果。
注意:請記住,這種效果還處於實驗階段,只有現代瀏覽器支援(Chrome,Safari和Opera)。
CSS Masks
使用所選影象來遮蓋元素的一部分的方法
W3C候選人推薦
支援以下版本:
桌面應用
移動端應用
可以在caniuse.com上檢視詳細的支援情況
請記住,Firefox只有部分支援(它只支援內聯SVG遮罩元素)所以我們會有一個回退版本。 希望CSS Masks能儘快得到所有現代瀏覽器的支援。 請注意,我們正在新增Modernizr以檢查是否支援。
讓我們一起愉快的開始吧!
建立遮罩圖片
在本教程中,我們將介紹第一個示例(演示1)。
為了使遮罩過渡效果起作用,我們需要一個影象,用於隱藏/顯示基礎影象的某些部分。 該遮罩影象將是一個PNG,上面有透明部分。 這個PNG將是一個雪碧圖,它看起來如下:
黑色部分將顯示當前影象,但白色部分(實際上是透明的)將是我們影象的遮罩部分,將顯示第二個影象。
為了建立雪碧圖,我們將使用此視訊。 我們將其匯入Adobe After Effects以減少視訊的時間,刪除白色部分並將其匯出為PNG序列。
要將持續時間縮短到1.4秒(我們希望轉換的時間),我們將使用時間拉伸效果(Time stretch effect)。
要刪除白色部分,我們將使用Keying -> extract並將白點設定為0.在下面的螢幕截圖中,藍色部分是我們合成的背景,即視訊的透明部分。
最後,我們可以將合成的視訊儲存為PNG序列,然後使用Photoshop或CSS sprite生成單個影象:
這是一個雪碧圖,具有非常連貫的外觀效果。 我們將為另一種效果建立另一個“反向”雪碧圖。 您將在演示檔案的img資料夾中找到所有不同的雪碧圖。
現在,我們已經建立了遮罩影象,讓我們簡單實現示例輪播圖的HTML結構。
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樣式
在這部分中,我們將為我們的效果新增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;
}
}
複製程式碼
現在我們有了輪播圖的結構和樣式。 讓我們給它新增一些動效吧!
JavaScript表現
我們將使用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);
};
複製程式碼
新增相應的類將觸發我們的動畫,然後遮罩影象應用於我們的輪播圖。 主要思想是在動畫功能中移動遮罩影象以建立過渡流。
就是這樣! 我希望這個教程對你有用,並且在建立你自己的酷遮罩效果時感受到樂趣! 不要猶豫,分享你的作品,我很樂意看到他們!