Как применить CSS-анимацию к маске SVG в Firefox? - PullRequest
1 голос
/ 09 апреля 2019

Я пытаюсь применить анимацию CSS к маске SVG.Хотя он отлично работает в Chrome (v. 73), я не могу заставить его работать в Firefox (v. 66).

Я не могу понять, почему мой текущий пример (см. Ниже) не подходитработа с Firefox

Примечание: согласно Могу ли я использовать , Firefox 66 не требует какого-либо префикса для transform для работы.Я планирую добавить их для поддержки более старых версий, но это не решит мою текущую проблему.

Вот небольшой пример моей проблемы: (HTML-идентификаторы были добавлены для именования объектов в моих объяснениях)

.canvas {
  border: solid 1px lime;
  background: lightblue;
}

.animated {
  transform-origin: center center;
  animation: myAnimation 1s ease forwards;
}

@keyframes myAnimation {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(0.8);
  }
}
<html>

<head>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <center>
    <div>
      <svg class="canvas" viewBox="0 0 100 100" width="150px" height="150px">

          <defs>
            <mask id="gmask" fill="white">
              <!-- Mask is defined here as a black circle in a white background -->
              <rect x="0" y="0" width="100" height="100" fill="white" />
              <circle id="maskCircle" class="animated" cx="50" cy="50" r="25" fill="black" />
            </mask>
          </defs>

          <!-- Pink circle is animated in both browsers -->
          <circle id="testCircle" class="animated" cx="50" cy="50" r="50" fill="pink" />

          <circle id="outerCircle" class="outer" cx="50" cy="50" r="25" mask="url(#gmask)" />
        </svg>
    </div>
  </center>
</body>

</html>

Я пытаюсь transform: scale круг maskCircle размера 25 от 0 до 0.8, чтобы он создавал форму пончика при применениив качестве маски для outerCircle (также размером 25).

В Chrome я могу получить ожидаемый вывод view в Chrome ;в то время как в Firefox анимация не применяется, поэтому круг маски остается в полном размере (25) и полностью скрывает outerCircle вид в Firefox .

(ну, почти полностью скрыть это, так как я вижу небольшую линию, где должен быть круг, но он отображается даже без анимации, поэтому я считаю, что это маска / круг, не отображаемая с точно таким же размером и не относящаяся к моей проблеме).

В качестве теста я применил ту же анимацию к простому объекту svg (testCircle, розовый круг), и он отлично работает.что заставляет меня думать, что проблема связана с масками.

Полагаю, анимация маски довольно распространена и должна быть возможной, поэтому я предполагаю, что я делаю что-то не так, с Chrome все в порядке, но не с Firefox.

Есть идеи, как я могу заставить их работать на обоих?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Как сказал Роберт, лучше использовать маски SVG, которые работают во всех современных браузерах.

Вместо анимации scale () я использовал анимацию радиусов круга. Это проще, потому что вам не нужно беспокоиться о расположении кругов после увеличения.

У вас сложная форма анимации, поэтому на первом этапе перед черным кольцом я применил комбинацию анимации маски.

<mask id="gmask" fill="white">
 <circle id="maskCircle" class="animated" cx="50" cy="50" r="0" fill="black" >
  <animate id="an1" attributeName="r"  dur="0.8s" values="0;20" fill="freeze" />
 </circle>
</mask>

и вне кольца анимация радиуса круга

<circle id="testCircle"  cx="50" cy="50" r="25" fill="pink"  >
      <animate attributeName="r" begin="an1.end" dur="0.2s" from="25" to="40" 
         fill="freeze"/>
</circle>   

Ниже приведен готовый код.

.canvas {
  border: solid 1px lime;
  background: lightblue;
<html>

<head>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>
  <center>
    <div>
      <svg class="canvas" viewBox="0 0 100 100" width="150px" height="150px">

          <defs>
            <mask id="gmask" fill="white">
              <!-- Mask is defined here as a black circle in a white background -->
              <rect x="0" y="0" width="100" height="100" fill="white" /> 
              <circle id="maskCircle" class="animated" cx="50" cy="50" r="0" fill="black" >
			    <animate id="an1" attributeName="r"  dur="0.8s" values="0;20" fill="freeze" />
			  </circle>	
            </mask>
          </defs>

          <!-- Pink circle is animated in both browsers --> 
		  <circle id="testCircle"  cx="50" cy="50" r="25" fill="pink"  >
            <animate attributeName="r" begin="an1.end" dur="0.2s" from="25" to="40" fill="freeze"/>
			</circle>		  
		  <circle id="outerCircle" class="outer" cx="50" cy="50" r="25"  mask="url(#gmask)"/>
          

          
        </svg>
    </div>
  </center>
</body>

</html>
1 голос
/ 09 апреля 2019

Вот как это можно сделать, используя SMIL:

.center{margin:0 auto;width:150px;}

.canvas {
  border: solid 1px lime;
  background: lightblue;
}
<div class="center">
    <div>
      <svg class="canvas" viewBox="-50 -50 100 100" width="150px" height="150px">

          <defs>
            <mask id="gmask" fill="white">
              <!-- Mask is defined here as a black circle in a white background -->
              <rect x="-50" y="-50" width="100" height="100" fill="white" />
              <circle id="maskCircle" class="animated"  r="25" fill="black" >
                <animateTransform 
    	             attributeType="XML" 
                   attributeName="transform" 
                   type="scale"
                   values="0;.8"
                   calcMode="spline"
                   keySplines="0.4 0 0.2 1"
                   dur="1s" 
                   fill="freeze"
                    />	
              </circle>
            </mask>
          </defs>

          <!-- Pink circle is animated in both browsers -->
        <circle id="testCircle" class="animated"  r="50" fill="pink">
          <animateTransform 
    	             attributeType="XML" 
                   attributeName="transform" 
                   type="scale"
                   values="0;.8"
                   calcMode="spline"
                   keySplines="0.4 0 0.2 1"
                   dur="1s" 
                   fill="freeze"
                    />	
        </circle>

          <circle id="outerCircle" class="outer"  r="25" mask="url(#gmask)" />
        </svg>
    </div>
  </div>

Я использую calcMode="spline" keySplines="0.4 0 0.2 1" вместо замедления.

См. Это: SVG SMIL animateTransform замедление

Я использую fill="freeze" вместо CSS forwards.Надеюсь, это поможет.

...