如何在Firefox中将CSS动画应用于SVG蒙版?

时间:2019-04-09 12:31:08

标签: firefox svg css-transforms

我正在尝试将CS​​S动画应用于svg蒙版。虽然它在Chrome(v。73)上可以正常工作,但我无法使其在Firefox(v。66)上运行。

我不知道为什么我当前的示例(见下文)在Firefox上无法运行

注意:根据Can I use,Firefox 66不需要任何transform前缀就可以使用。我打算添加它们以支持较早的版本,但这不能解决我当前的问题。

这是我的问题的一个小例子:(已添加HTML ID以在我的说明中命名对象)

.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的大小为25的圆圈maskCircle00.8,因此当将其作为遮罩应用于{{ 1}}(大小也为25)。

在Chrome上,我可以得到预期的输出view in Chrome;而在Firefox中则不应用动画,因此遮罩圈将保持其完整大小(25),并完全隐藏outerCircle view in Firefox

(好吧,几乎全部隐藏了它,因为我可以看到圆应该出现的细线,但是即使没有动画也可以显示出来,所以我相信这是未渲染的遮罩/圆大小完全相同,与我的问题无关。

作为测试,我将相同的动画应用于一个简单的svg对象(outerCircle,粉红色圆圈),并且效果很好。这让我觉得这个问题与口罩有关。

我认为为面具设置动画非常普遍并且应该可行,所以我的猜测是我做错了铬,但使用Firefox没问题。

有什么主意我可以使两者同时起作用吗?

2 个答案:

答案 0 :(得分:2)

正如罗伯特所说,最好在所有现代浏览器中都使用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 :(得分:1)

这是使用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 easing

我使用fill="freeze"而不是CSS forwards。希望对您有所帮助。