How to create a simple parallax website with rails

Trước khi bắt tay vào việc xây dựng trang web chúng ta hãy tìm hiểu 1 chút qua về parallax. Parallax hay tên đầy đủ là "Parallax Scrolling", đây là 1 kỹ thuật được ra đời vào năm 2011 và được áp dụng đầu tiên trên trang web Nike Better World 2011. Đây là kỹ thuật dùng để tạo hiệu ứng 3d cho trang web thông qua việc các element được thay đổi vị trí cùng với thao tác cuộn chuột tạo sự thú vị cho người dùng.

boy coy đây là một trong những trang web đứng top đầu trong sử dụng parallax với các hiệu ứng kết hợp rất cool.

OK, để bắt đầu làm quen với kỹ thuật này bài viết sẽ giúp bạn xây dựng 1 parallax website đơn giản sau web demo.

1. Tạo trang web

Đầu tiên hãy bạn hãy dùng rails để tạo 1 web đơn giản với 1 view trang home để ap dụng parallax.

rails new demo-parallax
cd demo-parallax

tạo con trolller static-page cho trang home

#app/controller/static_pages_controller
class StaticPagesController < ApplicationController
  def home
  end
end

thêm đường dẫn trang home

#config/routes
Rails.application.routes.draw do
  root "static_pages#home"
end

tạo file view cho rang web

#app/view/static_pages/hone.html.erb
# code html sẽ được viết ở đây

2. Import thư viện parallax jquery

Tải file sau về Giải nén mở thư mục simple-parallax../css, copy 2 file css "main.css" (stylesheet chính) và "normalize.css"(dùng để reset css) vào thư mục app/asset/stylesheet Tiếp theo bạn vào thư mục simple-parallax..,và copy folder "js" chứa các file "imagesloaded.js", "_main.js", "skrollr.js" vào thư mục app/asset/javascript

Mở file app/assets/javasript/application.js thêm vào dòng sau để import file js

//= require jquery
//= require js/vendor/modernizr-2.7.1.min
//= require js/skrollr
//= require js/imagesloaded
//= require js/_main
//= require_tree .

Cập nhật ảnh vào thư mục public/images của app "demo-parallax". Ở đây tôi sẽ dùng 4 ảnh nền giống trên demo làm ví dụ

3. Cập nhật file html

nội dung file này được lọc từ file index trong bộ tài liệu bạn down trên về

<body class="loading">
    <!--[if lt IE 7]>
        <p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
    <![endif]-->

  <div id="preload">
    <img src="bcg_slide-1.jpg">
    <img src="bcg_slide-2.jpg">
    <img src="bcg_slide-3.jpg">
    <img src="bcg_slide-4.jpg">
  </div>

  <main>

    <section id="slide-1" class="homeSlide">
      <div class="bcg"
           data-center="background-position: 50% 0px;"
           data-top-bottom="background-position: 50% -100px;"
           data-anchor-target="#slide-1"
      >
        <div class="hsContainer">
          <div class="hsContent"
               data-center="bottom: 200px; opacity: 1"
               data-top="bottom: 1200px; opacity: 0"
               data-anchor-target="#slide-1 h2">
            <h2>Simple parallax scrolling is...</h2>
          </div>
        </div>
      </div>
    </section>

    <section id="slide-2" class="homeSlide">
      <div class="bcg"
           data-center="background-position: 50% 10px;"
           data-top-bottom="background-position: 50% -100px;"
           data-bottom-top="background-position: 50% 100px;"
           data-anchor-target="#slide-2"
      >
        <div class="hsContainer">
          <div class="hsContent"
               data-center="opacity: 1"
               data-center-top="opacity: 0"
               data--100-bottom="opacity: 0;"
               data-anchor-target="#slide-2"
          >
            <h2>great for story telling websites.</h2>
          </div>
        </div>
      </div>
    </section>

    <section id="slide-3" class="homeSlide">
      <div class="bcg"
           data-center="background-position: 50% 0px;"
           data-top-bottom="background-position: 50% -100px;"
           data-bottom-top="background-position: 50% 100px;"
           data-anchor-target="#slide-3"
      >
        <div class="hsContainer">
          <div class="hsContent"
               data--50-bottom="opacity: 0;"
               data--200-bottom="opacity: 1;"
               data-center="opacity: 1"
               data-200-top="opacity: 0"
               data-anchor-target="#slide-3 h2"
        >
            <h2>Now go and create your own story</h2>
          </div>
        </div>

      </div>
    </section>

    <section id="slide-4" class="homeSlide">
      <div class="bcg"
           data-center="background-position: 50% 0px;"
           data-top-bottom="background-position: 50% -100px;"
           data-bottom-top="background-position: 50% 100px;"
           data-anchor-target="#slide-4"
      >
        <div class="hsContainer">
          <div class="hsContent"
               data-bottom-top="opacity: 0"
               data-25p-top="opacity: 0"
               data-top="opacity: 1"
               data-anchor-target="#slide-4"
          >
            <h2>and share mine.</h2>
          </div>
        </div>
      </div>
    </section>

  </main>
</body>

Ta có thể dễ thấy phần body của file html này đc chia làm 4 phần tương ứng với 4 ảnh. Chú ý ở đây css có nhiệm vụ load ảnh background nên nếu bạn muốn sửa lại tên file ảnh hay đường dẫn ... thì bạn sửa trong file main.css ví dụ:

/* main.css */
/* Slide 1 */
#slide-1 .bcg {background-image:url('bcg_slide-1.jpg')}
#slide-1 .hsContent {
	bottom: 200px;
	top: auto;
}

Okie giờ bạn hãy bật server lên và truy cập vào trang web local host bạn vừa tạo để xem kết quả

rails server

Giờ tôi sẽ giải thích các option ta đã dùng để xây dựng nên web này trước hết ta sẽ em file html. Dầu tiên là phần code session cho ảnh 1

<section id="slide-1" class="homeSlide">
  <div class="bcg"
       data-center="background-position: 50% 0px;"
       data-top-bottom="background-position: 50% -100px;"
       data-anchor-target="#slide-1"
  >
    <div class="hsContainer">
      <div class="hsContent"
           data-center="bottom: 200px; opacity: 1"
           data-top="bottom: 1200px; opacity: 0"
           data-anchor-target="#slide-1 h2">
        <h2>Simple parallax scrolling is...</h2>
      </div>
    </div>
  </div>
</section>

Bạn hãy để ý đến các data attribute, các thông số này sẽ nói lên chuyển động của phần nội dung bên trong thực hiện khi cuộn chuột trang web. Ở đây dòng code:

data-center="background-position: 50% 0px;"
data-top-bottom="background-position: 50% -100px;"
data-anchor-target="#slide-1"

sẽ thay đổi ảnh nền backgroud từ vị trí (50% 0) tới (50% -100px) tức là ảnh nền này sẽ bị di chuyển lên 100px tính từ lúc ảnh hiện ra tới khi điểm cuối của ảnh chạm tới phần đỉnh của trình duyệt

  • giải thích một chút ở đây vị trí (x,y) là tọa độ của ảnh đó,đơn vị có thểlà % hoặc px, với 50% ~ 0px tức là ảnh ở giữa mành hình view, nếu muốn ảnh di chuyển trái phải or lên xuống thì ta thay đổi các giá trị tọa độ đó cùng với attribute data tương ứng(data-bottom-top -> data-center -> data-top-bottom, đây là thứ tự khi ảnh đc load từ dưới lên trên, để hiểu rõ hơn các bạn có thể xem ảnh dưới)

skrollr-cheatsheet-v02.png

Tương tự phần data attributes tiếp theo sẽ nói lên hành động của đoạn text "Simple parallax scrolling is..."

<div class="hsContent"
     data-center="bottom: 200px; opacity: 1"
     data-top="bottom: 1200px; opacity: 0"
     data-anchor-target="#slide-1 h2">
  <h2>Simple parallax scrolling is...</h2>
</div>

ở đây đoạn text sẽ xuất hiện cách phần cuối của ảnh slide-1 200px và di chuyển theo backgroud cho đến khi nó đến giữa màn hình view (data-center) , và sẽ di chuyển (so với ảnh nền) lên đồng thời dần biến mất cho đến khi phần cuối của thẻ text đó cách đỉnh 1200p => tốc độ di chuyển của đoạn text này được quyết định bởi tham số 1200px. càng lớn thì ảnh di chuyển càng nhanh và ngược lại,.

câu hỏi vui: theo bạn phải cài đặt là gí trị bao nhiêu để thấy text sẽ đi cùng ảnh nền như không có hiệu ứng gì cả (đáp án ở cuối bài)

Tiếp đến sesion2

<section id="slide-2" class="homeSlide">
  <div class="bcg"
       data-center="background-position: 50% 10px;"
       data-top-bottom="background-position: 50% -100px;"
       data-bottom-top="background-position: 50% 100px;"
       data-anchor-target="#slide-2"
  >
    <div class="hsContainer">
      <div class="hsContent"
           data-center="opacity: 1"
           data-center-top="opacity: 0"
           data--100-bottom="opacity: 0;"
           data-anchor-target="#slide-2"
      >
        <h2>great for story telling websites.</h2>
      </div>
    </div>
  </div>
</section>

Ở đây ảnh sẽ xuất hiện cao hơn bình thường 100px do attribute:

data-bottom-top="background-position: 50% 100px;"

sau đó di chuyển lên đến khi ảnh ở giữa màn hình view

data-center="background-position: 50% 10px;"

rồi tiếp tục di chuyển cho đến khi ảnh phần ảnh vượt phần top view 100px

data-top-bottom="background-position: 50% -100px;"

Đối với đoạn text H2 lúc đầu nó sẽ bị ẩn đi bởi đoạn code:

data-center-top="opacity: 0"

sau đó khi cuộn chuột lên thì đoạn text sẽ dần xuất hiên và hiện khi ảnh slide-2 ra giữa màn hình view, thông qua đoạn code:

data-center="opacity: 1"

Và khi đoạn text này sẽ dần biến mất cho đến khi điểm cuối của ảnh cách phần dưới view 100px

data--100-bottom="opacity: 0;"

Ngoài ra, nếu bạn muốn tắt chức năng này trong trường hợp người dùng sử dụng thiết bị di động có bề ngang hẹp vì hiệu ứng này có thường hay gây người dùng khó sử dụng trên các thiết bị màn hình nhỏ. Bạn hãy mở file "_main.js" và kiểm tra đoạn code sau trong function adjustWindow()

function adjustWindow(){

  // lấy size view
winH = $window.height();
winW = $window.width();

// đảm bào chiều rộng bé nhất có thể điều chỉnh là 550
  if(winH <= 550) {
    winH = 550;
  }

// sử dụng Skrollr với chiều rộng view > 768
  if( winW >= 768) {

    // khởi tạo Skrollr
    var s = skrollr.init({
      forceHeight: false
    });

    // refresh  lại slides
    $slide.height(winH);

    s.refresh($('.homeSlide'));

  } else {

    // Khởi tạo Skrollr
    var s = skrollr.init();
    s.destroy();
  }

}

Như vậy là với các thiết bị có view chiều rộng < 768 thì skrollr sẽ không chạy link githup ví dụ: https://github.com/leanh173/demo-parallax

Thao khảo thêm:

PS: Đáp án là 200px, vì lúc đầu khởi tạo vị trí đoạn text xuất hiện là cách lề dưới của ảnh nên 200px => để chữ so với ảnh ko di chuyển tương đương với việc sau khi ảnh đc cuộn lên hết thì dòng text cũng phải cách phần lề trên của cửa sổ view(trùng với lề dưới của ảnh 1) 1 khoảng giống ban đầu => 200px