Переход по свойству Fill с линейным градиентом внутри SVG

Я пытаюсь добиться какого-то Степпера. Все работает хорошо, за исключением перехода на заливке.

let step = 0;
document.querySelector("button").addEventListener('click', () => {
   step++;
   document.querySelector("svg").style.fill = `url(#lg-step-${step})`
})
.stepper {
    transition-property: fill;
    transition-duration: 1s;
    transition-timing-function: ease-in-out;
}
<svg id = "test_svg" viewBox = "0 0 620 50" width = "300" height = "20" fill = "url(#lg-step-0)" stroke = "black" stroke-width = "1" class = "stepper">
    <path d = "m 71 29 h -60 c -14 0 -14 -19 0 -19 h 60 c 6 -10 19 -10 25 0 h 200 c 6 -10 19 -10 25 0 h 200 c 6 -10 19 -10 25 0 h 60 c 14 0 14 19 0 19 h -60 c -6 10 -19 10 -25 0 h -200 c -6 10 -19 10 -25 0 h -200 c -6 10 -19 10 -25 0" />
    <linearGradient id = "lg-step-0">
        <stop offset = "0%" stop-color = "blue" />
        <stop offset = "6%" stop-color = "blue" stop-opacity = "60%" />
        <stop offset = "6%" stop-color = "transparent" />
    </linearGradient>
    <linearGradient id = "lg-step-1" >
        <stop offset = "0%" stop-color = "blue" />
        <stop offset = "14%" stop-color = "blue" stop-opacity = "60%"/>
        <stop offset = "14%" stop-color = "transparent" />
    </linearGradient>
    <linearGradient id = "lg-step-2">
        <stop offset = "0%" stop-color = "blue" />
        <stop offset = "50%" stop-color = "blue" stop-opacity = "60%" />
        <stop offset = "50%" stop-color = "transparent" />
    </linearGradient>
    <linearGradient id = "lg-step-3">
        <stop offset = "0%" stop-color = "blue" />
        <stop offset = "87%" stop-color = "blue" stop-opacity = "60%" />
        <stop offset = "87%" stop-color = "transparent" />
    </linearGradient>

</svg>
<button> Next step </button>

Весь js здесь взят не из моего реального кода, а для целей тестирования на SO.

Я хотел бы добиться плавного перехода между всеми моими шагами, но, как вы можете видеть, ни один переход никогда не срабатывает. Любая помощь приветствуется.

P.S. На самом деле я работаю над Blazor, поэтому чем меньше J, тем лучше решение.

Я не малый и средний бизнес, но не думаю, что вы анимируете fill, необходимый для анимации размера/положения градиента.

Paulie_D 17.07.2024 12:31

МСП? Но хорошая идея, попробую после обеда

Symtox 17.07.2024 12:42

Эксперт по предметной области ☺ - stackoverflow.com/questions/7850915/svg-animate-gradient-sto‌​p

Paulie_D 17.07.2024 12:43

@Symtox, это может быть полезно codepen.io/chirag0456/pen/KKjVdbR

chirag solanki 17.07.2024 12:52
Улучшение производительности загрузки с помощью 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
4
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

transition может интерполировать только между числами какого-либо типа, а не между строками, и уж точно не в том случае, если это ссылки на полные поддеревья DOM.

На самом деле вы хотите интерполировать значения атрибута offset элемента <stop>. Это возможно, но не с помощью CSS. В SVG есть два типа атрибутов: атрибуты чистого XML и «атрибуты представления», где вы можете записать их как атрибуты или как свойства CSS. Только второй доступен с помощью переходов CSS.

offset относится к первой категории. Его можно анимировать, но только с помощью SMIL-анимации. Результат громоздкий, но работает.

let step = 0;
document.querySelector("button").addEventListener('click', () => {
   step++;
   document.querySelectorAll(`.lg-step-${step}`).forEach(el => {
      el.beginElement();
   })
})
<svg id = "test_svg" viewBox = "0 0 620 50" width = "300" height = "20" fill = "url(#lg-step-0)" stroke = "black" stroke-width = "1" class = "stepper">
    <path d = "m 71 29 h -60 c -14 0 -14 -19 0 -19 h 60 c 6 -10 19 -10 25 0 h 200 c 6 -10 19 -10 25 0 h 200 c 6 -10 19 -10 25 0 h 60 c 14 0 14 19 0 19 h -60 c -6 10 -19 10 -25 0 h -200 c -6 10 -19 10 -25 0 h -200 c -6 10 -19 10 -25 0" />
    <linearGradient id = "lg-step-0">
        <stop offset = "0%" stop-color = "blue" />
        <stop offset = "6%" stop-color = "blue" stop-opacity = "60%">
            <animate class = "lg-step-1" attributeName = "offset" from = ".06" to = ".14"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
            <animate class = "lg-step-2" attributeName = "offset" from = ".14" to = ".5"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
            <animate class = "lg-step-3" attributeName = "offset" from = ".5" to = ".87"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
        </stop>
        <stop offset = "6%" stop-color = "transparent">
            <animate class = "lg-step-1" attributeName = "offset" from = ".04" to = ".14"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
            <animate class = "lg-step-2" attributeName = "offset" from = ".14" to = ".50"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
            <animate class = "lg-step-3" attributeName = "offset" from = ".5" to = ".87"
                     begin = "indefinite" dur = "1s" fill = "freeze"
                     calcMode = "spline" keySplines = "0.42, 0, 0.58, 1" />
        </stop>
    </linearGradient>
</svg>
<button> Next step </button>

Когда я нажимаю Next Step, ничего не происходит, это моя машина или проблема с кодом?

Meet 17.07.2024 13:08

Протестировано с Firefox 128 в Linux. Хром 126 не работает, теперь вижу. Я догадываюсь, что это такое, попробую...

ccprog 17.07.2024 13:12

Я разочаровался, когда нажал кнопку «Далее» на Chrome lmao. Отлично работает на firefo, огромное спасибо за отправную точку!!

Symtox 17.07.2024 13:20

Работает сейчас. В Chromium нужны безразмерные значения, проценты не работают (.14 вместо 14%). Я не знал об этом баге.

ccprog 17.07.2024 13:23

Ты просто сделал мой день, еще раз спасибо

Symtox 17.07.2024 13:41

Кстати, я пытаюсь «сделать это по-своему», но откуда это begin? он даже не упоминается в MDN, есть ли у вас более надежный источник по этой теме (кроме спецификации 2 тыс. строк?)

Symtox 17.07.2024 14:15
Вот определение в спецификации. По сути, это говорит о том, что у анимации нет начальной точки на временной шкале документа. Его необходимо запустить извне вызовом API Javascript к AnimationElement.beginElement().
ccprog 17.07.2024 14:21

Это сложно, но управление временем стоит прочитать, потому что SMIL имеет больше возможностей, чем CSS-анимация/переходы. Однако обратите внимание, что wallclock-sync-value не реализован ни в одном браузере.

ccprog 17.07.2024 14:25

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