Шаблон 3D-портфолио на CSS и jQuery

Шаблон портфолио с фильтром, который запускает вращение 3D-разделов.



ДЕМО
ИСХОДНИКИ


CSS 3D Transforms можно использовать множеством творческих способов, особенно в сочетании с CSS Transitions! Сегодняшний самородок - хороший пример того, как использовать CSS для создания параллелепипеда, гранями которого являются разные проекты. Фильтр в верхней части страницы запускает трехмерное вращение, открывающее новые проекты.

Изображения: Unsplash


Создание структуры

Структура HTML состоит из двух основных элементов: nav.cd-3d-portfolio-navigation для навигации по основным проектам и div.projects, обертывающих проекты портфолио. Внутри div.projects три неупорядоченных списка (ul.row) используются для создания трех вращающихся параллелепипедов.


<div class="cd-3d-portfolio">
   <nav class="cd-3d-portfolio-navigation">
      <div class="cd-wrapper">
         <h1>3D Portfolio Template</h1>
         <ul>
            <li><a href="#0" class="selected">Filter 1</a></li>
            <li><a href="#0">Filter 2</a></li>
            <li><a href="#0">Filter 3</a></li>
         </ul>
      </div>
   </nav> <!-- .cd-3d-portfolio-navigation -->
 
   <div class="projects">
      <ul class="row">
         <li class="front-face selected project-1">
            <div class="project-wrapper">
               <div class="project-image">
                  <div class="project-title">
                     <h2>Project 1</h2>
                  </div>
               </div> <!-- .project-image -->

               <div class="project-content">
                  <!-- project content here -->
               </div> <!-- .project-content -->

               <a href="#0" class="close-project">Close</a>
            </div> <!-- .project-wrapper -->
         </li>

         <li class="right-face project-2">
            <div class="project-wrapper">
               <div class="project-image">
                  <div class="project-title">
                     <h2>Project 2</h2>
                  </div>
               </div> <!-- .project-image -->

               <div class="project-content">
                  <!-- project content here -->
               </div> <!-- .project-content -->

               <a href="#0" class="close-project">Close</a>
            </div> <!-- .project-wrapper -->
         </li>

         <li class="right-face project-3">
            <div class="project-wrapper">
               <div class="project-image">
                  <div class="project-title">
                     <h2>Project 3</h2>
                  </div>
               </div> <!-- .project-image -->

               <div class="project-content">
                  <!-- project content here -->
               </div> <!-- .project-content -->

               <a href="#0" class="close-project">Close</a>
            </div> <!-- .project-wrapper -->
         </li>
      </ul> <!-- .row -->
 
      <ul class="row">
         <!-- projects here -->
      </ul> <!-- .row -->
 
      <ul class="row">
         <!-- projects here -->
      </ul> <!-- .row -->
   </div><!-- .projects -->
</div>


Добавление стиля

Каждая ul.row имеет высоту, равную одной четвертой высоты области просмотра, и перемещается по оси Z на половину ширины области просмотра. Таким образом, мы перемещаем центр вращения элемента от пользователя на величину, равную половине ширины элемента.

Элементы его списка (проекты портфолио) затем используются для создания различных граней параллелепипеда и переводятся / поворачиваются в соответствии с гранью, на которой они находятся. Например, переднюю грань нужно просто переместить назад по оси Z, а правую грань нужно повернуть вдоль оси Y и переместить назад.

Вот простая анимация, объясняющая эту концепцию (созданная с помощью Adobe After Effects):

3D-шаблон портфолио


.cd-3d-portfolio .projects .row {
  height: 25vh;
  position: relative;
  z-index: 1;
  /* position its children in a 3d space */
  transform-style: preserve-3d;
  transform: translateZ(-50vw);
  transition: transform 0.6s cubic-bezier(0.5, 0, 0.1, 1);
}

.cd-3d-portfolio .projects .row > li {
  /* this is the single project */
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.cd-3d-portfolio .projects .row > li.front-face {
  transform: translateZ(50vw);
}
.cd-3d-portfolio .projects .row > li.right-face {
  transform: rotateY(90deg) translateZ(50vw);
}
.cd-3d-portfolio .projects .row > li.left-face {
  transform: rotateY(-90deg) translateZ(50vw);
}
.cd-3d-portfolio .projects .row > li.back-face {
  transform: rotateY(180deg) translateZ(50vw);
}

Когда пользователь выбирает один из фильтров в верхней панели навигации, каждая ul.row поворачивается, чтобы показать выбранное лицо (подробнее в разделе «Обработка событий»).

Что касается отдельных проектов, изображение предварительного просмотра проекта устанавливается как фоновое изображение элемента .project-image::before; он имеет абсолютное положение и высоту 240% от высоты проекта (что означает 60% высоты окна просмотра); таким образом, видна только часть изображения предварительного просмотра из-за свойства переполнения его предка .row> li.

Содержимое проекта заключено в элемент .project-content, который размещается прямо под изображением предварительного просмотра проекта. Когда проект открыт, свойство переполнения элемента .row> li изменяется, чтобы раскрыть его содержимое.


.cd-3d-portfolio .projects .project-image {
  position: relative;
  width: 100%;
  height: 25%;
  transition: transform 0.6s;
}
.cd-3d-portfolio .projects .project-image::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1;
  height: 240%;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

.cd-3d-portfolio .projects .project-content {
  position: absolute;
  /* place the content right below the project image */
  top: 60%;
  width: 100%;
  background: white;
}

Чтобы трехмерное вращение работало, для свойства transform-style элементов .row установлено значение preserve-3d, так что его дочерние элементы помещаются в трехмерное пространство. Если браузер не поддерживает это свойство, мы заменяем 3D-эффект на эффект постепенного появления / исчезновения (мы используем Modernizrдля проверки поддержки браузером).


.no-preserve3d .cd-3d-portfolio .projects .row {
  /* fallback for browsers that don't support the preser3d property */
  transform: translateZ(0);
}
.no-preserve3d .cd-3d-portfolio .projects .row > li {
  opacity: 0;
  transform: translateX(0);
}
.no-preserve3d .cd-3d-portfolio .projects .row > li.front-face, 
.no-preserve3d .cd-3d-portfolio .projects .row > li.right-face, 
.no-preserve3d .cd-3d-portfolio .projects .row > li.left-face, 
.no-preserve3d .cd-3d-portfolio .projects .row > li.back-face {
  transform: translateX(0);
}
.no-preserve3d .cd-3d-portfolio .projects .row > li.selected {
  opacity: 1;
}


Обработка событий

Чтобы реализовать это трехмерное портфолио, мы создали объект Portfolio3D и использовали функцию bindEvents для присоединения обработчиков событий к нужным элементам.


function Portfolio3D( element ) {
   //define a Portfolio3D object
   this.element = element;
   this.navigation = this.element.children('.cd-3d-portfolio-navigation');
   this.rowsWrapper = this.element.children('.projects');
   this.rows = this.rowsWrapper.children(\.row');
   this.visibleFace = 'front';
   this.visibleRowIndex = 0;
   this.rotationValue = 0;
   //animating variables
   this.animating = false;
   this.scrolling = false;
   // bind portfolio events
   this.bindEvents();
}

if( $('.cd-3d-portfolio').length > 0 ) {
   var portfolios3D = [];
   $('.cd-3d-portfolio').each(function(){
      //create a Portfolio3D object for each .cd-3d-portfolio
      portfolios3D.push(new Portfolio3D($(this)));
   });
}

Свойство visibleFace используется для хранения видимой в данный момент грани параллелепипеда (если ul.row не был повернут, видимая грань является передней гранью, а если она была повернута на 90 градусов, видимая грань является левой и скоро).

Когда пользователь выбирает фильтр в верхней части навигации, метод showNewContent () используется для перемещения выбранных граней в нужное положение и для поворота элементов ul.row.


Portfolio3D.prototype.bindEvents = function() {
   var self = this;

   this.navigation.on('click', 'a:not(.selected)', function(event){
      //update visible projects when clicking on the filter
      event.preventDefault();
      if( !self.animating ) {
         self.animating = true;
         var index = $(this).parent('li').index();
      
         //show new projects
         self.showNewContent(index);

         //update filter selected element
         //..
      }
   });

   //...
};

В зависимости от того, предшествует ли выбранный фильтр уже выбранному или следует за ним, ul.row поворачивается по часовой стрелке (rightToLeft) или против часовой стрелки (leftToRight).

Метод getRotationPrameters использует это значение направления плюс значение свойства visibleFace для определения нового значения поворота ul.row; кроме того, он определяет, какое лицо будет видно, чтобы присвоить ему соответствующие классы. Например, если видимая в данный момент грань является передней гранью и нам нужно повернуть параллелепипед rightToLeft, тогда новая видимая грань будет правильной.


Portfolio3D.prototype.showNewContent = function(index) {
   var self = this,
       direction = ( index > self.visibleRowIndex ) ? 'rightToLeft' : 'leftToRight',
       rotationParams = this.getRotationPrameters( direction ),
       newVisibleFace = rotationParams[0],
       rotationY = rotationParams[1],
       translateZ = $(window).width()/2;
  
   //rotate the parallelepiped
   this.setTransform(rotationY, translateZ);
  
   //update .row > li classes
   //...

   //update Portfolio3D properties
   //..
};

Вот и всё!


🔖 Выбор по тегам ×

Top