Реализуем эффект анимации границ с помощью SVG и CSS

demosourse

На сайте Carl Philipe Brenner есть несколько красивых и утонченных анимированных эффектов, и сегодня мы хотим воссоздать эфект анимации границ с использованием переходов CSS на линиях SVG.

Сегодня мы бы хотели изучить красивый и интересный эффект анимации границ, который можно увидеть на креативном сайте Carl Philipe Brenner. При наведении на один из трех блоков портфолио, происходит прикольная анимация: фон блока становится прозрачным, а линии границ движутся по часовой стрелке, что создает весьма приятный эффект. В данном случае эффект реализуется при изменении ширины или высоты нескольких span-блоков при помощи JS. Мы попробуем применить другой подход, который будет использовать SVG и переходы CSS. Прошу заметить, что эта техника является экспериментальной.

Давайте определимся с основной концепцией, а дальше будем постепенно ее прорабатывать до получения финального эффекта.

Заметьте, что мы будем использовать переходы CSS и SVG, что может не поддерживаться во всех браузерах.

При первом просмотре эффекта не сразу понятно, что же все-такие происходит, но если присмотреться к границе - скажем, к верхней границе, - вы можете заметить, что сначала длина белой линии уменьшается справа налево, а новая линия выезжает с правой стороны с небольшой задержкой. Принимая во внимание всю картину, получается, что линии движутся вокруг углов по часовой стрелке. Конечно, вы можете реализовать подобный эффект без помощи SVG, даже без каких-либо дополнительных элементов, лишь используя псевдо-элементы. Но мы ведь хотим изучить, что же мы можем сделать с помощью SVG, и как мы можем контролировать его посредством CSS без необходимости использовать JavaScript.

При обдумывании того, как можно реализовать подобный эффект с использованием SVG, на ум приходит следующее: можно анимировать свойство stroke-dashoffset заливки прямоугольника, или же рисовать линии напрямую. Мы бы хотели решить задачу без использования JavaScript, и после некоторых изысканий мы пришли к выводу, что CSS-переходы для свойств stroke-dashoffset и stroke-dasharray ведут себя по-разному в разных браузерах. Так что мы решили попробовать другие решения, используя линии и анимируя их смещения. Мы могли бы придумать и другие подходы к решению этой задачи, но нам нравится идея сдвига линий, так как это довольно легко понять и реализовать в CSS, и это также открывает варианты использования различных анимаций.

Особенность линий, которые мы будем использовать заключается в том, что они будут представлять собой три состояния нашей анимации. Фактически они будут в три раза длиннее стороны контейнера, в которой они будут содержаться. В середине линий будет разрыв шириной со сторону контейнера. Мы добьемся этого установкой значения stroke-dashoffset в размер стороны контейнера. Весь трюк заключается в манипуляции позиции линии:

SVG будет размером с контейнер, так что мы не увидим части линий, выходящих за границы контейнера.

Для начала создадим разметку. У нас будет блок div, в котором будет находиться SVG с нашей линией:

<div>
    <svg width="200" height="200">
        <line x1="0" y1="0" x2="600" y2="0" />
    </svg>
</div>

У блока ширина и высота равны 200px, как и у полотна SVG, а само полотно SVG мы позиционируем абсолютно. Ширина штриха линии равна 10, и, что самое важное, параметр stroke-dasharray имеет величину 200:

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):

<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>

Для каждой линии необходимо задать своё значение сдвига при наведении:

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), и мы также в него добавим несколько текстовых элементов:

<div class="box">
    <svg xmlns="http://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>

Чтобы воссоздать эффект, который мы видели на сайте Carl Philipe Brenner, добавим также эффекты перехода для цвета самому контейнеру, а также добавим небольшое пространство между границей SVG и контейнером с помощью box-shadow:

.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;
}

Также стилизуем и текстовые элементы:

.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 и линии будут стилизованы с помощью следующих стилей:

.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;
}

Далее мы бы хотели реализовать небольшую задержку сдвига линий, иначе при смене цвета контейнера их не увидим:

.box:hover svg line {
    -webkit-transition-delay: 0.1s;
    transition-delay: 0.1s;
}

До этого мы задавали параметр stroke-dasharray одинаковым для всех линий, но теперь нам нужно, чтобы “заполненные” части линии и разрыв были разных размеров, чтобы наш эффект стал именно таким, как нам надо:

.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. То же касается и вертикальных линий:

.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);
}

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

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://tympanus.net/codrops/2014/02/26/creating-a-border-animation-effect-with-svg-and-css/
Перевел: Станислав Протасевич
Урок создан: 14 Марта 2014
Просмотров: 18971
Правила перепечатки


5 последних уроков рубрики "HTML и DHTML"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 15 Марта 2014 20:04
    artemt
    Не работает в EI, Opera, Safari )
    • 16 Марта 2014 13:23
      Larik29
      В Опере у меня работает. Обновись
  • 2 Апреля 2014 10:10
    deonisii185
    спасибо
  • 9 Июля 2016 01:48
    ira_nagornaya
    В Safari не работает((
^ Наверх ^