CSS 动画不适用于 <img> 中的 svg

Posted

技术标签:

【中文标题】CSS 动画不适用于 <img> 中的 svg【英文标题】:CSS animation do not work for svg in <img> 【发布时间】:2018-02-13 12:10:50 【问题描述】:

我正在尝试为图像/对象标签中的 SVG 设置动画,但它不起作用

svg 
  width: 100%;
  height: 200px;


.rotate-45 
  transform-origin: center;
  transform: rotate(45deg);


.rotate 
  transform-origin: center;
  animation: rotate 1s ease-in-out infinite;


.rotate-back 
  transform-origin: center;
  animation: rotate 1s ease-in-out infinite;
  animation-direction: alternate;


.left 
  animation: move 1s ease-in-out infinite;


.right 
  animation: move 1s ease-in-out infinite;


@keyframes rotate 
  100% 
    transform: rotate(calc(90deg + 45deg));
  


@keyframes move 
  50% 
    transform: translate(-30px, -30px);
  
 <svg   viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g transform="translate(500,500)">
      <rect class="rotate-45 rotate-back" x="-5" y="-5"   stroke="#00a99d" stroke- fill="none" />
      <rect class="rotate-45 rotate" x="-50" y="-50"   stroke="#00a99d" stroke- stroke-linejoin="bevel" fill="none" />
      <g transform="translate(-50,0) rotate(-45)">
        <polyline class="left" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke- fill="none" />
      </g>
      <g transform="translate(50,0) rotate(135)">
        <polyline class="right" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke- fill="none" />
      </g>
      <text y="-140" text-anchor="middle" font-weight="bold" font-size="3em" font-family="sans-serif">loading data...</text>
    </g>
  </svg>

如何将图像标签内的 SVG 与 CSS 一起制作动画

这是该代码https://plnkr.co/edit/TdfR7cpVaQArtcUs0Hro?p=preview的plunker

【问题讨论】:

你的标题没有说明这个问题。请在标题中简要说明您的问题 你似乎需要帮助做 CSS 动画,这与 SVG 无关。 将你的 CSS 直接包含在你的 svg 中,html 的文档的 CSS 不能针对 img 的内容:plnkr.co/edit/dtjUhZpzbm3NjdzsBKch?p=preview 你也可以使用&lt;?xml-stylesheet href="style.css" type="text/css"?&gt;,如果你不想嵌入img标签来工作。上面的代码将在object 标签中工作 @Kaiido 你没有阅读我的全部信息吗?我说如果你不想嵌入它以使img 标签工作。这适用于object 标签 【参考方案1】:

如果您不想想要嵌入&lt;?xml-stylesheet href="style.css" type="text/css"?&gt; 以使img 标记正常工作,则可以使用&lt;?xml-stylesheet href="style.css" type="text/css"?&gt;。上面的代码将在object 标签中工作

如果您希望 img 标签起作用,请按照 Kaiido 的建议进行操作并嵌入它。

【讨论】:

请您公开您的解决方案吗?【参考方案2】:

您无法从外部为&lt;img&gt; 的内部设置动画。即使它是 SVG。这有两个原因:

    CSS 不适用于跨文档边界,并且 通过&lt;img&gt; 引用的图像必须是独立的。

如果您将 CSS 放在外部 SVG 中(在 &lt;style&gt; 元素中正常),动画应该可以工作。

另请注意,您需要更改transform-origin 的操作方式。它在 Chrome 中的工作方式很方便,但根据当前规范是错误的。它不适用于 Firefox 等其他浏览器。

<svg   viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
  <style>
.rotate-45 
  transform-origin: 0px 0px;
  transform: rotate(45deg);


.rotate 
  transform-origin: 0px 0px;
  animation: rotate 1s ease-in-out infinite;


.rotate-back 
  transform-origin: 0px 0px;
  animation: rotate 1s ease-in-out infinite;
  animation-direction: alternate;


.left 
  animation: move 1s ease-in-out infinite;


.right 
  animation: move 1s ease-in-out infinite;


@keyframes rotate 
  100% 
    transform: rotate(135deg);
  


@keyframes move 
  50% 
    transform: translate(-30px, -30px);
  

  </style>
  <g transform="translate(500,500)">
    <rect class="rotate-45 rotate-back" x="-5" y="-5"   stroke="#00a99d" stroke- fill="none"/>
    <rect class="rotate-45 rotate" x="-50" y="-50"   stroke="#00a99d" stroke- stroke-linejoin="bevel" fill="none"/>
    <g transform="translate(-50,0) rotate(-45)"><polyline class="left" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke- fill="none"/></g>
    <g transform="translate(50,0) rotate(135)"><polyline class="right" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke- fill="none"/></g>
    <text y="-140" text-anchor="middle" font-weight="bold" font-size="3em" font-family="sans-serif">loading data...</text>
  </g>
</svg>

【讨论】:

一个疑问是这个svg中使用的样式是否会对其他元素产生影响 没有。就像我说的。 CSS 不能跨文档边界工作。无论是 SVG 还是其他任何东西都是如此。【参考方案3】:

如果您正在使用纯 javascript 或其他不会在 HTML 输出中自动包含 SVG 内联的环境(例如 create-react-app 那样),这里有一个可能对您有用的解决方案:

<img id="logo" src="logo.svg" />
<script>
// load logo inline for animation on hover
const loadLogo = async () => 
  // get logo, parse source text, and insert text into doc
  document.write(await (await fetch("logo.svg")).text());
  // remove fallback img logo
  document.querySelector("img#logo").remove();
;
loadLogo();
</script>

所有这一切都是尝试在给定的 url/路径加载图像,然后将其文本内容直接插入到文档中。然后您可以从其他样式表中对其进行样式设置,使用 javascript 操作子元素,拥有用户交互动画等。如果由于任何原因无法加载,则有一个 &lt;img&gt; 作为备份。

这也可以写得更笼统,但这只是我曾经使用过的一个快速解决方案。


另一种解决方案是仅使用 &lt;object&gt; as explained here 嵌入 SVG,但根据您想要执行的操作可能会有一些限制。

【讨论】:

以上是关于CSS 动画不适用于 <img> 中的 svg的主要内容,如果未能解决你的问题,请参考以下文章

SVG + css3 动画不适用于链接标记

带有变换的css关键帧动画不适用于SVG

动画转发不适用于:悬停

动画不适用于带有tailwindcss的className中的条件

CSS 过渡不适用于 FF 中的 top 属性

css子选择器不适用于thead中的元素