Главная » Полезные статьи » HTML-верстка » Урок по CSS маскам – создаем вращающуюся галерею
Распечатать статью

Урок по CSS маскам – создаем вращающуюся галерею

Я попробовал много вещей, которые вы можете сделать с CSS свойством «mask». С помощью этого свойства вы сможете наложить маску или обрезать любой элемент. В роли маски может выступать как PNG, так и SVG.

Я связывал маски со свойствами transform и transition и добился крутого эффекта для галереи изображений. Я сделал демо для Chrome и ночных сборок Webkit. Firefox тоже поддерживает свойство mask, но не очень хорошо отображает вращающиеся изображения с масками, поэтому я использовал только префикс -webkit для этого демо.

Мы разберем процесс создания галереи поэтапно, начиная с разметки.

HTML

<div id="gallery">
        <div id="gallery-wheel"<img class="active" src="pic1.png" alt="" />
        <img src="pic2.png" alt="" />
        <img src="pic3.png" alt="" />
        <img src="pic4.png" alt="" /> <img src="pic5.png" alt="" />
        <img src="pic6.png" alt="" /></div>
    </div>

Структура весьма простая. Мы имеем обертку внутри которой находится вращающееся колесо и центральный кусок. Картинки я взял с Dribbble.

Маска

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">
  <path d="M150,300 L25,83 A250,250 0 0,1 275,83 z"/>
</svg>

Код мы засунем в отдельный .svg файл и подключим в CSS.

Так как у нас будет шесть изображений, маска имеет форму одной шестой круга. Мы нарисовали её используя тег path. Форма определяется атрибутом d с набором параметров. Я не буду рассказывать что делает каждый из параметров, но просто знайте, что с помощью них мы нарисовали 60-ти градусный кусок круга, с радиусом 250 пикселей. В этой статье вы можете почитать побольше про рисование с помощью SVG.

Почему мы выбрали именно SVG?

Вы наверное подумали, что гораздо проще было нарисовать изображение в фотошопе, сохранить его в PNG и назначить маской? Частично вы правы, но что если вы захотите увеличить количество изображений в галерее? Тогда нам придется опять возвращаться в редактор и рисовать фигуру заново. Поменять число в параметре SVG куда быстрее, не так ли?

И что если вы захотите сделать галерею полностью динамичной? Могут быть случаи когда вы не можете знать заранее сколько изображений будет отображено на экране. Наша SVG маска может быть легко сгенерированна с помощью JavaScript кода и положена в DOM, который (код) будет учитывать количество изображений.

Тем не менее, единственным браузером который на данный момент позволяет назначить маской встроенный SVG является Firefox, который, как я сказал ранее, не может вращать изображения с масками правильно.

CSS

#gallery {
   margin: 0 auto;
   position: relative;
   background: white;
   width: 520px;
   height: 520px;
   border-radius: 50%;
   border: 5px solid white;
}

#gallery-wheel {
   position: relative;
   width: 100%;
   height: 100%;
}

#gallery-wheel img {
   position: absolute;
   -webkit-mask-box-image: url("../mask.svg") round;
   -webkit-transform-origin: 50% 100%;
   padding: 5px;
   top: 0;
   margin-top: -50px;
   left: 50%;
   margin-left: -155px;
   cursor: pointer;
}
#gallery-wheel img:hover { opacity: 0.5; }

#gallery-wheel img:nth-child(2) { -webkit-transform: rotate(60deg); }
#gallery-wheel img:nth-child(3) { -webkit-transform: rotate(120deg); }
#gallery-wheel img:nth-child(4) { -webkit-transform: rotate(180deg); }
#gallery-wheel img:nth-child(5) { -webkit-transform: rotate(240deg); }
#gallery-wheel img:nth-child(6) { -webkit-transform: rotate(300deg); }

#gallery-center {
   position: absolute;
   background-image: url("../pic1.png");
   background-position: center;
   top: 50%;
   left: 50%;
   margin-left: -160px;
   margin-top: -160px;
   width: 300px;
   height: 300px;
   border-radius: 50%;
   border: 10px solid white;
}

.fade-overlay {
   position: absolute;
   background-position: center;
   opacity: 0.0;
   width: 100%;
   height: 100%;
   border-radius: 50%;
}

В основном код содержит обычное оформление, поэтому давайте взглянём только на части с масками и трансформациями. Правило -webkit-mask-box-image: url(../mask.svg) round назначает маской наш SVG файл.

-webkit-transform-origin: 50% 100% делает нижнюю часть маски точкой опоры круга. Эта точка является его центром.

Этот код:

#gallery-wheel img:nth-child(2) { -webkit-transform: rotate(60deg); }
#gallery-wheel img:nth-child(3) { -webkit-transform: rotate(120deg); }
#gallery-wheel img:nth-child(4) { -webkit-transform: rotate(180deg); }
#gallery-wheel img:nth-child(5) { -webkit-transform: rotate(240deg); }
#gallery-wheel img:nth-child(6) { -webkit-transform: rotate(300deg); }

Поворачивает каждое последующее изображение на 60 градусов. Наши «куски» выстраиваются в круг.

Класс Fade-overlay будет использован скриптом ↓

JavaScript – заставляем галерею вращаться

$(document).ready(init);

var galleryWheel;
var galleryCenter;
var galleryItems;
var animating;

function init() {
   galleryWheel = $("#gallery-wheel");
   galleryCenter = $("#gallery-center");
   galleryItems = $("#gallery img");

   galleryItems.click(clickImage);
}

function clickImage(e) {
   var target = $(e.target);
   if (!target.hasClass("active") && !animating) {
      animating = true;
      var activeElement = galleryWheel.find(".active");

      // Calculate the number of elements between the active (top) image and the clicked
      // one, and multiply that by the inner angle that each slice has.
      var rotateBy = -360/galleryItems.length * (target.index() - activeElement.index());

      // Make sure the shortest path is taken, the maximum length the wheel should spin
      // is 180 degrees.
      if (rotateBy >= 180) {
         rotateBy -= 360;
      } else if(rotateBy < -180) {
         rotateBy += 360;
      }

      // Create a temporary overlay element that fades in over the center image.
      // When the opacity is full, change the image of the center element behind,
      // and remove the overlay.
      $('<div>')
          .css("backgroundImage", "url(" + target.attr("src") + ")")
              .appendTo(galleryCenter).animate({opacity: 1.0}, 500, function() {
                   galleryCenter.css("backgroundImage", "url(" + target.attr("src") + ")");
                   $(this).remove();
               });

      activeElement.removeClass("active");
      target.addClass("active");

      galleryWheel.animate({rotate: "+=" + rotateBy + 'deg'}, 500, function() { animating = false; } );
   }
}

Для работы скрипта нужно подключить jQuery и плагин jQuery 2D Transformation plugin

Когда пользователь кликает на картинку мы вычисляем расстояние (в градусах) от нее до активной в данный момент картинки. Мы можем быть уверены в том, что круг выберет самый короткий путь вращения, если назначим его лимит между 180 и 180 градусами.

Когда картинка докрутится до нужного положения (сверху) она плавно появится в центре. Так как мы не можем плавно менять фон центрального элемента, то мы накладываем новую картинку поверх него. Когда новая картинка полностью появляется мы убираем изображение-подложку и делаем новую картинку фоном этой подложки, а после чего убираем элемент, который находился наверху. Это создает иллюзию плавной смены фона элемента.

Заключение

Небольшое раздражение в конечном продукте вызывает то, что ограничивающий контейнер центрального изображения блокирует наведение на элементы, расположенные ниже, т.к. он на самом деле квадратный. Есть свойство pointer-events: none;, которое позволяет наводить мышку на элементы, расположенные позади. Но его поведение в этом случае странное.

Эта галерея бесполезна и я не вижу её реального применения. Я лишь хотел показать, что вы можете сделать с помощью современных свойств CSS. Я думаю, вы могли бы сделать какое-нибудь необычное меню, используя эту технику, но поддержка этих свойств браузерами весьма ограничена, поэтому не следует использовать её в реальных сайтах. Надеюсь, что кто-нибудь научился чему-то новому сегодня.

Ссылка на демо этой галереи. Помните что она работает только в Chrome и ночных сборках Safari. Я добавлю поддержку Firefox, когда они исправят баг с прокруткой.

Источник:  css-live.ru
Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи