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

在線預覽 下載源碼css

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

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

CSS Masks

使用所選圖像來遮蓋元素的一部分的方法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結構。

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

添加相應的類將觸發咱們的動畫,而後遮罩圖像應用於咱們的輪播圖。 主要思想是在動畫功能中移動遮罩圖像以建立過渡流。

就是這樣! 我但願這個教程對你有用,而且在建立你本身的酷遮罩效果時感覺到樂趣! 不要猶豫,分享你的做品,我很樂意看到他們!

相關文章
相關標籤/搜索