• Hotline Phone
    0898 370 098
  • Giờ mở cửa
    T2 - CN 8h - 23h
  • Server
    HCM - Viet Nam

[Web Design] Kỹ thuật Parallax Scrolling – Phần 2

Howdy! Chào các bạn, chúng ta hãy cùng trở lại với chủ đề Parallax Scrolling nhé! Nếu như có bạn nào chưa biết hoặc đã quên hiệu ứng này thì có thể xem Kỹ thuật Parallax Scrolling – Phần 1 mình đã đăng trước đó.

Ở phần đầu, chúng ta đã được giới thiệu khái niệm về Parallax Scrolling và làm quen với cách tạo ra hiệu ứng này bằng một demo nhỏ. Sang phần hai, chúng ta sẽ tăng nhẹ sức mạnh của kỹ thuật parallax scrolling bằng cách áp dụng nó cho nhiều element, nhiều background cùng một lúc. Now, let’s have some fun!

Các “Vũ Khí” Cơ Bản

Trước tiên là phải chuẩn bị các nguyên liệu cần thiết cho việc design. Các bạn vẫn sẽ phải tạo một thư mục chứa project có cấu trúc như hình dưới:

thu-muc-project

Vai trò của các file đều giống như phần đầu. Đừng quên include 2 file normalize.cssjquery.min.js trong 2 folder cssjs. Bên cạnh đó, chúng ta có thêm 1 folder mới khác, đó là sass. Mình khá là thích sử dụng SASS để code sau đó compile ra file CSS vì code của SASS rất linh hoạt, dễ hiểu và nó giúp mình tiết kiệm thời gian hơn là code thuần CSS.

Các bạn có thể xem qua bài viết Hướng dẫn sử dụng SASS để viết CSS chuyên nghiệp của anh Thạch để biết thêm về cách sử dụng SASS. Đừng lo lắng gì cả, một khi đã rành về CSS thì việc nắm bắt SASS chỉ tốn của bạn khoảng 10′-15′ thôi. Trong code SASS ở bài này mình sẽ chú thích đầy đủ cho mọi người có thể đối chiếu với code CSS thuần.

Mở Đầu Với HTML Và SASS

Đầu tiên là sẽ tạo một trang index.html. Ý tưởng sẽ là tạo ra 3 thẻ div đại diện cho 3 phần lớn của trang web, các div lớn này sẽ có các class chính được đặt tên lần lượt là .section-1 , .section-2 , .section-3 . Trong div lớn là các thành phần con như .greeting-content , .quotes , .sherlock , .steve

 <div class="section-1 cf">	<!-- .cf is a clearfix hack: http://nicolasgallagher.com/micro-clearfix-hack/ --> 	<div class="greeting-content"> 		<!-- your content goes here --> 	</div> </div> <div class="section-2 cf"> 	<img id="sherlock-img" src="img/sherlock.png" alt="sherlock holmes"></img> 	<div class="quotes sherlock"> 		<p>&ldquo;My name is Sherlock Holmes.  It is my business to know what other people don't know.&rdquo;</p> 		<p>&ldquo;When you have eliminated all the impossible, whatever remains, however improbable, must be the truth.&rdquo;</p> 		<p>&ldquo;The world is full of obvious things which nobody by any chance ever observes.&rdquo;</p> 		<p>&ldquo;I never guess. It is a shocking habbit, destructive to the logical faculty.&rdquo;</p> 	</div> </div> <div class="section-3 cf"> 	<img id="steve-img" src="img/steve.png" alt="steve jobs"></img> 	<div class="quotes steve"> 		<p>&ldquo;Sometimes life is going to hit you in the head with a brick. Don’t lose faith.&rdquo;</p> 		<p>&ldquo;Things don't have to change the world to be important.&rdquo;</p> 		<p>&ldquo;Deciding what not to do is as important as deciding what to do.&rdquo;</p> 		<p>&ldquo;Design is not just what it looks like and feels like. Design is how it works.&rdquo;</p> 	</div> </div>

Sau khi kết thúc phần core của index.html . Tiếp theo là bước trang trí . Mình sẽ sử dụng SASS bằng cách tạo 1 file main.scss trong thư mục sass.

 /* Set fullscreen */
 html, body {
 	height: 100%;
}
 /* Section 1 --- full screen */
 /* CSS .section-1 */
 .section-1 {
 	background: url('../img/bg.jpg') no-repeat 50% 0 fixed; 	height: 100%; 	font-family: 'Sofadi One', cursive;
	/* CSS .section-1 .greeting-content */
 	.greeting-content {
 		max-width: 960px; 		margin: 100px auto; 		text-align: center;
		/* CSS .section-1 .greeting-content h1, 			.section-1 .greeting-content h3 */
 		h1, h3 {
 			color: #2c3e50; 			font-size: 3.5em; 		}
  		/* CSS .section-1 .greeting-content p */
 		p {
 			font-size: 2em; 			background: rgba(231, 76, 60, 0.4); 			padding: 20px; 			border-radius: 30px; 			-moz-border-radius: 30px; 			-webkit-border-radius: 30px;
			/* CSS .section-1 .greeting-content p a */
 			a {
 				color: #fff; 				text-decoration: none; 			}
 		}
 	}
 }
 /* Section 2 */
 /* CSS .section-2 */
 .section-2 {
 	position: relative; 	height: 800px; 	max-width: 960px; 	background: url('../img/londoncity.jpg') no-repeat 50% 0 fixed; 	font-family: 'Elsie', cursive; 	overflow: hidden;
	/* CSS .section-2 #sherlock-img */
 	#sherlock-img {
 		position: absolute;	/* important */
 		margin: 0 auto; 		z-index: 200; 		right: 50px; 	}
  	/* CSS .section-2 .sherlock */
 	.sherlock {
 		position: absolute;	/* important */
 		background: rgba(192, 57, 43, 0.8); 		z-index: 100; 		left: 100px; 		width: 600px; 		font-size: 18px; 	}
 }
 /* Section 3 */
 /* CSS .section-3 */
 .section-3 {
 	position: relative; 	height: 900px; 	max-width: 960px; 	background: url('../img/appleinc.jpg') no-repeat 50% 0 fixed; 	font-family: 'Elsie', cursive; 	overflow: hidden;
	/* CSS .section-3 #steve-img */
 	#steve-img {
 		position: absolute;	/* important */
 		margin: 0 auto; 		z-index: 200; 		right: 0px; 	}
  	/* CSS .section-3 .steve */
 	.steve {
 		position: absolute;	/* important */
 		font-size: 1em; 		background: rgba(44, 62, 80, 0.8); 		z-index: 100; 		left: 50px; 		width: 600px; 		font-size: 20px; 	}
 }

Tính Toán Parallax Scrolling Cho Hình Nền

Vậy là bước chuẩn bị đã hoàn tất. Để có thể dễ dàng nhận diện parallax scrolling nó như thế nào thì trước khi thực hiện hiệu ứng, các bạn hãy thử cuộn trình duyệt lên xuống và cảm nhận.

pic2.png

Giống như phần đầu tiên, chúng ta tạo thêm 1 file parallax.js và include nó vào index.html . Ta vẫn sẽ sử dụng hàm .bind('scroll', function()) trong jquery để nhận thao tác cuộn chuột từ người dùng và thực hiện parallax function, nhưng lần này chúng ta không áp dụng cho thuộc tính top mà sẽ áp dụng cho thuộc tính background-position , bởi vì trong code SASS chúng ta đã cài đặt hình nền bằng background: url('...') no-repeat 50% 0px fixed , trong đó background-position: 50% 0px .

Để background có thể di chuyển theo thao tác scroll chuột của người dùng, chúng ta sẽ liên tục cập nhật giá trị thứ hai (yPos) trong background-position .

Như SASS chúng ta đã định nghĩa, background-position của cả 3 div.section50% 0px . Tức là khi cửa sổ browser của người dùng scroll đến vị trí của div nào , div đó phải có giá trị yPos = 0px.

Ví dụ: khi .section-1 nằm trong viewport thì sẽ có style=”background-position: 50% 0px;”

pic4.png

Và khi scroll đến .section-2 , lúc này .section-2 sẽ có style=”background-position: 50% 0px;”

pic5.png

Như vậy đối với background-position thì chúng ta sẽ có công thức tính parallax như sau:

background-yPos = ( div.offset.top - scrollPos ) * speed

pic3.png

Trong đó:

  • div.offset.top sẽ là giá trị top của thẻ div đó trong trang web, xem thêm về .offset() trong jquery.
  • scrollPos vẫn là vị trí scrollbar, thay đổi liên tục khi người dùng scroll chuột.
  • speed là tốc độ thay đổi của yPos.

Nhìn lên sơ đồ trên ( mình dùng paint ? ), ta thử tính toán:

  1. Khi chưa scroll chuột, .section-1 nằm trong browser viewport, scrollPos = 0px, div-1.offset.top = 0px => .section-1background-yPos-1 = 0px. Trong quá trình scroll chuột xuống, background-yPos-1 sẽ giảm dần, vậy background sẽ đi lên.
  2. Khi scrollPos = 300px , lúc này đã kết thúc .section-1, .section-2 nằm trong viewport, do div-2.offset.top = 300px => background-yPos-2 = 0px.
  3. Khi scrollPos = 800px, .section-3 nằm trong viewport, do div-3.offset.top = 800px => background-yPos-3 = 0px.

Parallax Action

Phần nhức đầu nhất đã qua, bây giờ sẽ là áp dụng công thức vào code jquery, mở file parallax.js, ta sử dụng đoạn code sau:

 $(document).ready(function() {
 	$(window).bind('scroll', function() {
 		parallax(); 	}
);
}
);
function parallax() {
 	var scrollPos = $(window).scrollTop(); 	// Section 1 	$('.section-1').css('backgroundPosition', "50% " + Math.round(($('.section-1').offset().top - scrollPos) * 0.5) + "px"); 	// Section 2 	$('.section-2').css('backgroundPosition', "50% " + Math.round(($('.section-2').offset().top - scrollPos) * 0.3) + "px"); 	// Section 3 	$('.section-3').css('backgroundPosition', "50% " + Math.round(($('.section-3').offset().top - scrollPos) * 0.4) + "px");
}

Kế đó là áp dụng parallax scrolling cho phần img và các .quotes , cái này thì giống như phần 1, thay đổi giá trị top của chúng là xong. Lưu ý là do các div.sectionposition: relative và hình ảnh, câu quote có position: absolute nên tọa độ của chúng sẽ dựa vào các div.section chứ không dựa vào toàn bộ website. Đến đây ta có thể hoàn chỉnh file parallax.js bằng đoạn code sau:

 $(document).ready(function() {
 	$(window).bind('scroll', function() {
 		parallax(); 	}
);
}
);
function parallax() {
 	var scrollPos = $(window).scrollTop(); 	// Section 1 	$('.section-1').css('backgroundPosition', "50% " + Math.round(($('.section-1').offset().top - scrollPos) * 0.5) + "px"); 	// Section 2 	$('.section-2').css('backgroundPosition', "50% " + Math.round(($('.section-2').offset().top - scrollPos) * 0.3) + "px"); 	$('.sherlock').css('top',(300 - (scrollPos * 0.2)) + 'px') 	$('#sherlock-img').css('top',(800 - (scrollPos * 1)) + 'px') 	// Section 3 	$('.section-3').css('backgroundPosition', "50% " + Math.round(($('.section-3').offset().top - scrollPos) * 0.4) + "px"); 	$('.steve').css('top',(1000 - (scrollPos * 0.5)) + 'px') 	$('#steve-img').css('top',(1700 - (scrollPos * 1)) + 'px') }

Trong source file mình sử dụng jquery function để cho code ngắn gọn, không dài dòng khó nhìn như thế này, các bạn có thể tham khảo sau ?

Vậy là đã xong toàn bộ rồi. Bây giờ các bạn có thể load lại trang (mình hay dùng ctrl+F5 để chống cache) và xem thành quả ? Really cool, huh?

Lời Kết

Như vậy là mình sẽ kết thúc chủ đề về Parallax Scrolling ở phần hai này.  Khi đã nắm bắt được hết về parallax scrolling, hãy thử áp dụng nó vào thực tế. Parallax Scrolling có thể giúp bạn làm 1 trang web kể chuyện hoành tráng giống như Life of Pi Movie hay Every Last Drop. Hi vọng là mình có thể khiến các bạn thích thú với hiệu ứng này hoặc là tạo thêm cảm hứng sáng tạo cho các bạn trong việc thiết kế một trang web đẹp mắt, sinh động. Good luck and have fun!

Source Code

Leave your comment