ghett
ghett

Reputation: 99

animated svg mask doesn't work in firefox

h1 everyone, i'm trying to make a cross-browser animation based on svg mask for svg elements. At first, I caught a bug with css, in firefox mask doesn't work with css 'width' and 'height', only with inline properties. So, next question - how to animate mask for firefox, nothing harder that 'width resize'. https://codepen.io/flyby/pen/KmYOgb

<div id='cont'>
  <svg>
    <defs>
      <mask id='rectMask' maskUnits='userSpaceOnUse' maskContentUnits='userSpaceOnUse' transform='scale(1)'>
        <rect x='0' y='0' id='maskRect' width='700' height='850'/>
      </mask>
    </defs>
    <path id='maskedPath' d='m 0,0 l 650,0 -100,850 -550,0 z' mask='url(#rectMask)'/>
    <path id='riverPath' d='m 653,0 l -100,850' mask='url(#rectMask)'/>
    <path id='notMaskedPath' d='m 655,0 l 650,0 0,850 -750,0 z'/>
  </svg>
</div>

CSS:

body {
  margin:0;
  padding:0;
  overflow:hidden;
}
#cont {
  width:100vw;
  height:100vh;
  background-color:rgb(50,50,50);
}
svg {
  width:100%;
  height:100%;
}
#maskedPath {
  stroke:none;
  fill:rgb(230,230,230);
}
#notMaskedPath {
  stroke:none;
  fill:rgb(230,230,230);
}
#riverPath {
  stroke:rgb(50,160,240);
  stroke-width:8;
  fill:none;
}
#maskRect {
  width:0px;
  height:850px;
  fill:white;
  stroke:none;
  animation: resize 3s linear infinite;
}
@-moz-keyframes resize {
  50% {width: 700px !important;}
  0%,100% {width: 0px !important;}
}

Upvotes: 1

Views: 679

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101820

Like you have discovered, your can't (yet) set geometric properties, like width and height of SVG elements in Firefox. It's not a bug. It's just an SVG 2 thing that Firefox has not implemented yet, but Chrome has.

The solution is to use the built-in SVG ("SMIL") animation elements, instead of CSS animation.

body {
  margin:0;
  padding:0;
  overflow:hidden;
}
#cont {
  width:100vw;
  height:100vh;
  background-color:rgb(50,50,50);
}
svg {
  width:100%;
  height:100%;
}
#maskedPath {
  stroke:none;
  fill:rgb(230,230,230);
}
#notMaskedPath {
  stroke:none;
  fill:rgb(230,230,230);
}
#riverPath {
  stroke:rgb(50,160,240);
  stroke-width:8;
  fill:none;
}
#maskRect {
  fill:white;
  stroke:none;
}
<!--this animation doesn't work in FIREFOX, and not tested in IE11 ad Edge YET, WILL BE FIXED SOON (I HOPE)-->
<div id='cont'>
  <svg>
    <defs>
      <mask id='rectMask' maskUnits='userSpaceOnUse' maskContentUnits='userSpaceOnUse' transform='scale(1)'>
        <rect x='0' y='0' width="0" height="850" id='maskRect'>
          <animate attributeName="width"
                   keyTimes="0; 0.4; 0.5; 1"
                   values="0; 670; 670; 0"
                   dur="4s" repeatCount="indefinite"/>
        </rect>
      </mask>
    </defs>
    <path id='maskedPath' d='m 0,0 l 650,0 -100,850 -550,0 z' mask='url(#rectMask)'/>
    <path id='riverPath' d='m 653,0 l -100,850' mask='url(#rectMask)'/>
    <path id='notMaskedPath' d='m 655,0 l 650,0 0,850 -750,0 z'/>
  </svg>
</div>

Upvotes: 2

Related Questions