【问题标题】:SVG width attribute css animation in firefoxFirefox中的SVG宽度属性css动画
【发布时间】:2016-07-16 15:19:26
【问题描述】:

SVG 宽度属性 css 动画在 Firefox 中不起作用,但在 chrome 中却可以完美运行。请查看下面的 sn-p 演示。

我的代码有什么问题吗?有没有办法在属性宽度上应用动画?

svg {
  display: inline-block;
}


@-moz-keyframes glareAnim1 {
  0% {
    width: 0;
  }
  50% {
    width: 10px;
  }
  100% {
    width: 0;
  }
}
@-webkit-keyframes glareAnim1 {
  0% {
    width: 0;
  }
  50% {
    width: 10px;
  }
  100% {
    width: 0;
  }
}
@keyframes glareAnim1 {
  0% {
    width: 0;
  }
  50% {
    width: 10px;
  }
  100% {
    width: 0;
  }
}
.glare-top {
  -moz-animation: glareAnim1 2s linear infinite;
  -webkit-animation: glareAnim1 2s linear infinite;
  animation: glareAnim1 2s linear infinite;
}

@-moz-keyframes glareAnim2 {
  0% {
    width: 10px;
  }
  50% {
    width: 0;
  }
  100% {
    width: 10px;
  }
}
@-webkit-keyframes glareAnim2 {
  0% {
    width: 10px;
  }
  50% {
    width: 0;
  }
  100% {
    width: 10px;
  }
}
@keyframes glareAnim2 {
  0% {
    width: 10px;
  }
  50% {
    width: 0;
  }
  100% {
    width: 10px;
  }
}
.glare-bottom {
  -moz-animation: glareAnim2 2s linear infinite;
  -webkit-animation: glareAnim2 2s linear infinite;
  animation: glareAnim2 2s linear infinite;
}

@-moz-keyframes translateDoor {
  0% {
    -moz-transform: translate(-1px, 0);
    transform: translate(-1px, 0);
    opacity: 1;
    width: 1px;
    height: 6px;
  }
  15% {
    width: 4px;
  }
  50% {
    -moz-transform: translate(16px, 0);
    transform: translate(16px, 0);
    opacity: 1;
    width: 2px;
  }
  51% {
    opacity: 0;
  }
  100% {
    -moz-transform: translateX(-10px);
    transform: translateX(-10px);
    opacity: 0;
  }
}
@-webkit-keyframes translateDoor {
  0% {
    -webkit-transform: translate(-1px, 0);
    transform: translate(-1px, 0);
    opacity: 1;
    width: 1px;
    height: 6px;
  }
  15% {
    width: 4px;
  }
  50% {
    -webkit-transform: translate(16px, 0);
    transform: translate(16px, 0);
    opacity: 1;
    width: 2px;
  }
  51% {
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(-10px);
    transform: translateX(-10px);
    opacity: 0;
  }
}
@keyframes translateDoor {
  0% {
    -moz-transform: translate(-1px, 0);
    -ms-transform: translate(-1px, 0);
    -webkit-transform: translate(-1px, 0);
    transform: translate(-1px, 0);
    opacity: 1;
    width: 1px;
    height: 6px;
  }
  15% {
    width: 4px;
  }
  50% {
    -moz-transform: translate(16px, 0);
    -ms-transform: translate(16px, 0);
    -webkit-transform: translate(16px, 0);
    transform: translate(16px, 0);
    opacity: 1;
    width: 2px;
  }
  51% {
    opacity: 0;
  }
  100% {
    -moz-transform: translateX(-10px);
    -ms-transform: translateX(-10px);
    -webkit-transform: translateX(-10px);
    transform: translateX(-10px);
    opacity: 0;
  }
}
.researchDoor {
  fill: #464949;
  -moz-animation: translateDoor 5s linear infinite;
  -webkit-animation: translateDoor 5s linear infinite;
  animation: translateDoor 5s linear infinite;
}

.research0 {
  fill: #FFFFFF;
  stroke: #464949;
  stroke-width: 2;
  stroke-miterlimit: 10;
}

.research1 {
  fill: #FCBD38;
  overflow: hidden;
}

.research2 {
  fill: #464949;
}

.research3 {
  fill: none;
  stroke: #464949;
  stroke-width: 2;
  stroke-linecap: square;
  stroke-miterlimit: 10;
}
<svg version="1.1" x="0px" y="0px" viewBox="0 0 100 120" style="enable-background:new 0 0 100 120;" xml:space="preserve">

  <path id="XMLID_42_" class="research0" d="M57.9,25.5c-3-6.4-8.3-11.6-8.3-11.6c-5.1,5-8.3,11.5-8.3,11.5v5.8L57.7,32L57.9,25.5z" />
  <g id="XMLID_40_">
    <rect x="41.4" y="25.9" class="research1" width="16.3" height="11.5" />
    <path class="research2" d="M56.7,26.9v9.5H42.4v-9.5H56.7 M58.7,24.9H40.4v13.5h18.3V24.9L58.7,24.9z" />
  </g>
  <polygon id="XMLID_43_" class="research3" points="33.5,85.2 40.8,37.7 58.8,37.7 66.2,85.2 	" />
  <!--  door    -->
  <rect x="41" y="28.9" class="researchDoor" />
  <!--   left top wind  -->
  <rect x="30" class="glare-top" y="28" fill="#464949" width="14" height="2" />
  <!--   left bottom wind    -->
  <rect x="30" class="glare-bottom" y="32" fill="#464949" width="14" height="2" />
  <!--   right top wind  -->
  <rect x="62" y="28" class="glare-top" fill="#464949" width="14" height="2" />
  <!--   right bottom wind    -->
  <rect x="62" y="32" class="glare-bottom" fill="#464949" width="14" height="2" />
  <!--   
  <line id="glareLeftTop" class="research3" x1="36.6" y1="28.7" x2="32.8" y2="28.7"/>
  <line id="glareLeftBottom" class="research3" x1="36.6" y1="33.3" x2="23.8" y2="33.3"/> 
  <line id="glareTopRight" class="research3" x1="62.9" y1="28.7" x2="66.6" y2="28.7"/>
  <line id="glareTopBottom" class="research3" x1="62.9" y1="33.3" x2="75.6" y2="33.3"/>
  -->
  <line id="XMLID_2_" class="research3" x1="76.3" y1="85.3" x2="23.7" y2="85.3" />
  <line id="XMLID_64_" class="research3" x1="60.7" y1="37.7" x2="38.8" y2="37.7" />
  <line id="XMLID_70_" class="research3" x1="58.7" y1="44.3" x2="40.8" y2="44.3" />
  <line id="XMLID_79_" class="research3" x1="60.2" y1="51.7" x2="39.3" y2="51.7" />
  <line id="XMLID_80_" class="research3" x1="61.7" y1="61" x2="37.8" y2="61" />
  <line id="XMLID_90_" class="research3" x1="63.5" y1="69.3" x2="36.8" y2="69.3" />
  <g id="XMLID_49_">
    <path class="research2" d="M49.8,76.2c1.5,0,2.8,1.2,2.8,2.8v5.2H47v-5.2C47,77.4,48.2,76.2,49.8,76.2 M49.8,74.2
			c-2.6,0-4.8,2.1-4.8,4.8v7.2h9.5v-7.2C54.5,76.3,52.4,74.2,49.8,74.2L49.8,74.2z" />
  </g>
</svg>

【问题讨论】:

  • 宽度的默认值为自动,过渡只能跨数值进行动画。
  • 你能举个例子吗?
  • 在 Firefox 和 Chrome 中对我来说看起来完全一样。工作正常。
  • @Shikkediel 这个问题很老了。 5年前问过这个bug已经被firefox修复了但是我觉得回答这个问题很有趣,用`stroke-dasharray`将动画width替换为资源密集度较低的动画
  • 啊好吧,我没注意到...

标签: html css svg css-animations svg-animate


【解决方案1】:

考虑在动画中使用stroke-width 等于矩形高度的线条,而不是矩形。

stroke-dasharray 行将用于动画。

  • 0% {stroke-dasharray: 0.10;} 处为等于 10px 的动画线 该行将被隐藏

  • 在 50% {stroke-dasharray: 10,0;} 时,该行将完整显示

  • 在 100% {stroke-dasharray: 0.10;} 时,该行将再次隐藏

.glare-top {
  -webkit-animation: glareAnim1 2s linear infinite;
  stroke-dasharray:0,10;
  animation: glareAnim1 2s linear infinite;
}

@-webkit-keyframes glareAnim1 {
  0% {stroke-dasharray:0,10;}
  50% {stroke-dasharray:10,10;}
  100%{stroke-dasharray:0,10;}
}
.glare-bottom {
   -webkit-animation: glareAnim2 2s linear infinite;
  stroke-dasharray:0,10;
  animation: glareAnim2 2s linear infinite;
}
@-webkit-keyframes glareAnim2 {
  0% {stroke-dasharray:10,0;}
  50% {stroke-dasharray:0,10;}
  100%{stroke-dasharray:10,0;}
}
<svg version="1.1"  viewBox="0 0 100 120" >
<!--   left top wind  -->
      <polyline class="glare-top" points="27,28 37,28" stroke="#464949"  stroke-width="2" /> 
 <!--   left bottom wind    -->
      <polyline class="glare-bottom" points="27,33 37,33" stroke="#464949"  stroke-width="2" /> 
  </svg> 

我已缩短您的代码以显示线条和门的基本动画。

svg {
  display: inline-block;
}
.glare-top {
  -webkit-animation: glareAnim1 2s linear infinite;
  stroke-dasharray:0,10;
  animation: glareAnim1 2s linear infinite;
}

@-webkit-keyframes glareAnim1 {
  0% {stroke-dasharray:0,10;}
  50% {stroke-dasharray:10,10;}
  100%{stroke-dasharray:0,10;}
}
@keyframes glareAnim1 {
  0% {stroke-dasharray:0,10;}
  50% {stroke-dasharray:10,10;}
  100%{stroke-dasharray:0,10;}
}

.glare-bottom {
  -moz-animation: glareAnim2 2s linear infinite;
  -webkit-animation: glareAnim2 2s linear infinite;
  stroke-dasharray:0,10;
  animation: glareAnim2 2s linear infinite;
}
@-webkit-keyframes glareAnim2 {
  0% {stroke-dasharray:10,0;}
  50% {stroke-dasharray:0,10;}
  100%{stroke-dasharray:10,0;}
}
@keyframes glareAnim2 {
 0% {stroke-dasharray:10,0;}
  50% {stroke-dasharray:0,10;}
  100%{stroke-dasharray:10,0;}
}

.researchDoor {
  fill: #464949;
  stroke-dasharray:0,6;
   animation: translateDoor 5s linear infinite;
}

@keyframes translateDoor {
  0% {
    transform: translate(-1px, 0);
    opacity: 1;
    stroke-dasharray:0,6;
  }
  15% {
   stroke-dasharray:1.4,4.6;
  }
  50% {
    transform: translate(8px, 0); 
     stroke-dasharray:5,1;
    
  }
   70% {
    transform: translate(12.8px, 0); 
     stroke-dasharray:3.5,2.5;
    
  }
    
  100% {
        
    transform: translateX(16px);
    stroke-dasharray:0,6;
      }
}


.research0 {
  fill: #FFFFFF;
  stroke: #464949;
  stroke-width: 2;
  stroke-miterlimit: 10;
}

.research1 {
  fill: #FCBD38;
  overflow: hidden;
}

.research2 {
  fill: #464949;
}

.research3 {
  fill: none;
  stroke: #464949;
  stroke-width: 2;
  stroke-linecap: square;
  stroke-miterlimit: 10;
}
<svg version="1.1"  viewBox="0 0 100 120" >

  <path id="XMLID_42_" class="research0" d="M57.9,25.5c-3-6.4-8.3-11.6-8.3-11.6c-5.1,5-8.3,11.5-8.3,11.5v5.8L57.7,32L57.9,25.5z" />
  <g id="XMLID_40_">
    <rect x="41.4" y="25.9" class="research1" width="16.3" height="11.5"  />
    <path class="research2"  d="M56.7,26.9v9.5H42.4v-9.5H56.7 M58.7,24.9H40.4v13.5h18.3V24.9L58.7,24.9z" />
  </g>
  <polygon id="XMLID_43_" class="research3"  points="33.5,85.2 40.8,37.7 58.8,37.7 66.2,85.2    " />
  <!--  door    -->
   <!-- <rect x="41" y="28.9" class="researchDoor" />  -->
    <polyline class="researchDoor" points="41,32 47,32" stroke="#464949"  stroke-width="6" /> 
  <!--   left top wind  -->
      <polyline class="glare-top" points="27,28 37,28" stroke="#464949"  stroke-width="2" /> 
  <!--   right top wind  -->
   <polyline class="glare-top" points="  62,28 72,28" stroke="#464949"  stroke-width="2" />

 <!--   left bottom wind    -->
      <polyline class="glare-bottom" points="27,33 37,33" stroke="#464949"  stroke-width="2" /> 
 
 <!--   right bottom wind    -->
      <polyline class="glare-bottom" points="  62,33 72,33" stroke="#464949"  stroke-width="2" />
  
    
 
  <line id="XMLID_2_" class="research3" x1="76.3" y1="85.3" x2="23.7" y2="85.3" />
  <line id="XMLID_64_" class="research3" x1="60.7" y1="37.7" x2="38.8" y2="37.7" />
  <line id="XMLID_70_" class="research3" x1="58.7" y1="44.3" x2="40.8" y2="44.3" />
  <line id="XMLID_79_" class="research3" x1="60.2" y1="51.7" x2="39.3" y2="51.7" />
  <line id="XMLID_80_" class="research3" x1="61.7" y1="61" x2="37.8" y2="61" />
  <line id="XMLID_90_" class="research3" x1="63.5" y1="69.3" x2="36.8" y2="69.3" />
  <g id="XMLID_49_">
    <path class="research2" d="M49.8,76.2c1.5,0,2.8,1.2,2.8,2.8v5.2H47v-5.2C47,77.4,48.2,76.2,49.8,76.2 M49.8,74.2
            c-2.6,0-4.8,2.1-4.8,4.8v7.2h9.5v-7.2C54.5,76.3,52.4,74.2,49.8,74.2L49.8,74.2z" />
  </g>
</svg>

【讨论】:

    【解决方案2】:

    在 SVG 1.1 中,宽度是一个属性,不能使用 CSS 动画进行动画处理。

    在 SVG 2 规范中,宽度是一个 CSS 属性,因此可以使用 CSS 动画进行动画处理。

    Chrome 已经实现了 SVG 2 规范的这一部分,Firefox 在第一次编写这个问题时没有,但现在已经实现了。事实上,Firefox 已经有这个功能很长一段时间了。

    【讨论】:

      猜你喜欢
      • 2018-10-04
      • 1970-01-01
      • 2023-04-03
      • 2016-10-03
      • 2016-04-17
      • 2015-11-03
      • 2014-07-17
      • 2013-05-25
      相关资源
      最近更新 更多