От автора: Веб-сайт Карла Филипа Бреннена (Carl Philipe Brenner) отличается очень креативной и изящной анимацией, и сегодня мы собираемся разобраться, как воссоздать эффект анимации рамки, применив к линиям SVG переходы CSS.
Сегодня мы хотели бы разобраться в очень тонком, но интересном эффекте анимации рамки, которую можно видеть на креативном вебсайте Карла Филипа Бреннера (Carl Philipe Brenner). При проведении мышью над одним из белых элементов сетки портфолио вы увидите изящную анимацию: элемент сетки становится прозрачным, а линии рамки с каждой стороны начинают анимацию по часовой стрелке, создавая действительно красивый эффект. В данном случае он получается путем анимации ширины или высоты нескольких тегов span с помощью JS. Мы опробуем другой подход, применяющий SVG и переходы CSS. Пожалуйста, помните, что эта техника очень экспериментальна.
Сначала давайте рассмотрим основную концепцию, а затем двинемся к конечному эффекту. Пожалуйста, обратите внимание, что переходы CSS к SVG, которые мы применим, поддерживаются не во всех браузерах.
Когда смотришь на эффект, не сразу ясно, что происходит, но если внимательно глядеть только на одну сторону, скажем, на верхнюю линию рамки, то заметно, что сначала ширина белой линии уменьшается справа налево, и справа с небольшой задержкой, или брешью, появляется новая линия. Будучи добавленным ко всем сторонам, эффект создает иллюзию того, что верхняя линия как будто перемещается вокруг угла к левой стороне, левая сторона перемещается вниз и так далее.
Конечно, такой эффект можно создать без SVG, даже без дополнительных элементов, просто применив псевдоэлементы. Но здесь нужно разобраться, что можно сделать с помощью SVG, и как контролировать ее посредством CSS, а не через JavaScript.
Обдумывая, как создать этот эффект с помощью SVG, нам можно было анимировать stroke-dashoffset штриха прямоугольника или просто начертить линии. Но требовалось решение, не использующее JS, и после некоторых колебаний мы решили, что значения перехода stroke-dashoffset и stroke-dasharray в CSS могут оказаться весьма «глючными». Так что было решено попробовать другое решение, использовав линии и анимировав их перевод. (Можно представить себе другие подходы конкретно к этому эффекту, но нам понравилась идея перемещения линий, потому что ее довольно легко понять и выполнить в CSS, а также она создает возможность другой анимации, как видно из демопримера.)
Особенность линий, которые мы станем использовать, состоит в том, что они послужат в качестве трех состояний анимации. На самом деле они будут в три раза длиннее размера блока, в котором находятся. В середине линии будет зазор размером со сторону блока. Мы добьемся этого, установив значение stroke-dashoffset на длину стороны блока. Теперь весь фокус в переходе позиции линии:
У SVG будет размер блока, поэтому мы не увидим за штриховой линией переполнение. До того, как продолжить работу над следующими тремя линиями, давайте закодируем этот первый этап. Наша линия с SVG содержится в div:
1 2 3 4 5 |
<div> <svg width="200" height="200"> <line x1="0" y1="0" x2="600" y2="0" /> </svg> </div> |
Ширина и высота секции равны 200px, в точности как у рисунка SVG, и мы устанавливаем SVG на абсолютное позиционирование. Ширина штриха линии равна 10 и, что еще важнее, значение stroke-dasharray равно 200:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
div { width: 200px; height: 200px; position: relative; overflow: hidden; background: #ddd; } svg { position: absolute; top: 0; left: 0; } svg line { stroke-width: 10; stroke: #000; fill: none; stroke-dasharray: 200; -webkit-transition: -webkit-transform .6s ease-out; transition: transform .6s ease-out; } div:hover svg line { -webkit-transform: translateX(-400px); transform: translateX(-400px); } |
Также у линии есть переход, а при проведении мышью над секцией нам требуется, чтобы линия перемещалась на две трети своей длины влево, поэтому мы переводим ее на -400px по оси абсцисс x. Рассмотреть и обыграть первый этап можно в этом примере JSBin. Так как нам для значений перехода нельзя здесь применить процентное соотношение, то установим перевод в пикселях.
Следующий этап – добавляем остальные линии. Для того, чтобы понять, как их следует расположить и анимировать, давайте рассмотрим этот GIF:
Нам нужно так анимировать каждую линию, чтобы когда первая часть линии убиралась из блока, в нем появлялась последняя часть связанной перпендикулярной линии. Это создаст иллюзию движения линий вокруг углов.
Давайте рассмотрим свою систему координат и правильно определим точки линии:
Точки левой линии — (0,200) и (0,-400), нижней — (200,200) и (-400,200), а правой — (200,0) и (200,600):
1 2 3 4 5 6 7 8 |
<div> <svg width="200" height="200"> <line class="top" x1="0" y1="0" x2="600" y2="0"/> <line class="left" x1="0" y1="200" x2="0" y2="-400"/> <line class="bottom" x1="200" y1="200" x2="-400" y2="200"/> <line class="right" x1="200" y1="0" x2="200" y2="600"/> </svg> </div> |
Для каждой линии нам требуется установить разные значения перевода при проведении мышью:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
div:hover svg line.top { -webkit-transform: translateX(-400px); transform: translateX(-400px); } div:hover svg line.bottom { -webkit-transform: translateX(400px); transform: translateX(400px); } div:hover svg line.left { -webkit-transform: translateY(400px); transform: translateY(400px); } div:hover svg line.right { -webkit-transform: translateY(-400px); transform: translateY(-400px); } |
Смотрите код в действии.
Теперь мы правильно уловили основную мысль, нам нужен сам эффект. Давайте сделаем его красивым 🙂
Теперь наш блок станет другого размера (300 x 460), а также мы добавим к нему текстовые элементы:
1 2 3 4 5 6 7 8 9 10 11 |
<div class="box"> <svg xmlns="//www.w3.org/2000/svg" width="100%" height="100%"> <line class="top" x1="0" y1="0" x2="900" y2="0"/> <line class="left" x1="0" y1="460" x2="0" y2="-920"/> <line class="bottom" x1="300" y1="460" x2="-600" y2="460"/> <line class="right" x1="300" y1="0" x2="300" y2="1380"/> </svg> <h3>D</h3> <span>2012</span> <span>Broccoli, Asparagus, Curry</span> </div> |
Чтобы воссоздать этот эффект таким, как на веб-сайте Карла Филипа Бреннера, добавим самому блоку цветовой переход и небольшой зазор между рамкой SVG и элементом с помощью тени блока:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.box { width: 300px; height: 460px; position: relative; background: rgba(255,255,255,1); display: inline-block; margin: 0 10px; cursor: pointer; color: #2c3e50; box-shadow: inset 0 0 0 3px #2c3e50; -webkit-transition: background 0.4s 0.5s; transition: background 0.4s 0.5s; } .box:hover { background: rgba(255,255,255,0); -webkit-transition-delay: 0s; transition-delay: 0s; } |
Кроме того, назначим стили элементам текста:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
.box h3 { font-family: "Ruthie", cursive; font-size: 180px; line-height: 370px; margin: 0; font-weight: 400; width: 100%; } .box span { display: block; font-weight: 400; text-transform: uppercase; letter-spacing: 1px; font-size: 13px; padding: 5px; } .box h3, .box span { -webkit-transition: color 0.4s 0.5s; transition: color 0.4s 0.5s; } .box:hover h3, .box:hover span { color: #fff; -webkit-transition-delay: 0s; transition-delay: 0s; } |
Стили SVG и линии будут такими же, как до этого:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.box svg { position: absolute; top: 0; left: 0; } .box svg line { stroke-width: 3; stroke: #ecf0f1; fill: none; -webkit-transition: all .8s ease-in-out; transition: all .8s ease-in-out; } |
Нам нужна небольшая задержка перехода линии, иначе мы ее не увидим из-за перехода фонового цвета блока:
1 2 3 4 |
.box:hover svg line { -webkit-transition-delay: 0.1s; transition-delay: 0.1s; } |
До того мы определили stroke-dasharray всего одно значение, но теперь нам нужно, чтобы «заполненные» части и зазор были разных размеров с тем, чтобы эффект стал в точности таким, какой нам нужен:
1 2 3 4 5 6 7 8 9 |
.box svg line.top, .box svg line.bottom { stroke-dasharray: 330 240; } .box svg line.left, .box svg line.right { stroke-dasharray: 490 400; } |
Поиграв с этими значениями, вы заметите, что линии появляются по-разному.
И наконец, установим соответственные значения для переводов при проведении мышью. Так как ширина нашего элемента составляет 300px, линиям по горизонтали потребуется переход двух третей общей ширины, которая составляет 900px. То же самое касается вертикальных линий:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.box:hover svg line.top { -webkit-transform: translateX(-600px); transform: translateX(-600px); } .box:hover svg line.bottom { -webkit-transform: translateX(600px); transform: translateX(600px); } .box:hover svg line.left { -webkit-transform: translateY(920px); transform: translateY(920px); } .box:hover svg line.right { -webkit-transform: translateY(-920px); transform: translateY(-920px); } |
Вот и все! Надеюсь, этот небольшой эффект вам понравился и оказался для вас источником вдохновения. Просмотрите альтернативные варианты, чтобы увидеть остальные возможности этой техники.
Автор: Mary Lou
Источник: //tympanus.net/
Редакция: Команда webformyself.
Комментарии (1)