Почему путь SVG размывается, когда я использую масштабирование?

#html #css #google-chrome #svg #css-animations

Вопрос:

У меня на сайте есть SVG с анимированными глазами. Глаза имеют анимацию мигания, сделанную с transform: scale() помощью . Когда я сейчас открываю Chrome и глаза моргают, путь глаз иногда становится размытым. Это часто случается, когда я масштабирую сайт до 90%, но это не соответствует действительности. Я также попытался добавить translateZ(0) и backface-visibility: hidden; , но ничего не помогло.

Могу ли я как-то решить эту проблему?

Поскольку это происходит не последовательно, я не знаю, покажет ли этот фрагмент мою проблему. В качестве альтернативы я сделал JSFiddle: https://jsfiddle.net/qnwj8uLm/

 .info-eyes {
    animation-name: info-eyes;
    animation-duration: 6s;
    animation-iteration-count: infinite;
    transform: scale(1) translateZ(0);
    transform-origin: 0% 75%;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    -webkit-transform: translateZ(0) scale(1, 1);
}
  
 
  .info-iris {
    animation-name: info-iris;
    animation-duration: 6s;
    animation-iteration-count: infinite;
  }

  @keyframes info-eyes {
    0%   {transform:scale(1, 1)   translateZ(0); }
    96%  {transform:scale(1, 1)  translateZ(0); }
    98%  {transform:scale(1, 0.1) translateZ(0); }
    100% {transform:scale(1, 1)  translateZ(0); }
  }
  
  @keyframes info-iris {
    0%   {transform: translate(0%, 0%); opacity: 100%;; }
    25%  {transform: translate(0%, 8%); opacity: 100%;} 
    50%  {transform: translate(8%, 8%); opacity: 100%;}
    75%  {transform: translate(8%, 8%); opacity: 100%;}
    96%  {transform: translate(0%, 0%); opacity: 100%;}
    98%  {transform: translate(0%, 0%); opacity: 0%;}
    100% {transform: translate(0%, 0%); opacity: 100%;}
  }
   
 <body>
  <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="81.7" height="75.3" viewBox="0 0 81.7 75.3">
    <defs>
      <style>
        .a {
          fill: none;
        }

        .b {
          clip-path: url(#a);
        }

        .h {
          fill: #fff;
        }

      </style>
      <clipPath id="a">
        <rect class="a" width="81.7" height="75.3" />
      </clipPath>
    </defs>
    <g transform="translate(40.85 37.65)">
      <g class="b" transform="translate(-40.85 -37.65)">
        <path class="info-eyes" d="M34.8,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="info-eyes" d="M60.7,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="h info-iris" d="M25.9,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
        <path class="h info-iris" d="M51.6,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
      </g>
    </g>
  </svg>
</body> 

Комментарии:

1. По крайней мере, в Firefox я не вижу размытия. Но вы можете попробовать другой вид анимации, используя библиотеку js, например anime.js или GSAP. Или, может быть, попробуйте родную анимацию SMIL.

Ответ №1:

Проблема, скорее всего, связана с оптимизацией браузера. Есть некоторые возможные решения, например will-change: transform , но в моем браузере это не работает в вашем примере. Хакерский способ заставить браузер перерисовать-это добавить transform: translateZ(0) сразу после масштабирования, что портит рисунок:

 .info-eyes {
    animation-name: info-eyes;
    animation-duration: 6s;
    animation-iteration-count: infinite;
    
    transform: scale(1) translateZ(0);
    transform-origin: 0% 75%;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    -webkit-transform: translateZ(0) scale(1, 1);
}
  
 
  .info-iris {
    animation-name: info-iris;
    animation-duration: 6s;
    animation-iteration-count: infinite;
  }

  @keyframes info-eyes {
    0%   {transform:scale(1, 1)   translateZ(0); }
    96%  {transform:scale(1, 1)  translateZ(0); }
    98%  {transform:scale(1, 0.1) translateZ(0); }
    98.001%  {transform: translateZ(0); }
    100% {transform:scale(1, 1)  translateZ(0); }
  }
  
  @keyframes info-iris {
    0%   {transform: translate(0%, 0%); opacity: 100%;; }
    25%  {transform: translate(0%, 8%); opacity: 100%;} 
    50%  {transform: translate(8%, 8%); opacity: 100%;}
    75%  {transform: translate(8%, 8%); opacity: 100%;}
    96%  {transform: translate(0%, 0%); opacity: 100%;}
    98%  {transform: translate(0%, 0%); opacity: 0%;}
    100% {transform: translate(0%, 0%); opacity: 100%;}
  } 
 <body>
  <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="81.7" height="75.3" viewBox="0 0 81.7 75.3">
    <defs>
      <style>
        .a {
          fill: none;
        }

        .b {
          clip-path: url(#a);
        }

        .h {
          fill: #fff;
        }

      </style>
      <clipPath id="a">
        <rect class="a" width="81.7" height="75.3" />
      </clipPath>
    </defs>
    <g transform="translate(40.85 37.65)">
      <g class="b" transform="translate(-40.85 -37.65)">
        <path class="info-eyes" d="M34.8,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="info-eyes" d="M60.7,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="h info-iris" d="M25.9,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
        <path class="h info-iris" d="M51.6,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
      </g>
    </g>
  </svg>
</body> 

Ответ №2:

Я нашел решение своей проблемы. Я изменил ключевой кадр мигания с transform:scale(1, 0.1) на transform:scale(1, 0.2) , и теперь анимация работает нормально.

Отрывок:

 .info-eyes {
    animation-name: info-eyes;
    animation-duration: 6s;
    animation-iteration-count: infinite;
    transform-origin: 0% 75%;
}
  
 
  .info-iris {
    animation-name: info-iris;
    animation-duration: 6s;
    animation-iteration-count: infinite;
  }

  @keyframes info-eyes {
    0%   {transform:scale(1, 1) }
    96%  {transform:scale(1, 1) }
    98%  {transform:scale(1, 0.2) }
    100% {transform:scale(1, 1)  }
    
  }
  
  @keyframes info-iris {
    0%   {transform: translate(0%, 0%); opacity: 100%;; }
    25%  {transform: translate(0%, 8%); opacity: 100%;} 
    50%  {transform: translate(8%, 8%); opacity: 100%;}
    75%  {transform: translate(8%, 8%); opacity: 100%;}
    96%  {transform: translate(0%, 0%); opacity: 100%;}
    98%  {transform: translate(0%, 0%); opacity: 0%;}
    100% {transform: translate(0%, 0%); opacity: 100%;}
  }
   
 <body>
  <svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="81.7" height="75.3" viewBox="0 0 81.7 75.3">
    <defs>
      <style>
        .a {
          fill: none;
        }

        .b {
          clip-path: url(#a);
        }

        .h {
          fill: #fff;
        }

      </style>
      <clipPath id="a">
        <rect class="a" width="81.7" height="75.3" />
      </clipPath>
    </defs>
    <g transform="translate(40.85 37.65)">
      <g class="b" transform="translate(-40.85 -37.65)">
        <path class="info-eyes" d="M34.8,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="info-eyes" d="M60.7,52.7a7,7,0,1,1-7-7,7,7,0,0,1,7,7" />
        <path class="h info-iris" d="M25.9,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
        <path class="h info-iris" d="M51.6,50.6c0-2-2.5-2.4-2.5,0s2.5,2,2.5,0" />
      </g>
    </g>
  </svg>
</body>