SVG-анимация, примененная с маской

Я хотел бы применить SVG-анимацию к моей кнопке загрузки.

В моей практике предполагается, что стрелка рекурсивно прокручивается вниз в красном поле.

Было бы примерно так.

Анимация по-прежнему ожидает калибровки, но основная проблема заключается в том, что mask не работает должным образом, поскольку стрелка все еще видна при выходе из красного поля.

Что пошло не так?

Я надеюсь, что это можно решить без использования JavaScript.

посмотрите это в jsfiddle

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}


.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

#fanbox-helper-quick-save-button.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id = "fanbox-helper-quick-save-button" class = "fanbox-helper-fixed-menu-button busy">
  <svg class = "fanbox-helper-svg-icon" xmlns = "http://www.w3.org/2000/svg" xmlns:xlink = "http://www.w3.org/1999/xlink" version = "1.1" id = "Capa_1" x = "0px" y = "0px" viewBox = "0 0 512 512" style = "enable-background:new 0 0 512 512;" xml:space = "preserve">
    <mask id = "fanbox-helper-quick-save-arrow-area" x = "120" width = "272" height = "440">
      <rect x = "120" width = "272" height = "440" fill = "red"></rect>
    </mask>
    
    <rect x = "120" width = "272" height = "440" fill = "red"></rect>
    
    <g id = "fanbox-helper-quick-save-arrow" mask = "#fanbox-helper-quick-save-arrow-area">
      <path class = "arrow stick" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" d = "m256,96 l0,256" stroke-width = "40"></path>
      <path class = "arrow edge left" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m256,392 l-104,-104"></path>
      <path class = "arrow edge right" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m256,392 l104,-104"></path>
    </g>
    <path class = "bowl" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

Я отредактировал ваш вопрос, добавив ваш код во фрагмент с помощью кнопки <>.

Cédric 30.07.2024 09:57
Улучшение производительности загрузки с помощью 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 страниц, которые помогут...
0
1
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы неправильно применили маску — вам нужно обернуть ссылку в функцию url() вот так

svg{
  overflow:visible;
  outline:1px solid #ccc;
}

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}


.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

#fanbox-helper-quick-save-button.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id = "fanbox-helper-quick-save-button" class = "fanbox-helper-fixed-menu-button busy">
  
  <svg class = "fanbox-helper-svg-icon" xmlns = "http://www.w3.org/2000/svg" id = "Capa_1" viewBox = "0 0 512 512">
    <mask id = "fanbox-helper-quick-save-arrow-area" >
      <rect x = "120" width = "272" height = "440" fill = "#fff"></rect>
    </mask>
    <rect x = "120" width = "272" height = "440" fill = "red"></rect>
    
    <g id = "fanbox-helper-quick-save-arrow" mask = "url(#fanbox-helper-quick-save-arrow-area)">
      <path class = "arrow stick" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" d = "m256,96 l0,256" stroke-width = "40"></path>
      <path class = "arrow edge left" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m256,392 l-104,-104"></path>
      <path class = "arrow edge right" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m256,392 l104,-104"></path>
    </g>
    <path class = "bowl" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

Кроме того, красный цвет заливки приведет к полупрозрачности. Для полностью непрозрачного рендеринга внутри прямоугольника маски вам нужно использовать «#fff» или «white».

Честно говоря, я настоятельно рекомендую вместо этого использовать clip-path, так как это более производительно (не вводит альфа-канал).

svg {
  overflow: visible;
  outline: 1px solid #ccc;
}

@keyframes arrow-slide-recursively {
  from {
    transform: translate(0%, 0%)
  }
  to {
    transform: translate(0%, 50%)
  }
}

.fanbox-helper-fixed-menu-button {
  background-color: transparent;
  cursor: pointer;
  border: medium;
  padding: 4px;
  width: 54px;
  height: 54px;
}

.fanbox-helper-fixed-menu-button.busy {
  opacity: 0.3;
  pointer-events: none;
}

.busy .arrow {
  animation: arrow-slide-recursively 2s linear infinite;
}
<button id = "fanbox-helper-quick-save-button" class = "fanbox-helper-fixed-menu-button busy">

  <svg class = "fanbox-helper-svg-icon" xmlns = "http://www.w3.org/2000/svg" id = "Capa_1" viewBox = "0 0 512 512">
    <clipPath id = "clip">
          <rect x = "120" width = "272" height = "440" fill = "red" />
    </clipPath>
    <rect x = "120" width = "272" height = "440" fill = "red"></rect>

      <g class = "fanbox-helper-quick-save-arrow" clip-path = "url(#clip)" >
        <path  class = "arrow" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" d = "M256 96v256m0 40-104-104m104 104 104-104" stroke-width = "40" />
      </g>
    <path class = "bowl" stroke = "black" stroke-linecap = "round" stroke-linejoin = "round" fill = "none" stroke-width = "40" d = "m64,312 l0,148 l384,0 l0,-148"></path>
  </svg>
</button>

Спасибо! Первый подход работает как шарм. Однако второе кажется немного неправильным. Я попробовал некоторые другие аргументы в функции inset, но обнаружил, что отсечение «прилипает» к движущейся стрелке, в то время как оно должно оставаться на месте при движении стрелки.

G_S 31.07.2024 20:46

@G_S: извини, ты прав. Я обновил второй пример, добавив правильный путь обрезки SVG, который не будет перемещаться вместе с анимацией. Кроме того, я упростил стрелку, объединив атрибуты pathdata.

herrstrietzel 31.07.2024 21:33

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