Comments 6
А почему вы решили отказаться от стандартной практики рисования линий через свойства stroke-dasharray
и stroke-dashoffset
?
Когда у нас линия является линией - все же становится проще. У нас полный контроль над происходящим - доступны любые формы, можно сделать скругленные красивые концы линий, мы естественным образом контролируем линейную скорость рисования, можем легко с ней играться в явном виде, мы избавлены от этих проблем с округлениями радиусов наложенных элементов - толщина линий не меняется случайным образом в углах, и, понятное дело, мы по умолчанию имеем плавные движения - никакие костыли с бесконечно длинными keyframes не нужны. Ваша задача - это просто частный случай такого рисования.
Спасибо за комментарий.
Первоначально про stroke-dasharray
и stroke-dashoffset
. Не использовал только потому что не знал про такой способ (ещё не доводилось работать с svg анимацией), а при запросе во всемирную сеть "как анимировать границу блока" множество сайтов предложило вариант решения через псевдоэлементы, в частности тот, на который я давал ссылку. Но сейчас, изучив ваше предложение, действительно такую границу, скорее всего, лучше делать через svg анимацию.
А по поводу статьи в целом, она всё же не про конкретную реализацию "бегущей" границы, а про css анимацию с помощью styled components. Просто рассказывать было проще на примере. То есть тут про избегание настройки анимации через обращение к элементам по средствам JS. То есть про то, что можно записать анимацию keyframes через переменные, используя CSS-in-JS, и она будет создаваться при новом рендеринге на основе входных данных.
Даже если использовать stroke-dasharray
и stroke-dashoffset можно применить предложенный подход, и составить ключевые кадры на основе переменных для них, и избежать использования JS.
Суть не в анимации границы, а в избегании обращения к элементам через JS. То есть, если мы вдруг захотим, чтобы в компонент можно было бы передать пропс с цветом цифры, причем так, что можно задать цвет счетчика в момент счета и по завершению, вариантов реализации всего несколько (если не ошибаюсь):
Через JS обращаться к элементу и менять его цвет через style.
Через JS вешать на элементы класс с соответствующим цветом.
И я предлагаю третий вариант, без необходимости обращении к элементу через JS
Справедливости ради стоит сказать, что ваш код по сути занимается вариантом №2. Раз в секунду навешивает новые классы с новыми стилями. Тут, наверное, нужно говорить не о принципиальной позиции "дергать элемент из JS, или не дергать", потому что дергать придется в любом случае, а о частоте дергания. Мы можем все промежуточные значения в анимации рассчитывать скриптом и дергать элементы 60 раз в секунду, а можем рассчитывать какие-то точки отсчета и создавать keyframes на их основе, дергая элементы по мере необходимости. Тут можно передавать нужные значения в мир CSS через custom properties и их использовать в keyframes, или можно взять Web Animations API, если уж хочется прямо генерировать keyframes в скриптах. Получится почти то же самое, что и вы придумали с генерированием фреймов, только нативное, без завязки на экосистему реакта.
Зачем я предложил этот "третий" вариант, и вообще решил, что его можно выделить?
Скорее всего просто потому что сам хотел избежать обращение к элементу через JS, потому что читал, что css анимация лучше, чем менять стили через JS, и потому что в React не хотел писать весь необходимый JS с обращением к элементам.
Но основная причина в том, что такой метод точно есть (у меня же заработало), а в интернете его описание не нашел. Поэтому решил что это прекрасная возможность попробовать себя в написании статей).
А вопрос, что лучше в плане производительности, мне интересен, но до его изучения ещё не добрался.
Если цель создания вашей анимации - показать именно оставшийся процент, то она в вашей реализации в принципе не будет работать, так как угол вырезает неодинаковые по длине куски периметра из прямоугольника для одного и того же значения угла при разном повороте. На окружности будет работать.
классная статья, спасибо
React + Styled Components — идеальная анимация. Параметризованная анимация