SVG и CSS анимация для иконки
У меня есть две иконки: одна в исходном состоянии, вторая иконка перечеркнута.
Я хочу анимировать зачеркивающую линию, но изменение dash-offset не помогает, поскольку это два разных svg.
Я смотрю на эти анимированные иконки, но все еще не могу понять волшебную часть.
Я хочу спросить: Какой должен быть переходный процесс?
Я предпочитаю использовать pure CSS, возможно ли это?
Свободный перевод вопроса SVG line cross animation for icons от участника @Mengo.
Ответы (2 шт):
Анимированные иконки по вашей ссылке довольно сложны
Но в основном то, что они делают, это скользящая прямоугольная маска справа налево, которая покрывает первую иконку и открывает вторую иконку.
Вот упрощенная версия, использующая чистый CSS, который, надеюсь, делает ее более ясной.
svg {
width: 100px;
height: 100px;
}
/* сдвигает две маски влево при наведении курсора */
svg:hover #bottom-rect,
svg:hover #top-rect
{
transition: transform 500ms;
transform: translate(-24px, 0px);
}
/* сдвигает две маски вправо, когда они не hovered */
svg #bottom-rect,
svg #top-rect {
transition: transform 500ms;
transform: translate(0px, 0px);
}
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<defs>
<mask id="bottom">
<rect id="bottom-rect" width="24" height="24" fill="white" stroke="none"/>
</mask>
<mask id="top">
<rect id="top-rect" x="24" width="24" height="24" fill="white" stroke="none"/>
</mask>
</defs>
<g mask="url(#bottom)">
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path>
<path d="M19 10v2a7 7 0 0 1-14 0v-2"></path>
<line x1="12" y1="19" x2="12" y2="23"></line>
<line x1="8" y1="23" x2="16" y2="23"></line>
</g>
<g mask="url(#top)">
<line x1="1" y1="1" x2="23" y2="23"></line>
<path d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"></path>
<path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"></path>
<line x1="12" y1="19" x2="12" y2="23"></line>
<line x1="8" y1="23" x2="16" y2="23"></line>
</g>
</svg>
Свободный перевод ответа от участника @Paul LeBeau.
Анимированные иконки по вашей ссылке довольно сложны
А если попробовать сделать анимацию иконки самостоятельно. Действительно ли это так сложно?
Например попытаться анимировать Running Infinity иконку
Создание анимации иконки по шагам:
Шаг #1. В векторном редакторе рисуем восьмерку и вычисляем полную длину контура - getTotalLength()
<style>
.container {
width:10%;
height:auto;
}
</style>
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path id="path" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke="#151515" stroke-width="10" />
</svg>
<script>
console.log('Полная длина :' + Math.round(path.getTotalLength()) +'px')
</script>
Шаг #2. Вырезаем часть контура с помощью stroke-dasharray="202.75,54.25", где 54.25 - пробел
Обратите внимание: если сложить цифры длин черты и пробела получится максимальная длина контура 257px
<style>
.container {
width:8%;
height:auto;
background:white;
}
</style>
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke-dashoffset="27" stroke-dasharray="202.75,54.25" stroke="black" stroke-width="8" />
</svg>
Шаг #3. Добавляем анимацию вращения контура с помощью stroke-dashoffset
<animate attributeName="stroke-dashoffset" values="257; 0" begin="svg1.click"
dur="1s" restart="whenNotActive" repeatCount="indefinite" />
<style>
.container {
width:8%;
height:auto;
background:white;
}
</style>
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke-dashoffset="27" stroke-dasharray="202.75,54.25" stroke="black" stroke-width="8" >
<animate attributeName="stroke-dashoffset" values="257; 0" begin="svg1.click" dur="1s" restart="whenNotActive" repeatCount="indefinite" />
</path>
</svg>
Шаг #4. Вращение иконки при наведении :hover
Добавляем в условие запуска begin="svg1.mouseenter" end="svg1.mouseleave"
<style>
.container {
width:8%;
height:auto;
background:white;
}
</style>
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" stroke-dashoffset="27" stroke-dasharray="202.75,54.25" stroke="black" stroke-width="8" >
<animate attributeName="stroke-dashoffset" values="257; 0" begin="svg1.mouseenter" end="svg1.mouseleave" dur="1s" restart="whenNotActive" repeatCount="indefinite" />
</path>
</svg>
Вариант анимации CSS
При разработке варианта анимации SVG были вычислены необходимые значения параметров атрибутов stroke-dasharray:202.75,54.25; и stroke-dashoffset
Остается их перенести в CSS правила:
.container {
width:8%;
height:auto;
background:white;
}
#eight {
fill:none;
stroke:black;
stroke-width:8;
stroke-dasharray:202.75,54.25;
stroke-dashoffset:27px;
}
#svg1:hover #eight {
fill:#dedede;
animation:move 1s infinite linear;
}
@keyframes move {
0% {stroke-dashoffset:27px;}
100% {stroke-dashoffset:257px;}
}
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path id="eight" fill="none" d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z" />
</svg>

