Перевод маски SVG отстает в браузерах Chromium

Я автор коллекции анимированных SVG тема-переключатели. Я заметил, что все, что связано с переводом маски, чрезвычайно изменчиво в браузерах хрома, но прекрасно работает в Firefox.

Речь идет о переключателях Классический и Расширять.

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

Любая помощь в решении этой проблемы будет принята с благодарностью. Я нашел аналогичную проблему с Fire Fox, описанную здесь, но не полностью понял причину выработанного решения.

.theme-toggle {
  font-size: 10rem;
}
<link href = "https://cdn.jsdelivr.net/npm/[email protected]/css/classic.min.css" rel = "stylesheet"/>
<label class = "theme-toggle">
  <input type = "checkbox" />
  <span class = "theme-toggle-sr">Toggle theme</span>
  <svg
    xmlns = "http://www.w3.org/2000/svg"
    width = "1em"
    height = "1em"
    fill = "currentColor"
    stroke-linecap = "round"
    class = "theme-toggle__classic"
    viewBox = "0 0 32 32"
  >
    <mask id = "theme-toggle__classic__cutout" color = "#000">
      <path fill = "#fff" d = "M0 0h32v32H0z" />
      <circle cx = "34" cy = "2" r = "8" />
    </mask>
    <circle
      cx = "16"
      cy = "16"
      r = "9.34"
      mask = "url(#theme-toggle__classic__cutout)"
    />
    <g
      stroke = "currentColor"
      class = "theme-toggle__classic__sun-rays"
      mask = "url(#theme-toggle__classic__cutout)"
    >
      <path d = "M16 5.5v-4" />
      <path d = "M16 30.5v-4" />
      <path d = "M1.5 16h4" />
      <path d = "M26.5 16h4" />
      <path d = "m23.4 8.6 2.8-2.8" />
      <path d = "m5.7 26.3 2.9-2.9" />
      <path d = "m5.8 5.8 2.8 2.8" />
      <path d = "m23.4 23.4 2.9 2.9" />
    </g>
  </svg>
</label>

Извините, я понятия не имею, как это исправить. Я просто хочу похвалить вас за этот замечательный проект. Отличная работа!

chrwahl 18.03.2022 21:08

Спасибо, это мой первый проект с открытым исходным кодом, так что это действительно много значит ?

Alfie Jones 19.03.2022 00:08
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в 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. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
2
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это, по крайней мере, улучшает производительность в Chromium. Я сделал три изменения:

  1. заменить маску на clip-path
  2. применить clip-path только один раз к родительской группе, охватывающей как круг, так и лучи
  3. Это имело значение: не переходить transform, а напрямую d данные пути. Как для Chrome (99), так и для Firefox (98) теперь вы можете написать синтаксис CSS d: path('...') и анимировать данные пути. Это еще не работает с Safari.

.theme-toggle.theme-toggle--reversed .theme-toggle__classic {
    transform: scale(-1,1)
}

.theme-toggle {
    --theme-toggle__classic--duration: 750ms
}

.theme-toggle__classic * {
    transition-property: opacity,transform,d;
    transition-timing-function: cubic-bezier(0,0,0.15,1.25);
    transform-origin: center;
    transition-duration: var(--theme-toggle__classic--duration);
    transition-delay: calc(var(--theme-toggle__classic--duration) / 5);
}

.theme-toggle__classiC#theme-toggle__classic__cutout path {
    transition-delay: 0s;
    d: path('M0-10h34v4a8 8 0 108 8h1v32h-43z');
}

.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic .theme-toggle__classic__sun-rays *,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic .theme-toggle__classic__sun-rays * {
    transform: scale(.5) rotate(45deg);
    opacity: 0;
    transition-delay: 0s
}

.theme-toggle input[type=checkbox]:checked~.theme-toggle__classiC#theme-toggle__classic__cutout path,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classiC#theme-toggle__classic__cutout path {
    d: path('M-11 0h34v4a8 8 0 108 8h1v32h-43z');
    transition-delay: calc(var(--theme-toggle__classic--duration) / 5)
}

button.theme-toggle,label.theme-toggle {
    border: none;
    background: 0 0;
    cursor: pointer
}

button.theme-toggle input[type=checkbox],label.theme-toggle input[type=checkbox] {
    display: none
}

button.theme-toggle .theme-toggle-sr,label.theme-toggle .theme-toggle-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    white-space: nowrap;
    border-width: 0
}

.theme-toggle {
  font-size: 10rem;
}
<label class = "theme-toggle">
  <input type = "checkbox" />
  <span class = "theme-toggle-sr">Toggle theme</span>
  <svg
    xmlns = "http://www.w3.org/2000/svg"
    width = "1em"
    height = "1em"
    fill = "currentColor"
    stroke-linecap = "round"
    class = "theme-toggle__classic"
    viewBox = "0 0 32 32"
  >
    <clipPath id = "theme-toggle__classic__cutout">
      <path />
    </clipPath>
    <g clip-path = "url(#theme-toggle__classic__cutout)">
      <circle cx = "16" cy = "16" r = "9.34" />
      <g
        stroke = "currentColor"
        class = "theme-toggle__classic__sun-rays"
      >
        <path d = "M16 5.5v-4" />
        <path d = "M16 30.5v-4" />
        <path d = "M1.5 16h4" />
        <path d = "M26.5 16h4" />
        <path d = "m23.4 8.6 2.8-2.8" />
        <path d = "m5.7 26.3 2.9-2.9" />
        <path d = "m5.8 5.8 2.8 2.8" />
        <path d = "m23.4 23.4 2.9 2.9" />
      </g>
    </g>
  </svg>
</label>

Так что этот метод сработал потрясающе и устранил проблему с хромом. Он не поддерживается в сафари, но, добавив запрос @supports, я смог по-прежнему использовать переводы в браузерах, которые не поддерживают прямое изменение данных пути. Спасибо за вашу помощь

Alfie Jones 21.03.2022 16:50

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