围绕 inkscape 旋转 SVG 组 g:transform-center-x/y in Javascript/Jquery

Rotate an SVG group g around an inkscape:transform-center-x/y in Javascript/Jquery

我想以编程方式将 Inkscape 中设计的时钟指针旋转为 SVG,以便使用 Javascript/Jquery 在浏览器中制作自定义设计的 Date/Time 选择器。

SVG:

<svg
   width="2200"
   height="1700"
   viewBox="0 0 582.08332 449.79166"
   sodipodi:docname="DateTimePicker.svg">
...
  <g
     inkscape:label="DateTimePicker"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,152.79168)">
    <g
       id="g4802"
       inkscape:label="SecondsHand"
       inkscape:transform-center-x="0.23194686"
       inkscape:transform-center-y="-22.707409"
       transform="translate(10.583327,-42.333328)">
     .... (There are some paths in here to draw the shape)
     </g>
    <g
       id="g4798"
       inkscape:label="MinutesHand"
       inkscape:transform-center-x="0.050484234"
       inkscape:transform-center-y="-20.583753"
       transform="translate(10.583352,-42.333325)">
     .... (There are some paths in here to draw the shape)
     </g>
    <g
       id="g4789"
       inkscape:label="HoursHand"
       inkscape:transform-center-x="-0.29101068"
       inkscape:transform-center-y="-12.194587"
       transform="translate(10.583295,-42.333339)">
  <path
     inkscape:transform-center-y="-12.335484"
     sodipodi:nodetypes="ccccccccc"
     inkscape:transform-center-x="-0.43053568"
     inkscape:connector-curvature="0"
     id="path3199"
     d="m 424.77397,-31.058733 -2.7993,21.043385 c 0,0 -0.41499,2.6995795 0.88985,4.0317895 -0.089,0.23193 -0.1351,0.47814 -0.13589,0.72657 -1.3e-4,1.12967 0.91567,2.04548 2.04534,2.04536 1.12947,-1.6e-4 2.04496,-0.91589 2.04483,-2.04536 -1.8e-4,-0.24869 -0.0457,-0.49525 -0.13436,-0.7276 1.3035,-1.33258 0.88834,-4.0307595 0.88834,-4.0307595 z"
     style="opacity:0.778;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter2507)"
     inkscape:label="ShadowHourHand" />
  <g
     inkscape:transform-center-x="5.3889177e-06"
     transform="translate(47.709026,-125.85737)"
     inkscape:transform-center-y="-10.8713"
     id="g3193"
     inkscape:label="HourHand">
    <path
       sodipodi:nodetypes="ccccccccc"
       inkscape:connector-curvature="0"
       id="path3183"
       d="m 1423.707,324.97033 -10.58,72.17225 c 0,0 -1.5685,10.20314 3.3632,15.23828 -0.3366,0.87657 -0.5106,1.80713 -0.5136,2.74609 -5e-4,4.26959 3.4608,7.73091 7.7304,7.73047 4.2688,-6.1e-4 7.729,-3.46162 7.7285,-7.73047 -7e-4,-0.93992 -0.1727,-1.87183 -0.5078,-2.75 4.9266,-5.03651 3.3575,-15.23437 3.3575,-15.23437 z"
       style="opacity:1;fill:url(#linearGradient4836);fill-opacity:1;stroke:none;stroke-width:1.13385832;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       transform="matrix(0.26458333,0,0,0.26458333,0,11.249983)" />
    <path
       sodipodi:nodetypes="ccccccccccc"
       inkscape:connector-curvature="0"
       id="path3185"
       transform="matrix(0.26458333,0,0,0.26458333,0,11.249983)"
       d="m 1423.8672,338.32229 -6.9727,63.97654 0.2422,0.002 v 0.0215 c 8e-4,4.63516 3.1214,8.3923 6.9707,8.39257 3.8145,-0.002 6.919,-3.6962 6.9668,-8.28906 h 0.033 l -0.047,-0.67969 v -0.0176 -0.0215 z"
       style="opacity:0.7;fill:#ffe25d;fill-opacity:1;stroke:none;stroke-width:1.13385832;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3111)" />
    <path
       inkscape:connector-curvature="0"
       id="circle3187"
       d="m 378.15497,121.08581 a 1.4660022,1.4660022 0 0 1 -1.46601,1.466 1.4660022,1.4660022 0 0 1 -1.466,-1.466 1.4660022,1.4660022 0 0 1 1.466,-1.466 1.4660022,1.4660022 0 0 1 1.46601,1.466 z"
       style="opacity:1;fill:#ffe56a;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter2836)" />
    <path
       sodipodi:nodetypes="scscs"
       inkscape:connector-curvature="0"
       id="path3189"
       d="m 377.65184,117.39486 c 0,0.83592 -0.41881,1.51358 -0.93544,1.51358 -0.51663,0 -0.93544,-0.67766 -0.93544,-1.51358 0,-0.83592 0.35199,-2.54925 0.86862,-2.54925 0.51663,0 1.00226,1.71333 1.00226,2.54925 z"
       style="opacity:0.70899999;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3146)" />
    <path
       inkscape:connector-curvature="0"
       id="circle3191"
       d="m 377.173,121.08581 a 0.48403955,0.48403955 0 0 1 -0.48404,0.48404 0.48403955,0.48403955 0 0 1 -0.48403,-0.48404 0.48403955,0.48403955 0 0 1 0.48403,-0.48404 0.48403955,0.48403955 0 0 1 0.48404,0.48404 z"
       style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.30000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter3168)" />
  </g>
     </g>
</g>'s as needed

这是 Inkscape 在 HoursHand 上计算的 15 度旋转增量。

{
  // 0 degrees
  transform-center: (-0.29101049, -12.194589),
  transform: translate(10.583294,-42.333341)
},
{
  transform-center: (-2.679194, -11.668645),
  transform: rotate(15,590.36335,14.32942)
},
{
  transform-center: (-5.8379232, -10.278138),
  transform: rotate(30,508.58162,-6.1159341)
},
{
  transform-center: (-8.5291975, -8.1175788),
  transform: rotate(45,480.68739,-13.089463)
},
{
  transform-center: (-10.569195, -5.2923862),
  transform: rotate(60,466.24828,-16.699228)
},
{
  transform-center: (-11.819306, -1.9982106),
  transform: rotate(75,457.17147,-18.968421)
},
{
  transform-center: (-12.194588, 0.29100973),
  transform: rotate(90,450.7532,-20.572983)
},
{
  transform-center: (-11.668649, 2.679191),
  transform: rotate(105,445.82829,-21.804206)
},
{
  transform-center: (-10.278149, 5.8379174),
  transform: rotate(120,441.80712,-22.809495)
},
{
  transform-center: (-8.1175958, 8.5291943),
  transform: rotate(135,438.35406,-23.672756)
},
{
  transform-center: (-5.292401, 10.569196),
  transform: rotate(150,435.25813,-24.446734)
},
{
  transform-center: (-1.9982232, 11.819314),
  transform: rotate(165,432.37318,-25.167967)
},
{
  transform-center: (0.2910098, 12.194597),
  transform: rotate(180,429.58653,-25.864625)
},
{
  transform-center: (2.6792046, 11.668654)
  transform: rotate(-165,426.79988,-26.561283)
},
{
  transform-center: (5.837939, 10.278141),
  transform: rotate(-150,423.91493,-27.282518)
},
{
  transform-center: (8.1175808, 8.5292134),
  transform: rotate(-135,420.819,-28.056498)
},
{
  transform-center: (10.569206, 5.293819),
  transform: rotate(-120,417.36594,-28.919761)
},
{
  transform-center: (11.819324, 1.9982024),
  transform: rotate(-105,413.34476,-29.925051)
},
{
  transform-center: (12.194597, -0.29101935),
  transform: rotate(-90,408.41985,-31.156276)
},
{
  transform-center: (11.668649, -2.6792024),
  transform: rotate(-75,402.00158,-32.760839)
},
{
  transform-center: (10.278139, -5.8379339),
  transform: rotate(-60,392.92477,-35.030033)
},
{
  transform-center: (8.1175801, -8.5292112),
  transform: rotate(-45,378.48565,-38.6398)
},
{
  transform-center: (5.2923805, -10.569206),
  transform: rotate(-30,350.59142,-45.613334)
},
{
  transform-center: (1.9982049, -11.819318),
  transform: rotate(-15,268.80967,-66.058702)
}

这是一些 Javascript 我 运行 在 0 度的时针上:

CTM: SVGMatrix
​​  a: 0.6871868371963501
​  b: 0
  c: 0
​​  d: 0.6871868371963501
​​  e: 7.272700786590576
​​  f: 76.36006927490234
​boundingBox: SVGRect
​​  height: 28.33203125
​​  width: 6.1015625
​  x: 421.53515625
​​  y: -31.05859375
​​boundingClientRect: DOMRect
​​  bottom: 74.5
​​  height: 19.5
​​  left: 296.933349609375
​​  right: 301.15000915527344
​​  top: 55
​​  width: 4.2166595458984375
​​  x: 296.933349609375
​​  y: 55
​​0: <g id="g4789" inkscape:label="HoursHand" inkscape:transform-center-x="-0.29101068" inkscape:transform-center-y="-12.194587" transform="translate(10.583295,-42.333339)">
​​screenCTM: SVGMatrix
​​  a: 0.6871868371963501
​​  b: 0
​​  c: 0
​​  d: 0.6871868371963501
​​  e: 7.272700786590576
​​  f: 76.36006927490234
​​transform: "translate(10.583295,-42.333339)"
​transform_center_x: "-0.29101068"
​transform_center_y: "-12.194587"

逆 CTM = (a,d = 1.45522, b,c = 0, e = -10.58339, f = -111.12089)

我想知道的是对于一些任意对象,从 HoursHand 开始,任意角度或旋转,如何计算 t运行sform-center x 和 y,以及 x 和 y旋转中心的角度,对于 Inkscape 计算的度数。

注意:这里的t运行sform-center偏心了,我想用Javascript而不是依赖CSS,因为SVG t运行sforms与 CSS t运行sforms 的处理方式不同,因此这里解释的方法将不起作用:

更新1:我已经阅读了我能理解的关于这个答案中提到的相关章节的内容: pointing to this text: https://www.w3.org/TR/SVG/coords.html#TransformProperty这对一些人有所帮助。

虽然这里的问题是我从 Inkscape 出来的路径在他们的用户坐标 space 中有像 m 424.77397,-31.058733 这样的坐标。如果您注意到,在 HoursHand 上旋转 15 度时我有旋转(15,590.36335,14.32942),在旋转 30 度时我有旋转(30,508.58162,-6.1159341),t运行sform 上的旋转中心在x 轴。

所以需要应用一些找角代码来预先确定旋转时旋转中心需要在哪里,而不是当前的t运行slate(~10,~-42)用户坐标space,这是我需要帮助的地方。

在 Inkscape 中执行此操作的明智方法是 select 具有“transform: translate(x, y)”属性的组节点,然后删除转换。然后select组的子节点和组节点需要的位置。在 Javascript 方面,我需要在旋转之前记住变换的中心点位置。时、分、秒针都共享同一个旋转中心点,需要相对于getBBox()获取的边界框坐标进行绝对定位。

了解如何在 SVG 用户坐标系中使用已平移且变换中心为 off-center 的组进行旋转,但在某些情况下仍然很有用。