简体   繁体   English

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

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

I want to programmatically rotate the hands of a clock designed in Inkscape as an SVG to make a custom designed Date/Time picker in the browser using Javascript/Jquery.我想以编程方式旋转在 Inkscape 中设计为 SVG 的时钟指针,以使用 Javascript/Jquery 在浏览器中制作自定义设计的日期/时间选择器。

SVG: 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

This is what Inkscape calculates on the HoursHand for rotation increments of 15 degrees.这是 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)
}

Here is some Javascript I ran on the HoursHand at 0 degrees:这是我在 0 度的 HoursHand 上运行的一些 Javascript:

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"

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

What I want to know is for some arbitrary object, starting with HoursHand, and any degree or rotation, how to calculate the transform-center x and y, as well as the x and y of the center of rotation, for that degree as Inkscape calculates it.我想知道的是对于一些任意对象,从 hoursHand 开始,以及任何度数或旋转,如何计算变换中心 x 和 y,以及旋转中心的 x 和 y,对于那个度数作为 Inkscape计算它。

Note: The transform-center here is off center, and I want to use Javascript rather than rely on CSS since SVG transforms are handled differently than CSS transforms, so the method explained here will not work: SVG Animation rotate group around its center注意:这里的变换中心是偏离中心的,我想使用 Javascript 而不是依赖 CSS,因为 SVG 变换的处理方式与 CSS 变换不同,所以这里解释的方法不起作用: SVG 动画围绕其中心旋转组

Update 1: I've read what I can understand of the relevant chapter mentioned in this answer: Why am I failing to rotate a path around a given point in SVG pointing to this text: https://www.w3.org/TR/SVG/coords.html#TransformProperty which helped some.更新 1:我已经阅读了我对本答案中提到的相关章节的理解: 为什么我无法围绕指向此文本的SVG 中的给定点旋转路径https : //www.w3.org/TR /SVG/coords.html#TransformProperty对一些人有帮助。

The issue here though is that my paths coming out of Inkscape have coordinates like m 424.77397,-31.058733 in their user coordinate space.但这里的问题是,我从 Inkscape 出来的路径在他们的用户坐标空间中有像 m 424.77397,-31.058733 这样的坐标。 If you notice, at 15 degree rotation on the HoursHand I have rotate(15,590.36335,14.32942) and at 30 degrees I have rotate(30,508.58162,-6.1159341), the center of rotation on the transform has changed drastically on the x-axis.如果您注意到,在 HoursHand 旋转 15 度时,我有旋转(15,590.36335,14.32942),在 30 度时我有旋转(30,508.58162,-6.1159341),变换的旋转中心在 x 轴上发生了巨大变化。

So some angle-finding code needs to be applied to pre-determine where the center of rotation needs to be when rotating instead of the translate(~10,~-42) in the current user coordinate space, which is where I need help.所以需要应用一些寻角代码来预先确定旋转时需要旋转的中心在哪里,而不是在当前用户坐标空间中平移(~10,~-42),这是我需要帮助的地方。

The sane way to do this in Inkscape is to select a group node that has a "transform: translate(x, y)" attribute, and remove the transform.在 Inkscape 中执行此操作的明智方法是选择具有“transform: translate(x, y)”属性的组节点,然后移除该变换。 Then select the group's child nodes and position where the group node needed.然后选择组的子节点并放置组节点需要的位置。 On the Javascript side I needed to remember the center point positions for transformations before rotating.在 Javascript 方面,我需要在旋转之前记住转换的中心点位置。 The Hours, Minutes, and Seconds hand all share the same center point for rotation, which needs to be absolute positioned relative to the bounding box coordinates obtained with getBBox().时针、分针和秒针都共享相同的旋转中心点,需要相对于 getBBox() 获得的边界框坐标进行绝对定位。

Knowing how to do rotations in an SVG user coordinate system with a group that is translated and has a transformation center that is off-center could still be advantageous in some situations though.但是,知道如何在 SVG 用户坐标系中使用已平移且具有偏离中心的变换中心的组进行旋转在某些情况下仍然是有利的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM