如何正确使用 animateTransform cx cy 值?

Posted

技术标签:

【中文标题】如何正确使用 animateTransform cx cy 值?【英文标题】:How to use animateTransform cx cy values properly? 【发布时间】:2022-01-04 01:42:06 【问题描述】:

我正在尝试在 svg 中制作动画加载图标,尽管每当我在 Chrome 或 Edge 中检查结果时,旋转动画不会对 cx/cy 值做出反应(仅当我将它们设置为零时, 会适当旋转,否则会有一点摆动)。

我在 Qt 中使用 QSvgWidget,下面的示例运行良好。我只是想了解为什么它不能在 Chrome 上运行。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   
   
   viewBox="0 0 23 23"
   version="1.1"
   id="svg8"
   inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
   sodipodi:docname="loading_static.svg">
  <defs
 id="defs2">
<linearGradient
   inkscape:collect="always"
   id="linearGradient2832">
  <stop
     style="stop-color:#e9e9e9;stop-opacity:1"
     offset="0"
     id="stop2841" />
  <stop
     style="stop-color:#ffffff;stop-opacity:0"
     offset="1"
     id="stop2843" />
</linearGradient>
<linearGradient
   id="linearGradient2781"
   osb:paint="solid">
  <stop
     style="stop-color:#e5e5e5;stop-opacity:1;"
     offset="0"
     id="stop2779" />
</linearGradient>
<linearGradient
   inkscape:collect="always"
   xlink:href="#linearGradient2832"
   id="linearGradient2846"
   gradientUnits="userSpaceOnUse"
   x1="86.672661"
   y1="84.384331"
   x2="90.090706"
   y2="84.979637" />
  </defs>
  <sodipodi:namedview
 id="base"
 pagecolor="#ffffff"
 bordercolor="#666666"
 borderopacity="1.0"
 inkscape:pageopacity="0.0"
 inkscape:pageshadow="2"
 inkscape:zoom="4"
 inkscape:cx="49.995012"
 inkscape:cy="42.458459"
 inkscape:document-units="mm"
 inkscape:current-layer="layer1"
 inkscape:document-rotation="0"
 showgrid="false"
 fit-margin-top="0"
 fit-margin-left="0"
 fit-margin-right="0"
 fit-margin-bottom="0"
 inkscape:window-
 inkscape:window-
 inkscape:window-x="104"
 inkscape:window-y="0"
 inkscape:window-maximized="0" />
  <metadata
 id="metadata5">
<rdf:RDF>
  <cc:Work
     rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type
       rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    <dc:title></dc:title>
  </cc:Work>
</rdf:RDF>
  </metadata>
  <g
 inkscape:label="Layer 1"
 inkscape:groupmode="layer"
 id="layer1"
 transform="translate(-69.67318,-75.994617)">
<path
   style="fill:none;stroke:url(#linearGradient2846);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
   id="path833"
   sodipodi:type="arc"
   sodipodi:cx="81.170387"
   sodipodi:cy="87.492027"
   sodipodi:rx="10"
   sodipodi:ry="10"
   sodipodi:start="0"
   sodipodi:end="5.2186587"
   sodipodi:arc-type="arc"
   d="M 91.170387,87.492027 A 10,10 0 0 1 83.8004,97.139982 10,10 0 0 1 72.55378,92.566876 10,10 0 0 1 74.008018,80.513455 10,10 0 0 1 86.01957,78.746433"
   sodipodi:open="true"/>
  </g>

<animateTransform
    from="0 11.5 11.5"
    to="360 11.5 11.5"
    attributeName="transform"
    type="rotate"
    repeatCount="indefinite"
    dur="1300ms"
/>
</svg>
 

【问题讨论】:

【参考方案1】:

如果您希望此形状旋转而不会晃动,则必须确保它围绕其精确中心的一个点旋转。但是在您的代码中,很难确定这个形状的中心在哪里,所以难怪您很难让它工作。

对于这样的事情,最好不要使用 Inkscape。相反,这是一个从头开始制作的简单示例:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg"   viewBox="0 0 23 23">
  <g transform="translate(11.5,11.5)">
    <path d="M9.5,0C9.5,5.243 5.243,9.5 0,9.5C-5.243,9.5 -9.5,5.243 -9.5,0C-9.5,-5.243 -5.243,-9.5 0,-9.5C2.622,-9.5" fill="none" stroke="#000" stroke- stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4">
      <animateTransform from="0" to="360" attributeName="transform" type="rotate" repeatCount="indefinite" dur="1300ms"/>
    </path>
  </g>
</svg>

path 元素描述了一个以原点为中心、半径为 9.5 个单位的四分之三圆。其内部的animateTransform 元素使其围绕原点旋转(因此无需在旋转参数中添加额外的xy 值),而外部g 元素将整个事物转换为视图框。

【讨论】:

以上是关于如何正确使用 animateTransform cx cy 值?的主要内容,如果未能解决你的问题,请参考以下文章

svg animatetransform在firefox上运行但不在chrome / ie上

SVG SMIL:animateTransform 替换为设置(不透明度和缩放属性)

SVG animateTransform 同时旋转和缩放同一个对象?

如何使用 Python CFFI 正确包装 C 库

如何使用 ctypes 在 python 中正确包装 C API?

如何在 C 中正确使用“sleep()”系统调用