【问题标题】:How to apply CSS animation to a SVG mask in Firefox?如何在 Firefox 中将 CSS 动画应用于 SVG 蒙版?
【发布时间】:2019-04-10 00:24:25
【问题描述】:

我正在尝试将 css 动画应用于 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 的圆圈 maskCircle0 转换为 0.8,因此当它用作 outerCircle 的蒙版时会创建一个甜甜圈形状(同样大小为 25) .

在 Chrome 上,我可以得到预期的输出 view in Chrome ;而在 Firefox 中,动画未应用,因此蒙版圈保持原样 (25) 并完全隐藏 outerCircle view in Firefox

(嗯,几乎完全隐藏它,因为我可以看到圆圈应该在的地方有一条细线,但即使没有动画它也会显示,所以我相信这是未渲染的蒙版/圆圈大小完全相同,与我的问题无关)。

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

我认为动画蒙版很常见并且应该是可能的,所以我的猜测是我做错了 chrome 可以使用但不是 Firefox。

知道如何让它对两者都有效吗?

【问题讨论】:

  • 如您所见,Firefox 中的掩码不支持 CSS 动画。虽然支持 SMIL,但如果您使用它,它将在 Firefox 和 Chrome 中工作。

标签: firefox svg css-transforms


【解决方案1】:

正如 Robert 所说,最好使用适用于所有现代浏览器的 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>

【讨论】:

    【解决方案2】:

    这就是使用 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。希望对你有帮助。

    【讨论】:

    • 几乎同时:)
    猜你喜欢
    • 2017-10-28
    • 2015-04-25
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 2020-11-09
    • 2016-01-16
    • 2014-11-13
    相关资源
    最近更新 更多