【问题标题】:How to style/animate nested SVG?如何为嵌套的 SVG 设置样式/动画?
【发布时间】:2022-01-22 19:54:56
【问题描述】:

我正在学习 SVG。这是我的动画 SVG:

#sky {
  animation: skyColor 10s alternate infinite linear;
}

@keyframes skyColor {
  0% {
    fill: #000000;
  }
  30% {
    fill: #000000;
  }
  40% {
    fill: #303030;
  }
  50% {
    fill: #fffade;
  }
  60% {
    fill: #add1db;
  }
  100% {
    fill: #dcf5fc;
  }
}

#sun {
  r: 10;
  fill: yellow;
}

#bear {
  transform: translate(50px, 50px);
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="600" height="400">
  <defs>
    <linearGradient id="snowHillGradient1" x1="0.25" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="#fdfdfd"/>
      <stop offset="100%" stop-color="#e0e0e0"/>
    </linearGradient>

    <linearGradient id="snowHillGradient2" x1="0" x2="0.25" y1="0" y2="1">
      <stop offset="0%" stop-color="#fcfcfc"/>
      <stop offset="100%" stop-color="#d2d2d2"/>
    </linearGradient>

    <linearGradient id="snowHillGradient3" x1="0.5" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="#fcfcfc"/>
      <stop offset="100%" stop-color="#d6d6d6"/>
    </linearGradient>
  </defs>

  <rect x="0" y="0" width="300" height="200" id="sky"/>
  <circle id="sun" cx="150" cy="220">
    <animateMotion dur="20s" repeatCount="indefinite" path="m 0 0 a 1 1 0 0 1 0 -220 a 1 1 0 0 1 0 220" />
  </circle>

  <path id="moon" fill="#f7f7f7" d="M 0 0 a 9 9 0 1 0 3 15 c -13 2 -13 -14 -3 -15" >
    <animateMotion dur="20s" repeatCount="indefinite" path="m 150 0 a 1 1 0 0 1 0 220 a 1 1 0 0 1 0 -220" />
  </path>

  <path fill="url(#snowHillGradient1)" stroke="#f0f0f0" stroke-width="0.25" d="M -20 68 l 212 0 c -68 -50 -181 -29 -212 0" style="transform: scale(3);" />
  <path fill="url(#snowHillGradient2)" stroke="#f0f0f0" stroke-width="0.25" d="M -60 85 l 212 0 c -81 -42 -191 -39 -212 0" style="transform: scale(2.2);" />
  <path fill="url(#snowHillGradient3)" stroke="#eaeaea" stroke-width="0.25" d="M 4 85 l 212 0 c -68 -50 -181 -29 -212 0" style="transform: scale(2.5);" />
  <path fill="url(#snowHillGradient2)" stroke="#f0f0f0" stroke-width="0.25" d="M -44 85 l 212 0 c -81 -32 -183 -21 -212 0" style="transform: scale(2.5);" /> 

  <svg width="100" height="100" id="bear">
    <!-- Bear -->
    <path stroke="black" stroke-width="1" fill="#543C23" d="m 35 60 l -20 20 l -4 10 l 0 5 l 78 0 l 0 -5 l -4 -10 l -20 -20 " />

    <ellipse cx="50" cy="50" rx="30" ry="25" fill="#543C23" stroke="black" />

    <ellipse cx="41" cy="45" rx="7" ry="7" fill="white" stroke="black" />
    <ellipse cx="58" cy="45" rx="7" ry="7" fill="white" stroke="black" />
    <ellipse cx="41" cy="44" rx="3" ry="3" fill="black" stroke="none" />
    <ellipse cx="58" cy="44" rx="3" ry="3" fill="black" stroke="none" />
    
    <ellipse cx="49" cy="58" rx="6" ry="4" fill="black" stroke="none" />
    <line x1="49" y1="58" x2="49" y2="68" stroke="black" stroke-width="2" />

    <polyline points="34,62 41,67 49,68 57,67 64,62" stroke="black" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" />

    <path stroke="black" stroke-width="1" fill="#543C23" d="m 25 40 c -5 -10  0 -15 10 -10" />

    <path stroke="black" stroke-width="1" fill="#543C23" d="m 75 40 c 5 -10 0 -15 -10 -10" />

    <rect x="0" y="0" width="100%" height="100%" stroke="red" fill="none" />
  </svg>

  <rect x="0" y="0" width="300" height="200" stroke="black" fill="none" />
</svg>

我想为嵌套的 SVG (#bear id) 设置动画/样式。 但即使很简单

  #bear {
    transform: translate(50px, 50px);
  }

仅适用于 FireFox!但在 Chrome 中它没有效果。

如何在 Chrome 中设置嵌套 SVG 的样式/动画? 也许还有其他方法可以为嵌套 SVG 设置动画? 嵌套 SVG 由于有自己的坐标系,非常方便。

【问题讨论】:

  • 如果你想让它在 Chrome 中工作,你必须在 元素中放置一个 元素并对其进行转换。也许 Chrome 有一天会赶上 SVG 2 规范和 Firefox,而这不是必需的。
  • 但是这种方法限制了可能性。在嵌套的 SVG 中,我们可以将复杂的动画应用于元素,而无需考虑在外部 SVG 中的定位。然后,在这组内部动画之上,我们可以应用来自外部 SVG 的另一个动画。
  • 好的,go fix Chrome then毕竟是开源的。

标签: css svg


【解决方案1】:

嵌套&lt;svg&gt; 的替代方法可以是&lt;symbol&gt;。符号元素也可以与其他元素分开处理。要显示符号,您还需要使用 &lt;use&gt; —— 然后可以设置样式(我将 CSS 选择器更改为 #usebear)。

#sky {
  animation: skyColor 10s alternate infinite linear;
}

@keyframes skyColor {
  0% {
    fill: #000000;
  }
  30% {
    fill: #000000;
  }
  40% {
    fill: #303030;
  }
  50% {
    fill: #fffade;
  }
  60% {
    fill: #add1db;
  }
  100% {
    fill: #dcf5fc;
  }
}

#sun {
  r: 10;
  fill: yellow;
}

#usebear {
  transform: translate(50px, 50px);
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="600" height="400">
  <defs>
    <linearGradient id="snowHillGradient1" x1="0.25" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="#fdfdfd"/>
      <stop offset="100%" stop-color="#e0e0e0"/>
    </linearGradient>

    <linearGradient id="snowHillGradient2" x1="0" x2="0.25" y1="0" y2="1">
      <stop offset="0%" stop-color="#fcfcfc"/>
      <stop offset="100%" stop-color="#d2d2d2"/>
    </linearGradient>

    <linearGradient id="snowHillGradient3" x1="0.5" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="#fcfcfc"/>
      <stop offset="100%" stop-color="#d6d6d6"/>
    </linearGradient>
  </defs>

  <rect x="0" y="0" width="300" height="200" id="sky"/>
  <circle id="sun" cx="150" cy="220">
    <animateMotion dur="20s" repeatCount="indefinite" path="m 0 0 a 1 1 0 0 1 0 -220 a 1 1 0 0 1 0 220" />
  </circle>

  <path id="moon" fill="#f7f7f7" d="M 0 0 a 9 9 0 1 0 3 15 c -13 2 -13 -14 -3 -15" >
    <animateMotion dur="20s" repeatCount="indefinite" path="m 150 0 a 1 1 0 0 1 0 220 a 1 1 0 0 1 0 -220" />
  </path>

  <path fill="url(#snowHillGradient1)" stroke="#f0f0f0" stroke-width="0.25" d="M -20 68 l 212 0 c -68 -50 -181 -29 -212 0" style="transform: scale(3);" />
  <path fill="url(#snowHillGradient2)" stroke="#f0f0f0" stroke-width="0.25" d="M -60 85 l 212 0 c -81 -42 -191 -39 -212 0" style="transform: scale(2.2);" />
  <path fill="url(#snowHillGradient3)" stroke="#eaeaea" stroke-width="0.25" d="M 4 85 l 212 0 c -68 -50 -181 -29 -212 0" style="transform: scale(2.5);" />
  <path fill="url(#snowHillGradient2)" stroke="#f0f0f0" stroke-width="0.25" d="M -44 85 l 212 0 c -81 -32 -183 -21 -212 0" style="transform: scale(2.5);" /> 

  <symbol width="100" height="100" id="bear">
    <!-- Bear -->
    <path stroke="black" stroke-width="1" fill="#543C23" d="m 35 60 l -20 20 l -4 10 l 0 5 l 78 0 l 0 -5 l -4 -10 l -20 -20 " />

    <ellipse cx="50" cy="50" rx="30" ry="25" fill="#543C23" stroke="black" />

    <ellipse cx="41" cy="45" rx="7" ry="7" fill="white" stroke="black" />
    <ellipse cx="58" cy="45" rx="7" ry="7" fill="white" stroke="black" />
    <ellipse cx="41" cy="44" rx="3" ry="3" fill="black" stroke="none" />
    <ellipse cx="58" cy="44" rx="3" ry="3" fill="black" stroke="none" />
    
    <ellipse cx="49" cy="58" rx="6" ry="4" fill="black" stroke="none" />
    <line x1="49" y1="58" x2="49" y2="68" stroke="black" stroke-width="2" />

    <polyline points="34,62 41,67 49,68 57,67 64,62" stroke="black" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" />

    <path stroke="black" stroke-width="1" fill="#543C23" d="m 25 40 c -5 -10  0 -15 10 -10" />

    <path stroke="black" stroke-width="1" fill="#543C23" d="m 75 40 c 5 -10 0 -15 -10 -10" />

    <rect x="0" y="0" width="100%" height="100%" stroke="red" fill="none" />
  </symbol>
  <use href="#bear" id="usebear"/>

  <rect x="0" y="0" width="300" height="200" stroke="black" fill="none" />
</svg>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2019-07-14
    • 2018-07-10
    相关资源
    最近更新 更多