Змеиная анимация границы

Я пытался создать анимацию границы, которая выглядела бы как на прикрепленном изображении. Таким образом, яркая синяя линия будет вращаться вокруг прямоугольника. Линия также должна быть 3 пикселя, тогда как фактическая граница составляет 1 пиксель. Я попробовал несколько решений, которые нашел на Codepen, и попытался заставить их работать в моем случае. Но ни одно из решений CSS не сработало.

Я также попробовал несколько других идей, например, иметь 4 различных диапазона с абсолютным позиционированием, и каждый диапазон имеет элемент «до», который будет анимироваться в соответствии с положением элемента предварительного просмотра. Но это был просто беспорядок (и тоже не работал).

Кажется, что-то подобное невозможно с чистым CSS? Я пытался сделать это уже почти 2 дня, и ни одно из решений не сработало так, как ожидалось. Кто-нибудь делал что-то подобное раньше? Нужно ли мне сделать это анимированным SVG, чтобы работать? Буду признателен за любую оказанную помощь.

возможно, это может вам помочь: stackoverflow.com/a/48695388/8620333

Temani Afif 14.12.2020 16:42

также это: stackoverflow.com/a/56577095/8620333

Temani Afif 14.12.2020 16:44

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

Gershom Maes 14.12.2020 20:15
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
3
1 170
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку граница состоит ровно из двух отдельных отрезков, ::before и ::after может быть достаточно, чтобы добиться цели!

В целом это вопрос возни с @keyframes. В следующем примере показано:

  • крайний слева: только ::before, показан элемент "голова"
  • посередине: только ::after, показан элемент «хвост»
  • крайний справа: оба псевдоэлемента; это окончательный результат

body { background-color: #000000; }
.ex1, .ex2, .ex3 {
  display: inline-block;
  width: 150px; height: 150px;
  margin: 0 20px;
}

.ex1.snake-border::after { content: none; }
.ex2.snake-border::before { content: none; }

/* snake-border stuff: */
@keyframes snake-border-head {
  
  /*
  The snake's "head" stretches across a side of its container.
  The moment this head hits a corner, it instantly begins to
  stretch across the next side. (This is why some keyframe
  moments are repeated, to create these instantaneous jumps)
  */
  
  90% { left: 0; top: 0; width: 0; height: 40%; }
  90% { left: 0; top: 0; width: 0; height: 0; }
  100% { left: 0; top: 0; width: 40%; height: 0; } 0% { left: 0; top: 0; width: 40%; height: 0; }
  
  15% { left: 60%; top: 0; width: 40%; height: 0; }
  15% { left: 100%; top: 0; width: 0; height: 0; }
  25% { left: 100%; top: 0; width: 0; height: 40%; }
  
  40% { left: 100%; top: 60%; width: 0; height: 40%; }
  40% { left: 100%; top: 100%; width: 0; height: 0; }
  50% { left: 60%; top: 100%; width: 40%; height: 0; }
  
  65% { left: 0; top: 100%; width: 40%; height: 0; }
  65% { left: 0; top: 100%; width: 0; height: 0; }
  75% { left: 0; top: 60%; width: 0; height: 40%; }
  
}
@keyframes snake-border-tail {
  
  /*
  The "tail" of the snake is at full length when the head is at 0
  length, and vice versa. The tail always at a 90 degree angle
  from the head.
  */

  90% { top: 0%; height: 40%; }
  100% { left: 0; top: 0; width: 0; height: 0; } 0% { left: 0; top: 0; width: 0; height: 0; }
  
  15% { width: 40%; }
  25% { left: 100%; top: 0; width: 0; height: 0; }
  
  40% { height: 40%; }
  50% { left: 100%; top: 100%; width: 0; height: 0; }
  
  65% { left: 0%; width: 40%; }
  75% { left: 0; top: 100%; width: 0; height: 0; }
  
}

.snake-border {
  position: relative;
  box-shadow: inset 0 0 0 1px #00a0ff;
}
.snake-border::before, .snake-border::after {
  content: '';
  display: block;
  position: absolute;
  outline: 3px solid #00a0ff;
  animation-duration: 6s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.snake-border::before { animation-name: snake-border-head; }
.snake-border::after { animation-name: snake-border-tail; }
<div class = "ex1 snake-border"></div>
<div class = "ex2 snake-border"></div>
<div class = "ex3 snake-border"></div>

Я сделал это, используя квадратные контейнеры и предположив, что общая длина змеи составляет 40% длины стороны квадрата. Если вы хотите использовать прямоугольные контейнеры или змейку абсолютной длины, перемещающуюся по контейнеру с динамическими размерами, вам придется возиться со значениями.

Другие вопросы по теме