Добро пожаловать на форум!
Новые сообщения Участники Правила форума Поиск RSS
Статистика Форума
Последние обновленные темы Самые популярные темы Самые активные пользователи Новые участники
Болт (3758)
XemorDio (2722)
Skyline (2698)
Strelok41 (2176)
Таурус [21.08.2017]
Nikita123 [21.08.2017]
123451 [20.08.2017]
timurf4 [20.08.2017]
Denimo [20.08.2017]
Страница 1 из 11
Форум » Web-раздел » uCoz » Эффект неисправного монитора для текста, картинок и SVG
Эффект неисправного монитора для текста, картинок и SVG
Бармен Дата: Воскресенье, 30.10.2016, 16:18 | Сообщение # 1
«Программист»
Группа: Модераторы
Сообщений: 291
Награды: 6 Репутация: 70
Статус: Offline
Эффект Glitch Лукаса Беббера выглядит очень круто — как будто вы смотрите на текст на старом мониторе, который слишком часто роняли на пол и у него «плавает» вертикальная синхронизация и сведение.

Реализация этого эффекта на CSS выглядит вполне убедительно. Мне пришлось немного поломать голову, чтобы выяснить, как он работает, и теперь я хочу объяснить это вам. Кроме того, я воспроизвёл этот эффект не только для текста, но и для растровых изображений и SVG, а так же написал несколько примесей Sass, чтобы облегчить работу с ним.


Три копии текста

HTML для этого примера выглядит просто:

Код
<div class="glitch" data-text="GLITCH">GLITCH</div>

С помощью псевдоэлементов создаются две дополнительные копии основного элемента, которыми можно управлять индивидуально:

Код
.glitch {
  position: relative;
}
.glitch::before,
.glitch::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Все три копии текста расположены друг над другом:


Изменяем копии

Каждая из дополнительных копий идентична оригиналу за исключением того, что:

[-] они смещены влево или вправо;
[-] У них есть цветной ореол, созданный с помощью text-shadow.

Именно смещение и ореол служат основой для эффекта неисправного монитора.

Код
.glitch::before {
  /* ... всё, что нужно, чтобы сделать слой идентичным оригиналу */

  /* отличия от оригинала */
  left: 2px;
  text-shadow: -1px 0 red;
  
  /* Важно: непрозрачный фон закрывает предыдущий слой */
  background: black;
}
.glitch::after {
  /* ... всё, что нужно, чтобы сделать слой идентичным оригиналу */

  /* отличия от оригинала */
  left: -2px;
  text-shadow: -1px 0 blue;
  
  /* Важно: непрозрачный фон закрывает предыдущий слой */
  background: black;
}

Теперь наши три копии выглядят так:


Обрезаем копии

Пока что нам видна только самая верхняя из трёх копий. Скорее всего, это версия ::after, если только вы не меняли z-index. Но это не важно, так как мы будем попеременно показывать части всех трёх копий с помощью свойства clip. В данный момент это свойство уже считается устаревшим, его должно заменить clip-path, но на момент написания статьи именно свойство clip работало лучше. Конечно, со временем это изменится, так что нужно иногда поглядывать на ситуацию. В случае чего, их легко будет поменять, например, с помощью Autoprefixer.

У clip довольно странный синтаксис. Требуются четыре значения, логично было бы предположить, что это координаты верхнего левого угла и длина с шириной, или координаты верхнего левого и нижнего правого углов, но вместо этого числа означают отступы, как в свойствах margin или padding (top/right/bottom/left).

Код
.glitch::before {
  clip: rect(44px, 450px, 56px, 0);
  /*
    Получился прямоугольник с верхним левым углом 0, 44px
    и нижним правым 450px, 56px
  */
}

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


Анимируем обрезку

Для свойства clip можно использовать анимации CSS, меняя положение обрезающего прямоугольника. Вот пример такой анимации:

Код
@keyframes glitch-anim {
  0% {
    clip: rect(70px, 450px, 76px, 0);
  }
  20% {
    clip: rect(29px, 450px, 16px, 0);
  }
  40% {
    clip: rect(76px, 450px, 3px, 0);
  }
  60% {
    clip: rect(42px, 450px, 78px, 0);
  }
  80% {
    clip: rect(15px, 450px, 13px, 0);
  }
  100% {
    clip: rect(53px, 450px, 5px, 0);
  }
}

Обратите внимание, что левый и правый край остаются неизменными, меняются только верхний и нижний край. И эти значения выбраны совершенно произвольно. С помощью Sass вполне можно генерировать их случайным образом:

Код
@keyframes glitch-anim {
  $steps: 10;
  @for $i from 0 through $steps {
    #{percentage($i*(1/$steps))} {
      clip: rect(random(100)+px, 9999px, random(100)+px, 0);
    }
  }
}

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

Код
.glitch::before {
  ...

  animation: glitch-anim-1 2s infinite linear alternate-reverse;
}

.glitch::after {
  ...

  animation: glitch-anim-2 2s infinite linear alternate-reverse;
}

В этом месте мы можем отрегулировать скорость анимации зациклить её. Эффект готов:


Примеси Sass

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

Код
.example-one {
  font-size: 100px;
  @include textGlitch("example-one", 17, white, black, red, blue, 450, 115);
}

Вот что у меня получилось:

Код
/*
  (TEXT) PARAMS
  =================
  1. Namespace
  2. Intensity
  3. Text color
  4. Background color (flat)
  5. Highlight #1 color
  6. Highlight #2 color
  7. Width (px)
  8. Height (px)
*/

@mixin textGlitch($name, $intensity, $textColor, $background, $highlightColor1, $highlightColor2, $width, $height) {
  
  color: $textColor;
  position: relative;
  $steps: $intensity;
  
  // Ensure the @keyframes are generated at the root level
  @at-root {
    // We need two different ones
    @for $i from 1 through 2 {
      @keyframes #{$name}-anim-#{$i} {
        @for $i from 0 through $steps {
          #{percentage($i*(1/$steps))} {
            clip: rect(
              random($height)+px,
              $width+px,
              random($height)+px,
              0
            );
          }
        }
      }
    }
  }
  &:before,
  &:after {
    content: attr(data-text);
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    background: $background;
    clip: rect(0, 0, 0, 0);
  }
  &:after {
    left: 2px;
    text-shadow: -1px 0 $highlightColor1;
    animation: #{$name}-anim-1 2s infinite linear alternate-reverse;
  }
  &:before {
    left: -2px;
    text-shadow: 2px 0 $highlightColor2;
    animation: #{$name}-anim-2 3s infinite linear alternate-reverse;
  }
  
}

Конечно, можно придумать ещё миллион способов, как реализовать эту примесь — всё зависит от того, какие параметры вы хотите настраивать, какая у вас разметка HTML и т.д.

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

Форум » Web-раздел » uCoz » Эффект неисправного монитора для текста, картинок и SVG
Страница 1 из 11
Поиск:
07:29
Обновить

Хостинг от uCoz | Design by XemorDio | MODSTALKER © 2009-2017