使用CSS动画折叠SVG图层时,针对单个SVG图层进行定位会产生奇怪的行为

3
我希望能够通过动画让我的SVG信封的盖子向下折叠。我该如何实现?
我尝试过对整个信封进行动画,我认为这是盖子应该表现的方式。请看结果:

#svg-envelope {
  height: 200px;
  animation: fold 4s forwards infinite;
}

@keyframes fold {
  0% {
    transform: rotateX(0deg);
    transform-origin: bottom;
  }
  100% {
    transform: rotateX(180deg);
    transform-origin: bottom;
  }
}
<svg id="svg-envelope" height="100%" viewBox="0 0 1715 1689" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
  <g transform="matrix(1,0,0,1,-382.933,-901.191)">
      <g id="base" transform="matrix(0.885663,0,0,1,121.31,324.647)">
          <rect x="302.051" y="1266.63" width="1922.47" height="994.035" style="fill:url(#_Linear1);stroke:black;stroke-width:8.82px;"/>
      </g>
      <g id="innerside-after" transform="matrix(0.885663,5.76867e-17,1.24618e-16,-1.0038,121.31,2868.06)">
          <path d="M1238.5,755.873C1253.69,747.587 1272.88,747.587 1288.08,755.873C1438.68,838.015 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1087.89,838.015 1238.5,755.873Z" style="fill:url(#_Linear3);stroke:black;stroke-width:8.8px;stroke-linejoin:miter;stroke-miterlimit:1;"/>
      </g>
      <g id="bottomflap" transform="matrix(0.885663,5.42038e-16,-4.3385e-16,1.10652,121.31,1183.76)">
          <path d="M1236.74,756.832C1252.76,748.097 1273.82,748.097 1289.83,756.832C1444.69,841.292 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1081.89,841.292 1236.74,756.832Z" style="fill:url(#_Linear4);stroke:black;stroke-width:8.32px;"/>
      </g>
      <g id="topflap-open-colored" transform="matrix(0.885663,4.72789e-16,-6.19857e-16,1.30832,121.31,-65.8757)">
          <path d="M1233.71,758.485C1250.98,749.068 1275.6,749.068 1292.86,758.485C1454.58,846.686 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1072,846.686 1233.71,758.485Z" style="fill:url(#_Linear7);stroke:black;stroke-width:7.46px;"/>
      </g>
  </g>
  <defs>
      <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,994.035,302.051,1763.65)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
  </defs>
</svg>

但是当我尝试将同样的动画应用于仅翻翼层(如下所示)时,它似乎有点被缩放(或拉伸?),并且不从其原始起始点开始。为什么会这样?如何解决?

#svg-envelope{
  height: 200px;
}

#topflap-open-colored{
  animation: fold 4s forwards infinite;
}
    
@keyframes fold {
  0%{
    transform: rotateX(0deg);
    transform-origin: bottom;
  }

  100%{
    transform: rotateX(180deg);
    transform-origin: bottom;
  }
}
<svg id="svg-envelope" height="100%" viewBox="0 0 1715 1689" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
  <g transform="matrix(1,0,0,1,-382.933,-901.191)">
      <g id="base" transform="matrix(0.885663,0,0,1,121.31,324.647)">
          <rect x="302.051" y="1266.63" width="1922.47" height="994.035" style="fill:url(#_Linear1);stroke:black;stroke-width:8.82px;"/>
      </g>
      <g id="innerside-after" transform="matrix(0.885663,5.76867e-17,1.24618e-16,-1.0038,121.31,2868.06)">
          <path d="M1238.5,755.873C1253.69,747.587 1272.88,747.587 1288.08,755.873C1438.68,838.015 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1087.89,838.015 1238.5,755.873Z" style="fill:url(#_Linear3);stroke:black;stroke-width:8.8px;stroke-linejoin:miter;stroke-miterlimit:1;"/>
      </g>
      <g id="bottomflap" transform="matrix(0.885663,5.42038e-16,-4.3385e-16,1.10652,121.31,1183.76)">
          <path d="M1236.74,756.832C1252.76,748.097 1273.82,748.097 1289.83,756.832C1444.69,841.292 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1081.89,841.292 1236.74,756.832Z" style="fill:url(#_Linear4);stroke:black;stroke-width:8.32px;"/>
      </g>
      <g id="topflap-open-colored" transform="matrix(0.885663,4.72789e-16,-6.19857e-16,1.30832,121.31,-65.8757)">
          <path d="M1233.71,758.485C1250.98,749.068 1275.6,749.068 1292.86,758.485C1454.58,846.686 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1072,846.686 1233.71,758.485Z" style="fill:url(#_Linear7);stroke:black;stroke-width:7.46px;"/>
      </g>
  </g>
  <defs>
      <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,994.035,302.051,1763.65)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
  </defs>
</svg>

1个回答

3
您遇到的问题是由于#topflap-open-colored元素上有一个transform属性引起的冲突。将该属性移到其内部的路径中,问题得以解决。
不幸的是,在组上设置transform-originbottom并没有完全解决问题。看起来各种变换导致原点略微低于信封盖子的感知底部。经过一些试验,我能够稍微调整原点以改善结果——我最终选择了94%。

#svg-envelope{
  height: 200px;
}

#topflap-open-colored {
  transform-origin: center 94%;
  animation: fold 4s forwards infinite;
}
    
@keyframes fold {
  0%{
    transform: rotateX(0deg);
  }

  100%{
    transform: rotateX(180deg);
  }
}
<svg id="svg-envelope" height="100%" viewBox="0 0 1715 1689" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
  <g transform="matrix(1,0,0,1,-382.933,-901.191)">
      <g id="base" transform="matrix(0.885663,0,0,1,121.31,324.647)">
          <rect x="302.051" y="1266.63" width="1922.47" height="994.035" style="fill:url(#_Linear1);stroke:black;stroke-width:8.82px;"/>
      </g>
      <g id="innerside-after" transform="matrix(0.885663,5.76867e-17,1.24618e-16,-1.0038,121.31,2868.06)">
          <path d="M1238.5,755.873C1253.69,747.587 1272.88,747.587 1288.08,755.873C1438.68,838.015 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1087.89,838.015 1238.5,755.873Z" style="fill:url(#_Linear3);stroke:black;stroke-width:8.8px;stroke-linejoin:miter;stroke-miterlimit:1;"/>
      </g>
      <g id="bottomflap" transform="matrix(0.885663,5.42038e-16,-4.3385e-16,1.10652,121.31,1183.76)">
          <path d="M1236.74,756.832C1252.76,748.097 1273.82,748.097 1289.83,756.832C1444.69,841.292 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1081.89,841.292 1236.74,756.832Z" style="fill:url(#_Linear4);stroke:black;stroke-width:8.32px;"/>
      </g>
      <g id="topflap-open-colored">
          <path d="M1233.71,758.485C1250.98,749.068 1275.6,749.068 1292.86,758.485C1454.58,846.686 2224.52,1266.63 2224.52,1266.63L302.051,1266.63C302.051,1266.63 1072,846.686 1233.71,758.485Z" style="fill:url(#_Linear7);stroke:black;stroke-width:7.46px;" transform="matrix(0.885663,4.72789e-16,-6.19857e-16,1.30832,121.31,-65.8757)"/>
      </g>
  </g>
  <defs>
      <linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,994.035,302.051,1763.65)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear4" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear5" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,263.844,302.051,870.864)"><stop offset="0" style="stop-color:rgb(226,226,226);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(25,65,80);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear6" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
      <linearGradient id="_Linear7" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1922.47,0,0,524.276,302.051,1004.49)"><stop offset="0" style="stop-color:rgb(59,183,90);stop-opacity:1"/><stop offset="0.51" style="stop-color:rgb(31,93,81);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(21,62,78);stop-opacity:1"/></linearGradient>
  </defs>
</svg>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接