Разработка интерактивной демонстрации при помощи контуров обрезки в CSS

Впечатляющие интерактивные веб-демонстрации широко используются в нынешнюю эпоху по разным основаниям, преимущественно для рекламы особо выдающихся продуктов и услуг. После обнаружения малоизвестного свойства clip-path в CSS, я пустился в пятимесячное интерактивное приключение по созданию моей собственной с иной целью: распространить знание о трудностях 30 столь же малоизвестных исчезающих видов.

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

1-in-pieces-opt

In Pieces: 30 видов, 30 кусочков.

In Pieces  интерактивная демонстрация 30 самых необычных, но, как это ни печально, находящихся под угрозой исчезновения видов в мире. эта демонстрация является информационным напоминанием о красоте, которую мы ежедневно рискуем потерять, но также и возможность показать эволюционное отличие, поскольку эволюция наделила многие виды особой генетической спецификой. Пользователи узнают историю этих уникальных форм жизни и о том, какие опасности им грозят, а также приглашаются погрузиться в численные данные, скачать обои и даже получить плакат, демонстрирующий целую коллекцию — полностью доступную на мобильном устройстве.

Вдохновение: контуры обрезки и анимация в CSS

«In Pieces» начинался как экспериментирование и ковыряние в коде, а не как грандиозный план для интерактивного произведения искусства, чтобы помочь охране природы, как бы романтично это ни звучало. Я помню, как читал про значение polygon свойства CSS clip-path в середине 2014 и изучал его удивительный потенциал. Прошло несколько месяцев, и я был удивлён, когда увидел, что оно почти не используется в вебе, вероятно находясь в тени внимания, которое уделяется SVG, canvas и WebGL. Я чувствовал, что clip-path даёт возможность погрузиться во что-то неизведанное и исследовать, что можно было бы сделать при помощи него. В тоже самое время, создавая проект на чистом CSS (как ни странно), я чувствовал себя современным.

Если вы не знакомы с CSS clip-path или его возможностями создавать многоугольники, у Дирка Шульце есть замечательное руководство. В качестве примера, превратить обычный div в треугольник можно при помощи этого фрагмента кода:

Код
.polygon-div {   -webkit-clip-path: polygon(0% 0%, 50% 100%, 100% 0%); }
2-in-pieces-polygon-opt

Результат создания многоугольника при помощи вышеприведённого кода.

Первейшее, что я хотел выяснить — смогут ли значение polygon и CSS-переходы найти общий язык, и насколько гладко пройдет их первое свидание. Я был счастлив видеть, что их союз оказался прочным, особенно с функцией плавности в придачу, чтобы добавить естественности:

Код
.polygon-div {   -webkit-clip-path: polygon(9.38% 59.35%, 13.4% 58.95%, 9.28% 61.08%);   transition: .18s cubic-bezier(.7,.3,0,1);     &:hover {       -webkit-clip-path: polygon(20% 59.35%, 30% 58.95%, 40% 61.08%);     } }

Идея и дизайн

3-in-pieces-scan-opt

Первые наброски и мозговой штурм

Исходя из этого я понял, что мне нужно придумать способ сделать многоугольник художественным средством, который стал бы своего рода визуальным сравнением — животные из многоугольников, которые казались бы настоящей визуальной областью для изучения. Для начала я хочу кое-что прояснить: виды из многоугольников — не что-то новое в дизайне. Сотни проектов используют многоугольники для создания животных, и их легко найти на таких сайтах как «Behance» (искать «превратить обычный div в треугольник можно») Этот момент очень важен, когда я говорю об «идеи». Я видел несколько по-настоящему приятных комментариев на проекте, и некоторые из них содержали ссылки на «оригами» и «полигональный стиль», но они немножко промахнулись в том, что идея не столько в визуальном оформлении, сколько в том, что виды собираются из «кусочков» и в метафоре, что эти виды настолько редки, что в природе их приходится буквально «собирать по кусочкам», поэтому и сами животные составлены «из кусочков». Без этих аспектов, проект просто становится визуальной периферией.

Я думаю, что есть что-то очень романтичное и интересное в непосредственном соединении элемента новой технологии с идеей и в таком подходе к разработке, при котором технология сливается с идеей и работает на нее. Вот в чем на самом деле суть In Pieces.

После этого начального эксперимента другие идеи пришли быстро. Например, понимание того, что на одно животное могло бы потребоваться около 30 кусков, что привело к решению создать 30 видов и идеи использовать многоугольные формы для визуализации данных истории численности и другой статистики по этим видам. Давайте погрузимся в некоторые конкретные детали и посмотрим, каким путём они были достигнуты и как вы можете использовать их для ваших собственных интерактивных проектов.

Создание животных из многоугольников

Код для каждого треугольного куска был написан вручную, потому что не существовало инструментов или фрейморков, которые могли бы мне помочь. Если вы посмотрите исходный код каждой части, то увидите, что они делаются из 30 div-ов, которые размещены друг на друге и вложены в последовательности родительских div-ов. Каждый из 30 div-ов в свою очередь содержит дочерний элемент, который фактически и является одной из 30 частей.

Иллюстрация

Возможно самым простым аспектом проекта была подготовка иллюстраций в Adobe Illustrator. Было нелегко создать все их 30 штук, но в то же время это была самая очевидная часть проекта, главным ограничением было количество многоугольников. На втором изображении ниже показано то, что получилось после трассировки.

4-in-pieces-opt

Векторные контуры сахарского орикса в выбранном состоянии.

5-in-pieces-oryx-tracer-opt

Пример прозрачной картинки в формате PNG — использовалась для трассировки в браузере.

6-in-pieces-wire-opt

Это изображение ужасного листолаза в режиме контуров обводки в иллюстраторе, благодаря чему процесс иллюстрирования выглядит круче и серьезнее, чем до этого. Но обратите внимание на преднамеренные наложения.

Трассировка

Затем я использовал эти иллюстрации в виде плоских PNG-изображений в браузере, чтобы проследить за ними — но, чтобы скопировать в код 30 иллюстраций, я отчаянно нуждался в способе ускорить процесс, который состоял преимущественно из размещения 30 многоугольников в позиции по умолчанию, а затем отдельного перемещения каждой точки в соответствии с нижележащим PNG-изображением. Некоторые онлайн-сервисы, такие как «CSS Plant Generator» и «Clippy» Беннета Фили полезны, чтобы наметить точкиclip-path, но я нуждался в чём-то более индивидуальном — так что я создал его в виде функции JavaScript:

Код
$('body').on('click', function (e){   var mouseX = e.pageX;   var mouseY = e.pageY;   var shapesoffsetX = $('.polygon-wrap').offset().left;   var shapesoffsetY = $('.polygon-wrap').offset().top;   var polygonswidth=$('.polygon-wrap').width();   var polygonsheight=$('.polygon-wrap').height();   var shapesmouseX = mouseX - shapesoffsetX;   var shapesmouseY = mouseY - shapesoffsetY;   var mousepercentX = shapesmouseX / polygonswidth;   var mousepercentY = shapesmouseY / polygonsheight;   var finalmouseX = (mousepercentX) * 100 ;   var finalmouseY = (mousepercentY) * 100 ;   var normalisedX = parseFloat(finalmouseX).toFixed(3);   var normalisedY = parseFloat(finalmouseY).toFixed(3);    nodecount = nodecount+1;   if (nodecount < 3) {      nodescss = nodescss + normalisedX + '% ' + normalisedY + '% ,';   } else   if (nodecount == 3) {      nodescss = nodescss + normalisedX + '% ' + normalisedY + '% );';     alert(nodescss);      nodescss = '-webkit-clip-path: polygon( ';      nodecount = 0;   } });

Эта JavaScript-функция запускается по клику на body. Вам может понадобиться добавить проверку по определенной переменной, как сделал я, чтобы она запускалась только в тот момент, когда вы трассируете многоугольники. Вот краткий список того, к чему привязаны div-ы и переменные:

  • mouseX и mouseY
    Эти переменные принимают координаты мыши в точке клика.
  • shapesoffset
    Эта переменная показывает расстояние от div-а до верхнего левого угла окна браузера.
  • shapesmouseX и shapesmouseY
    Эти показывают где находится мышь в контексте polygon-wrap.
  • mousepercentX и mousepercentY
    А в этих переменных сохраняется координаты мыши в процентах относительно polygon-wrap.
  • finalmouse и normalised
    Эти значения преобразуют те дробные проценты в удобные CSS-значения.
  • nodecount
    В эту переменную записывается, сколько раз пользователь кликнул по экрану, от 0 до 3, прежде чем цикл начнётся заново с 0. Поскольку кусочки — это треугольники, то для каждого из них требуется по три точки.

Итак, что тут происходит? В общем, эта функция дает вам возможность трижды кликнуть над плоской PNG-картинкой, чтобы найти положения точек в процентах относительно div-а, который вы обводите. При каждом клике постепенно собирается строковая переменная, пока третий клик не выведет полную CSS-строку в модальном окне, откуда ее можно скопировать и вставить.

7-in-pieces-opt

Модальное окно содержит копируемую и вставляемую строку после трассировки трёх точек, готовую к размещению в CSS.

Дальнейший процесс

После того, как вы скопировали код, его легко вставить, но мне также нужно было убедиться, что соответствующий кусочек во время этого шага был закрашен. Копирование каждого цвета из «Adobe Illustrator», а затем вставка в «Sublime» кажется слишком долгим процессом, и есть приложение для этого. Едва ли найдется что-то лучше Sip, поскольку он сразу же копирует цвет, который вы выбрали, в буфер обмена, откуда его можно вывести в код:

8-sip-opt

Sip — удобное приложение, которое предоставляет глобальный выбор цвета

Код
&:nth-child(4) {   .shard {     -webkit-clip-path: polygon(23.45% 56.143%, 34.66% 57.3%, 22.45% 71.714%);     background-color: #D7C5A4;   } }

Мне удалось вывести код для всех 30 кусочков каждого животного, один за другим, используя этот процесс трассировки. Но было ещё над чем работать: одна из самых больших проблем в отображении этого стиля — сглаживание между двумя формами. Если вы идеально подгоните две векторные формы вплотную друг к другу, то между ними окажется очень бледная, но всё же заметная сквозная линия, так же, как бывает у вас и в «Иллюстраторе». Поэтому мне было нужно слегка перекрыть каждый вектор при помощи инспектора, так что требовался способ точно определить, какие прямоугольники вели себя неправильно. Вот где вступает в дело другое огромное преимущество CSS-многоугольников: они работают как маска для фона внутри фигуры. Поэтому я создал повторяющиеся фоновые изображение для всех 30 чисел, чтобы отследить, где какой многоугольник:

9-in-pieces-opt

Повторяющиеся изображения чисел, обрезанные по маске многоугольников, чтобы указать, какие кусочки надо переделать.

Для меня контуры обрезки в виде многоугольника предоставляют нечто особенное благодаря подобному эффекту маски. Я решил проблему с его помощью (и позже применил это для эффекта крови при «взрыве»), но в конце концов я думаю, что с этим эффектом можно делать невероятно креативные вещи. Одна потрясающая возможность заключается в том факте, что когда вы двигаете многоугольник, изображение не движется вместе с многоугольником — вы изменяете маску. Если вы соедините отличную производительность, с которой преобразуется отдельный многоугольник, с фоновым изображением, которое может двигаться одновременно с ним, то, я думаю, за этим скрывается что-то действительно клёвое. Возможно из этого вырастет новый личный проект. Другое, что стоит помнить — маску можно накладывать на элементы, не только на изображения. По сути, несколькими абзацами ниже я разбираю более подробно эффект «мерцания» на видах, который делает именно это.

Я лично не смог найти способ, но я готов поспорить, что если вы копнёте глубже, то также найдёте способ придать многоугольникам визуальные «очертания» (как в изображении лягушки несколькими абзацами выше). Опять же, это могло бы классно выглядеть как что-то научное. Это инструмент с огромным потенциалом, и я очень рад видеть новые вещи, созданные им

Как изменяются виды

In Pieces во многом зависит от добавления, удаления и изменения названий класса, а сами виды ничем не отличаются. Изменение названия класса только лишь у родительского div соответствующих видов позволяет соответственно изменить CSS в элементах внутри него. Названия видов хранятся в таком массиве:

Код
var animalList = ['crow', 'vaquita', 'tamarin', 'frog', 'owl', 'turtle', 'oryx', 'iguana', 'seahorse', 'armadillo', 'sloth', 'kakapo', 'echidna', 'penguin', 'damselfly', 'bear', 'parrotfish', 'camel', 'butterfly', 'ostrich', 'panda', 'tapir', 'sifaka', 'lynx', 'rhino', 'peccary', 'okapi', 'loris', 'hirola', 'drill' ];

Как только новый вид включается в игру, будь то следующий, предыдущий или непосредственно выбранный вид, я определяю текущее состояние вида при помощи этого кода:

Код
prevAnimal = (animalList.indexOf($('#animalchanger').attr('class')));

Для справки, #animalchanger — родительский div, управляющий конкретными видами, которому устанавливается строковая переменная из массива animalList. Эта строка определяет индекс (т.е. целое число) для названия текущего вида в массиве. Это нужно, чтобы создать переменную newAnimal — названия нового вида, которое зависит от того, какую кнопку нажал пользователь. Например, кнопка «Следующий вид» могла бы быть такой:

Код
newAnimal = prevAnimal + 1;

Конечно, одновременно с этим происходит целый ряд других вещей, но уже с установленным индексом нового животного, который затем подставляется в класс div-а:

Код
$('#animalchanger').attr('class',animalList[newAnimal]);

Переходы между многоугольниками и SASS для циклов

Теперь вы знаете, как создаются многоугольники и как сменяются многоугольники от вида к виду при помощи изменения класса у родительского div-а. А сейчас давайте углубимся в забавы с анимацией! Как уже упоминалось, всё основано на CSS, а движение ничем не отличается; чтобы адаптировать движение для соответствующих действий, применяется широкий выбор настроек для переходов. Прежде чем мы перейдем к CSS, мне следует упомянуть, что в последнем примере кода вычисляется кое-что еще: направление, которое выберет пользователь (слева направо или справа налево)

Код
if (prevAnimal > newAnimal) {    $('.wrap').addClass('right-to-left');    $('.wrap.left-to-right').removeClass('left-to-right'); } else {    $('.wrap').addClass('left-to-right');    $('.wrap.right-to-left').removeClass('right-to-left'); }

В результате такого присвоения класса «направления» виды чередуются в том направлении, в котором вы просматриваете демонстрацию, и делается это при помощи двух циклов for в SASS, в зависимости от того, какие два класса задействованы.

Код
$fluidpolygons: .7,.3,0,1; .left-to-right {   @for $i from 1 through 30 {     $s: ($i*0.04+0.3s);     $t: ($i*0.02s+0.2s);     $ct: ($i*0.02s);         :nth-child(#{$i}) {       transition:         -webkit-clip-path $s $t cubic-bezier($fluidpolygons),         background-color $s $ct;     }   } } .right-to-left {   @for $i from 1 through 30 {     $s: ((31-$i)*0.04+0.3s);     $t: ((31-$i)*0.025s+0.2s);     $ct: ((31-$i)*0.02s);         :nth-child(#{$i}) {       transition:       -webkit-clip-path $s $t cubic-bezier($fluidpolygons),       background-color $s $ct;     }   } }

Как можно видеть, есть набор разных скоростей и задержек для разных свойств. Цикл for в Sass используется, чтобы изменять как длительность, так и задержку перехода, в зависимости от индекса многоугольника. Например, в движении слева направо анимация перехода 10-го многоугольника будет длиться 0,7 секунды с задержкой в .4 секунды. Обратное направление высчитывается просто путём смены порядка на противоположный — вычитание индекса многоугольника из 31.

Анимация для видов

Вопреки первому впечатлению, виды не передвигаются при помощи CSS-анимаций. Причина, по которой я ушёл от CSS-анимаций — мне не нравятся явные «обрывы», когда анимация прерывается на полпути. Вместо этого я установил два класса, которые проходят в цикле два состояния: для основного и второстепенного движения.

Код
function animalStates(e) {   setInterval(function(){     e.removeClass('state-four');     setTimeout(function(){        e.addClass('state-two');     }, 1000);     setTimeout(function(){        e.removeClass('state-two');        e.addClass('state-three');     }, 2000);     setTimeout(function(){        e.removeClass('state-three');        e.addClass('state-four');     }, 3000);   },4000); } function animalStatesSecondLevel(e) {   setInterval(function(){     setTimeout(function(){        e.addClass('two-state-two');     }, 1000);     setTimeout(function(){        e.removeClass('two-state-two');     }, 1100);     setTimeout(function(){        e.addClass('two-state-two');     }, 1400);     setTimeout(function(){        e.removeClass('two-state-two');     }, 1500);   },3000); }

Есть новый CSS для каждого состояния, и многоугольники просто перемещаются в новое место, изменяют цвет или меняют еще какое-либо переопределяемое свойство. Важно отметить, что как только «фаза анимации» начинается (после того, как вид завершил свою трансформацию), длительности и задержки переходов в многоугольниках из предыдущего кода перезаписываются, чтобы синхронизироваться и ускориться.

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

10-frog

Анимации для видов использует двойной набор классов, чтобы создать «многослойные» движения.

Мерцание

Один из самых быстрых визуальных эффектов для реализации на сайте был эффект едва заметного мерцания, которое происходит с видами каждые несколько секунд, добавляя еще и всплеск объемного блеска. Эти мерцания пользуются преимуществом превосходного эффекта маски, который предоставляет по умолчанию clip-path: любой контент, содержащийся в элементе, к которому применено clip-path, будет виден только в области, обрезанной по маске. Для мерцания я создал псевдоэлемент на всю ширину и высоту, который располагается внутри каждого кусочка.

11-in-pieces-shimmer-opt

Слева — анимация мерцания

Код
.shard {   &::before {     content: ""; width: 100%; height: 100%;     background: rgba(255,255,255,0); top: 0; left: 0;     position: absolute;   }   @for $i from 1 through 30 {     &:nth-child(#{$i}) .shard::before {       $ad: ($i*0.05s+0.02s);       @include animation(shimmer .8s $ad forwards);     }   } } @include keyframes(shimmer) {   0% {     background-color: rgba(255,255,255,0);   }   35% {     background-color: rgba(255,255,255,.1);   }   100% {     background-color: rgba(255,255,255,0);   } }

Мерцание создаётся каждым псевдоэлементом путём простого медленного появления и затухания с задержкой перехода. Такое постепенное затухание создаёт приятный плавный эффект. Подумайте, как плохо бы это выглядело, если разных задержек не было. Вместо opacity я использую значение альфа-канала RGBa, чтобы изменять прозрачность псевдоэлементов: RGBa намного меньше загружает процессор. Использование opacity в моих первых экспериментах привели к огромным глюкам, как я объясню в ближайшее время.

Запасной вариант

Контуры обрезки поддерживаются во всех современных браузерах кроме Internet Explorer, но из-за одного фактора Firefox тоже выпадает. Он поддерживает данную технологию, но только в виде ссылки на SVG-контур, а это означает, что изменение координат придётся делать не на CSS. Я уверен, что кто-то с более программистским умом мог бы найти способ заставить это работать во всех браузерах, но что я ценю в этом проекте, это, во-первых, то, что он является откровенно экспериментальным, а во-вторых, что он достаточно быстро работает на большинстве мобильных устройств. Последний пункт — ключевой: заставить проект работать на мобильных, помимо обычных медиазапросов — почти то же самое, что возня с «ретиновыми» дисплеями.

Запасной вариант, к которому я пришёл в «In Pieces» — простое слайдшоу с изображениями видов. Идея сохраняется: визуально всё очень похоже, только без эффектов перехода.

Работа с «ретиной» и баги

С технологией, которая всё ещё требует префиксов, не удивительно, что при использовании CSS clip-pathвы, возможно, столкнётесь с рядом проблем, особенно когда в процессе учувствуют переходы. Во-первых, они не любят перекрытий с элементами, у которых происходит переход между значениями прозрачности — иногда вы получите визуальное «статическое» появление, как старый телевизор, который не может поймать сигнал.

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

В принципе у устройств с «ретиной» нет никаких проблем с clip-path, и при простом его использовании (т.е. для нескольких объектов) всё должно быть хорошо. Но с 30 многоугольниками я наткнулся на проблемы, которые, пожалуй, относятся к проблеме перекрывающихся прозрачностей. Например, можно заметить, что десктопных экранах без ретины у меня есть приятная виньетка вокруг видов, которое делает визуальный эффект появления немного более завершённым. Использовались ли при этом CSS-градиенты или изображения — не важно, экраны с ретиной и Safari «захлёбывались» пока это не было удалено. Так что это осталось неким «приятным дополнением» для Chrome на «безретиновых» экранах.

Производительность

На сайте столько всего происходит, что неудивительно, что мне пришлось изрядно повозиться, чтобы добиться хорошей производительности. Как отмечалось выше, «ретина» ведет себя неидеально (особенно в случае сплошь интерактивного контента), и ради нее пришлось кое-что удалить. Но я также применил множество изящных трюков для CSS, чтобы движение было более плавным, и их можно убирать и использовать снова. Я говорил о циклах for в Sass — все 30 объектов перемещаются с небольшими задержками, чтобы добавить глубины к визуальному движению. Но при правильном использовании это также может улучшить производительность.

12-in-pieces-performance-opt

Переход черепахи почти завершён — и только несколько многоугольников движутся в один момент времени.

Представьте себе, что вы двигаете 30 объектов одновременно; вы просите браузер о многом, и логично предположить, что это могло бы создать проблемы. Если у вас есть скорость 0.199 секунд и задержка 0.2 секунды на каждом объекте, то вы бы могли исправить эту проблему путём передвижения только одного объекта за раз. Тот факт, что всего происходит такое же количество движений, не имеет значения. Если анимация делается по очереди, то производительность сразу же улучшается в 30 раз. Также заметьте, что «.99» убивает любое наложение в этом случае. Конечно 0.2 × 30 дало бы в сумме 6 секунд, что утомило бы пользователя. Поэтому в моём случае я остановился где-то по середине, подобрав такое число одновременно движущихся элементов, которое хорошо смотрится, но не вредит производительности. Это великолепный трюк, потому что он полезен для многих вещей (он используется на всём сайте для замедленных переходов), но также добавляет так много глубины к визуальному виду.

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

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

Руководство: главное меню

13-in-pieces-menu-opt

Главное меню для выбора любого вида.

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

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

Код
.hover-detector {   div {     position: absolute;     left: 0; top: 0;     margin-left: -35px; margin-top: -35px;     width: 70px; height: 70px;     @for $i from 1 through 30 {       &:nth-child(#{$i}) {         $r: ($i*12deg - 7deg);         @include transform(rotate($r) translateY(-230px));       }     }   } }

Что-что?

Ну смотрите, 30 элементов div обозначены здесь как div. Я применяю Sass для цикла for, чтобы использовать каждую центральную привязку div-а (по-прежнему самый центр круга — каждый div позиционируется абсолютно поверх друг друга), чтобы трансформировать его относительно этого центра в зависимости от того, какой конкретно это дочерний элемент. Теперь 12 градусов умещаются в 360 градусов ровно 30 раз; таким образом 12 градусов — значение, которое используется, чтобы последовательно повернуть каждый div. Эффект завершается сдвигом каждого div-а на 230 пикселей от центра.

14-in-pieces-menu-opt

Сдвиг трансформации и поворот на угол, рассчитанный при помощи цикла for в Sass.

Приятные мелочи: визуализация данных

15-in-pieces-data-opt

Визуализация данных: круговые диаграммы

Такие инструменты, как D3 действительно расширяют возможности интерактивной визуализации данных, которыми мы можем воспользоваться, так как мы больше не ограничены квадратами, кругами прямоугольниками, чтобы делать передачу информации осязаемой. Но CSS-многоугольники тоже можно использовать для этого, причем очень просто. В диаграммах визуализации данных на «In Pieces» я использую такую же технику, как я делал для главного меню, чтобы позиционировать даты и числа по кругу, используя единственный div, пока контуры обрезки изменяются, перетекая из одной формы в другую, чтобы данные могли сами рассказать свою историю. Вот строка кода, которая нужна, чтобы сгенерировать быструю и простенькую круговую диаграмму, как используется в диаграмме выше:

Код
-webkit-clip-path: polygon(31% 4%, 66% 11%, 84% 36%, 81% 63%, 60% 74%, 43% 68%, 37% 55.5%, 42.5% 47%);

Одна из вещей, которую вы могли заметить в кусочке — это что схемы иногда переходят от восьми точек данных к 4, 5 или 6. Когда делаешь что-то типа этого, вы должны поддерживать одно и то же число координат многоугольника, чтобы перемещаться между ними. Подобно, как и во многих других языках программирования, если у вас разное число точек, то clip-path в CSS не знает, как обрабатывать движение, и поэтому оно просто перескакивает к следующему состоянию состояния. Скажем, для 6-точечной диаграммы, я просто сделал 2 «неактивные» точки данных, координаты которых равны 50% 50%, и это означает, что эти точки плавно переносятся в центр.

Приятные мелочи: шероховатости шрифта

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

16-in-pieces-scratchy-opt

Анимация шероховатой типографики

Ориентируясь только на WebKit-браузеры, следующий код используется для достижения эффекта:

Код
.textured-type, .animal-nav-content h2 {   background: url('../img/textured-ui/repeat-white.png') center center repeat;   background-size: 80px 60px;   -webkit-background-clip: text;   -webkit-text-fill-color: transparent;   animation: scratchy .253s linear forwards infinite; } keyframes scratchy {   0% { background-position: 0 0; }   25% { background-position: 0 0; }   26% { background-position: 20px -20px; }   50% { background-position: 20px -20px; }   51% { background-position: 40px -40px; }   75% { background-position: 40px -40px; }   76% { background-position: 60px -60px; }   99% { background-position: 60px -60px; }   100% { background-position: 0 0; } }

По сути здесь смешивается техника маски обрезки по тексту в CSS, которая теперь доступна для использования в WebKit-браузерах, с CSS-анимацией, которая просто перемещает фоновое изображение между определённым количеством разных мест при помощи движения быстрыми рывками, что приводит к эффекту «шуршания». Всё просто!

Приятные мелочи: неоднозначная иконографика и экспериментирование с интерфейсом как головоломкой

17-in-pieces-icons-opt

Иконографика использована для наиболее ценной информации.

Один тип, который я неоднократно получал, относится к читабельности пользовательского интерфейса — а именно к иконкам, в особенности тем, которых ссылаются на обои для рабочего стола и визуализацию данных. Это был как раз тот редкий случай, когда ты радуешься плохому отзыву, поскольку на самом деле именно этого я и добивался. В общем, я считаю, что в опытах наподобие этого (я определенно не говорю о корпоративных веб-сайтах, сайтах продающих продукцию и т.д.), излишнее «разжевывание» информации лишает пользователя радости самостоятельного открытия. Вы, вероятно, могли догадаться, что иконка справа указывает на обои или «изображение» для рабочего стола, например, но это совершенно неочевидно — тем не менее, это полностью преднамеренно. Пользователь, который кликает на иконку, удивится, когда она откроет окно, ещё один слой с контентом. Кликнули ли бы люди туда, знай они это заранее, и как тогда они бы узнали, что от этих обоев их отделяет всего один клик? Я считаю, что разумное экспериментирование с тем, как пользователь мысленно исследует сайт — так же важно, как и создание совершенно ясного пути для него.

Тоже самое можно даже было сказать о наиболее важных призывах к действию на всём сайте — «В чём опасность?». Кнопка выпрыгивает с едва заметной анимацией, чтобы привлечь внимание пользователя, но терминология на самом деле не объясняет того, что вот-вот произойдет — «момент взрыва». Психологически, изменение того, как информация преподносится пользователю, влияет на то, как он ее воспринимает, в состоянии удивления и заинтригованности.

Заключительные мысли

18-in-pieces-opt

Реакция на «In Pieces» просто сразила меня наповал. Мы могли бесконечно обсуждать, подходят ли сайты только для WebKit для клиентских проектов (и это достойный аргумент), но реальные реальное количество просмотров и публичный резонанс должны приобретать важность. Я считаю, что у CSS-многоугольников есть огромный потенциал для будущих проектов, и я надеюсь увидеть, что эта технология используется в ещё более безумными и креативными способами, чем получилось у меня.

За время «путешествия» я много раз пытался добраться до сути того, почему проект стал таким успешным. Идея важна, и по-моему это показывает, как побочный проект с действительно благими целями может охватить больше людей, поскольку широкая общественность намного умнее, чем мы в своей отрасли иногда ей приписываем. Я полагаю, что некоммерческий проект может быть оценен пользователем в 2015, и я нахожу это интересным, когда берусь за работу с клиентами.

Я думаю, что на такой проект будет интересно взглянуть дизайнерам-разработчикам, поскольку один-два человека в состоянии контролировать всё это дело в полной гармонии общения. От идеи до дизайна и разработки все составляющие непосредственно общаются друг с другом, и в итоге они идут рука об руку, а не остаются приятными по отдельности, но не связанными между собой частями. полигональный стиль не дал бы такого визуального эффекта без технологии, которая за ним стоит, а технология ничего ни сказала бы без причины или мессиджа, и эта идея не существовала бы без «кусочной» составляющей, которую несет в себе полигональный стиль. Я говорил многим друзьям, что не считаю, будто дизайн, идея, технология, звук или общий порядок представления информации в этом проекте — лучшие каждое в своем классе, если рассматривать их по отдельности. Но поскольку все они действуют заодно, они становятся чем-то большим, чем сумма их частей. И я полагаю, что этот потенциал даёт огромную возможность для дизайнеров и разработчиков в одном лице

1731