【譯】CSS遮罩實現過渡效果

赤木晴子發表於2019-01-08

【譯】CSS遮罩實現過渡效果

線上預覽 下載原始碼

今天我們想向您展示如何使用CSS Masks建立一個有趣的過渡效果。 與剪下類似,遮罩是定義可見性和與元素複合的另一種方式。 在下面的教程中,我們將向您展示如何在簡單輪播圖中為過渡效果應用新屬性。 我們將使用steps()計時功能動畫,並在影象上移動遮罩PNG以實現有趣的過渡效果。

注意:請記住,這種效果還處於實驗階段,只有現代瀏覽器支援(Chrome,Safari和Opera)。

CSS Masks

使用所選影象來遮蓋元素的一部分的方法

W3C候選人推薦

支援以下版本:

桌面應用

【譯】CSS遮罩實現過渡效果

移動端應用

【譯】CSS遮罩實現過渡效果

可以在caniuse.com上檢視詳細的支援情況

請記住,Firefox只有部分支援(它只支援內聯SVG遮罩元素)所以我們會有一個回退版本。 希望CSS Masks能儘快得到所有現代瀏覽器的支援。 請注意,我們正在新增Modernizr以檢查是否支援。

讓我們一起愉快的開始吧!

建立遮罩圖片

在本教程中,我們將介紹第一個示例(演示1)。

為了使遮罩過渡效果起作用,我們需要一個影象,用於隱藏/顯示基礎影象的某些部分。 該遮罩影象將是一個PNG,上面有透明部分。 這個PNG將是一個雪碧圖,它看起來如下:

【譯】CSS遮罩實現過渡效果

黑色部分將顯示當前影象,但白色部分(實際上是透明的)將是我們影象的遮罩部分,將顯示第二個影象。

為了建立雪碧圖,我們將使用此視訊。 我們將其匯入Adobe After Effects以減少視訊的時間,刪除白色部分並將其匯出為PNG序列。

要將持續時間縮短到1.4秒(我們希望轉換的時間),我們將使用時間拉伸效果(Time stretch effect)。

【譯】CSS遮罩實現過渡效果

要刪除白色部分,我們將使用Keying -> extract並將白點設定為0.在下面的螢幕截圖中,藍色部分是我們合成的背景,即視訊的透明部分。

【譯】CSS遮罩實現過渡效果

最後,我們可以將合成的視訊儲存為PNG序列,然後使用Photoshop或CSS sprite生成單個影象:

【譯】CSS遮罩實現過渡效果

這是一個雪碧圖,具有非常連貫的外觀效果。 我們將為另一種效果建立另一個“反向”雪碧圖。 您將在演示檔案的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;
  }
}
複製程式碼

現在我們有了輪播圖的結構和樣式。 讓我們給它新增一些動效吧!

【譯】CSS遮罩實現過渡效果

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);
};
複製程式碼

新增相應的類將觸發我們的動畫,然後遮罩影象應用於我們的輪播圖。 主要思想是在動畫功能中移動遮罩影象以建立過渡流。

就是這樣! 我希望這個教程對你有用,並且在建立你自己的酷遮罩效果時感受到樂趣! 不要猶豫,分享你的作品,我很樂意看到他們!

相關文章