CSS3のふわりとしたアニメーションが気持ちいい画像ギャラリーを実装するチュートリアル

CSS3アニメーションとjQueryを使って、アニメーションの動きが気持ちいい水平型のギャラリー・ポートフォリオを実装するチュートリアルを紹介します。

デモのアニメーション

Horizontal Portfolio Layout with CSS3 Animations and jQuery

デモ

デモはChrome, Safari, Firefox, Operaなどのモダンブラウザ、IEは9+でご覧ください。

サイトのキャプチャ

デモページ

水平型の画像ギャラリーで、CSS3アニメーションはページのロード時、サムネイルのホバー時、水平スクロール時など随所に盛り込まれています。

サイトのキャプチャ

デモページ:サムネイルのホバー時

サムネイルのホバー時だけでもキャプションの表示だけでなく、画像などのサイズ変更、テキストの表示、各アイテムの可視化、配置変更などもアニメーションで行われています。

実装

実装はポイントをまとめて紹介します、Stepは3つです。
元記事では詳細に書かれているので、参考にしてください。

Step 1: HTML

画像、2つのパラグラフ、タグが一つのセットになっており、それぞれをリスト要素で実装します。

<ul class="portfolio-items">
  <li class="item">
    <figure>
      <div class="view">
       <img src="images/1.jpg">
      </div>
      <figcaption>
        <p><span><a href="http://www.vladstudio.com/wallpaper/?thetwoandthebubbles">The Two and The Bubbles</a></span></p>
        <p><span>By Vlad Gerasimov</span></p>
      </figcaption>
    </figure>
    <div class="date">2005</div>
  </li>
  <li>
    <!-- second item -->
  </li>
  <li>
    <!-- third item -->
  </li>
  <!-- and so forth -->
</ul>

Step 2: CSS

まずは、画像ギャラリーの基本的なスタイルです。
最初の状態では、キャプションのテキストは不透明度を設定して見えない状態にします。

.portfolio-items {
  height: 400px;
  overflow-x: scroll;
  overflow-y: hidden;
  white-space: nowrap;
  margin-bottom: 30px;
  position: relative;
}
.portfolio-items > li {
  display: inline-block;
  /*aligning items by top baseline makes sure the baseline doesn't change once the hover
  effect is fired and therefore the other items stay put*/
  vertical-align: top;
}
.item {
  width: 300px;
  height: 202px;
  margin: 150px 20px 0;
  padding: 5px;
  border-radius:2px;
  box-shadow: 0px 10px 10px -5px rgba(0,0,0,0.5);
  background-color: white;
  font-size: 14px;
  /*initially all items are moved 300px up and faded out and rotated, they will fade 
  into view and back to position later via javascript*/
  opacity: 0;
  position: relative;
  top: -300px;
  transform: rotate(-135deg);
  transition: all .3s ease, opacity 2s ease,  top 1s ease;
}
/*even items will be 100px lower than their siblings*/
.item:nth-child(even) {
  margin-top: 100px;
}

figure{
  width:100%;
  height:100%;
}
.view {
  overflow: hidden;
  width: 100%;
  height: 190px;
  position: relative;
}
.view img {
  width: 300px;
  height: 190px;
  transition: width .3s ease;
  position: absolute;
}
 
figcaption {
  height: 60px;
  width: 100%;
  padding: 0;
  position: absolute;
  bottom: 0;
  overflow: hidden;
  opacity: 0;
}
figcaption p {
  font: bold 12px/18px "Arial", sans-serif;
  text-transform: uppercase;
  padding: 0 10px;
  margin:  5px 0;
  width:100%;
  background-color: #f0f0f0;
  color:#333;
}
/*the text of the paragraph tags in the footer(figcaption) is initially hidden to the left*/
figcaption span {
  left: -100%;
  opacity: 0;
}
figcaption a{
   color: #CC320F; 
}
 
.date {
  z-index: 1;
  width: 50px;
  height: 30px;
  line-height: 30px;
  color: #fff;
  font-weight: bold;
  text-align: center;
  border-radius: 1px;
  background-color: #CC320F;
  position: absolute;
  bottom: 30px;
  left: 15px;
  transition: transform 0.5s cubic-bezier(0.12, 1.6, 0.91, 0.92);
}

画像ホバー時のスタイルです。
まずは、画像やキャプションをアニメーションで変形させます。

.item:hover {
  height: 270px;
  padding: 15px;
  transform: translateY(-68px);
}
.item:hover .date {
  transform: translate3d(0, 61px, 0);
}
.item:hover figcaption {
  animation: show .25s ease-in .120s forwards;
}
.item:hover p:nth-of-type(1) span{
  animation: slideOut .25s ease-out .15s forwards;
}
.item:hover p:nth-of-type(2) span{
  animation: slideOut .2s  ease-out .3s forwards;
}
.item:hover .view {
  height: 170px;
}
.item:hover .view img {
  top: -20px;
  left: -20px;
}

ホバー時には、画像のデータを表示するよう不透明度を変更します。

/*animation to show the metadata*/
@keyframes slideOut {
  0% {
    left: -100%;
    opacity: 0;
  }
  95% {
    left: 0;
    opacity: 0.2;
  }
  100% {
    opacity: 1;
    left: 0;
  }
}
/*animation to show the footer, which will simply up its opacity to 1*/
@keyframes show {
  to {
    opacity: 1;
  }
}

ギャラリーのロード時には、最初は何も表示されていない状態で、画像がくるっと回転して表示されるようにします。

.falldown {
  top: 0;
  opacity: 1;
  /*they are also initially rotated, and are rotated back to their normal position*/
  transform: rotate(0);
}

スクロールバーもデザインに合わせて変更します。このスタイルはChromeのみがサポートしています。
全体的に重要なポイントであるなら、jQueryのプラグインでデザインを変更できます。

::-webkit-scrollbar {
  width: 7px;
  height: 7px;
  cursor: pointer;
}
::-webkit-scrollbar-track {
  background-color: #ddd;
  border-radius: 10px;
}
::-webkit-scrollbar-thumb {
  border-radius: 10px;
  background-color: #C4290D;
}

Step 3: JavaScript

スクリプトはまずは、ユーザーのビューポートをチェックすることから始めます。


//checks if element it is called on is visible (only checks horizontally)
(function($) {
var $window = $(window);

$.fn.isVisible = function(){
var $this = $(this),
Left = $this.offset().left,
visibleWidth = $window .width();

return Left < visibleWidth; } })(jQuery); [/javascript]

以下は全スクリプトです。
ビューポートをチェックした後に各アイテムを配置し、サムネイルのホバー時とスクロール時のエフェクトを設定します。また、マウスのホイール操作にも対応させます。


//checks if element it is called on is visible (only checks horizontally
(function($) {
var $window = $(window);

$.fn.isVisible = function(){
var $this = $(this),
Left = $this.offset().left,
visibleWidth = $window .width();

return Left < visibleWidth; } })(jQuery); (function($){ var list = $('.portfolio-items'), showVisibleItems = function(){ list.children('.item:not(.falldown)').each(function(el, i){ var $this = $(this); if($this.isVisible()){ $this.addClass('falldown'); } }); }; //initially show all visible items before any scroll starts showVisibleItems(); //then on scroll check for visible items and show them list.scroll(function(){ showVisibleItems(); }); //image hover pan effect list.on('mousemove','img', function(ev){ var $this = $(this), posX = ev.pageX, posY = ev.pageY, data = $this.data('cache'); //cache necessary variables if(!data){ data = {}; data.marginTop = - parseInt($this.css('top')), data.marginLeft = - parseInt($this.css('left')), data.parent = $this.parent('.view'), $this.data('cache', data); } var originX = data.parent.offset().left, originY = data.parent.offset().top; //move image $this.css({ 'left': -( posX - originX ) / data.marginLeft, 'top' : -( posY - originY ) / data.marginTop }); }); list.on('mouseleave','.item', function(e){ $(this).find('img').css({ 'left': '0', 'top' : '0' }); }); //add mouse wheel support with the jquery.mousewheel plugin list.mousewheel(function(event, delta) { this.scrollLeft -= (delta * 60); event.preventDefault(); }); })(jQuery); [/javascript]

top of page

©2017 coliss