mousemove/touchmove 错误导致的 SVG 角度旋转

SVG angle rotation by mousemove/touchmove bug

我想用一根手指将 svg 圆形旋转 mousemove/touchmove。

我尝试了很多 js 脚本(例如 Touchy Wheel Demo and Rotate Dial Demo),它们的示例运行完美,但是当我尝试我的示例时,我总是看到两个错误:

  1. 旋转仅在圆形的下部有效,在顶部 - 它是反向旋转。
  2. 旋转速度非常慢(在演示轮中强烈遵循 mouse/finger)。

我的演示:https://jsfiddle.net/0L87uabc/8/ (plz see how it work on author's demo page之前)

我也尝试了这个简单的例子-结果与上面类似:

var dragging = false
$(function() {
    var circles = ['circle-l1', 'circle-l2', 'circle-l3', 'circle-l4', 'circle-l5', 'circle-l6', 'circle-l7'];
    $.each(circles, function(ind, val) {
        var target = $('#'+val)
        target.mousedown(function() {
            dragging = true
        })
        $(document).mouseup(function() {
            dragging = false
        })
        target.mousemove(function(e) {
            if (dragging) {
                var mouse_x = e.pageX;
                var mouse_y = e.pageY;
                var radians = Math.atan2(mouse_x - 10, mouse_y - 10);
                var degree = (radians * (180 / Math.PI) * -1) + 90;
                target.css('transform', 'rotate(' + degree + 'deg)');
            }
        });
    });
});

Domo2:https://jsfiddle.net/0L87uabc/10/

你能解释一下,为什么我的 svg 不能正确旋转以及如何修复它(或者你知道最好的脚本)?

关于第二个例子:

var degree = (radians * (180 / Math.PI) * -1) + 90;

我将 + 90 更改为 + 180,这允许在上半部分进行旋转。此外,从上面的行中删除 (180 / Math.PI) 可能会帮助您获得所需的结果。

对于速度,您可以改变此行中的值:

Math.atan2(mouse_x - 10, mouse_y - 10);

我设置为mouse_x - 100, mouse_y - 100,速度快多了

您也许可以使用 SMIL 规范。看看这里有什么帮助 CSS Tricks.

您需要用圆心减去当前指针位置,得到指针相对于圆心的度数。 这两个值需要在同一坐标系中,因此您必须将指针位置转换为目标 (parentNode) 坐标系。

var dragging = false
$(function() {
    var circles = ['circle-l1', 'circle-l2', 'circle-l3', 'circle-l4', 'circle-l5', 'circle-l6', 'circle-l7'];
    $.each(circles, function(ind, val) {
        var target = $('#'+val)
        target.mousedown(function() {
            dragging = true
        })
        $(document).mouseup(function() {
            dragging = false
        })
        target.mousemove(function(e) {
            if (dragging) {
                var ctm=target[0].parentNode.getScreenCTM()

                var p=document.getElementById("rus-front").createSVGPoint()

                p.x=e.clientX
                p.y=e.clientY
                p=p.matrixTransform(ctm.inverse())

                var mouse_x = e.pageX;
                var mouse_y = e.pageY;
                var radians = Math.atan2(1990 - p.x , 1900 - p.y);
                var degree = (radians * (180 / Math.PI) * -1) + 90;
                target.css('transform', 'rotate(' + degree + 'deg)');
            }
     });
    });
});
html, body, #circular {
 width: 100%;
 height: 100%;
}
#circular {
 position: relative;
 text-align: left;
 height: 100%;
 width: auto;
 padding-left: 7%;
}
 #circular svg {
  display: inline-block;
  height: 100%;
     width: auto;
 }
 #circular [id^=circle-l] {
  transform-origin: center center;
  cursor: pointer;
 }
 #circular #circle-l1 {
  transform-origin: 52% 50%;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="circular"><svg version="1.1" id="rus-front" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
  width="4050px" height="3940px" viewBox="0 0 4050 3940" enable-background="new 0 0 4050 3940" xml:space="preserve">
<g id="circle-l7" opacity="0.9">
 <g>
  <defs>
   <rect id="SVGID_1_" x="321.191" y="211.45" width="3361.599" height="3361.596"/>
  </defs>
  <clipPath id="SVGID_2_">
   <use xlink:href="#SVGID_1_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_2_)" fill="#062D84" d="M3648.641,1553.511c-22.083-107.917-55.034-214.069-97.939-315.505
   c-42.125-99.594-94.263-195.653-154.968-285.508c-60.128-89.001-129.181-172.693-205.241-248.753
   c-76.058-76.059-159.75-145.112-248.752-205.239c-89.854-60.705-185.914-112.844-285.508-154.969
   c-101.436-42.904-207.587-75.855-315.505-97.938c-110.731-22.659-224.699-34.148-338.738-34.148
   c-114.04,0-228.007,11.489-338.739,34.148c-107.917,22.083-214.068,55.034-315.504,97.938
   c-99.594,42.125-195.654,94.264-285.508,154.969c-89.001,60.127-172.694,129.18-248.753,205.239
   c-76.059,76.06-145.112,159.752-205.24,248.753c-60.705,89.855-112.843,185.914-154.968,285.508
   c-42.904,101.436-75.855,207.588-97.938,315.505c-22.66,110.731-34.148,224.699-34.148,338.737
   c0,114.041,11.488,228.008,34.148,338.738c22.083,107.918,55.034,214.068,97.938,315.505
   c42.125,99.595,94.263,195.653,154.968,285.507c60.128,89.002,129.181,172.694,205.24,248.754
   c76.059,76.058,159.752,145.111,248.753,205.239c89.854,60.705,185.914,112.843,285.508,154.968
   c101.436,42.905,207.587,75.856,315.504,97.939c110.732,22.659,224.699,34.147,338.739,34.147
   c114.039,0,228.007-11.488,338.738-34.147c107.918-22.083,214.069-55.034,315.505-97.939
   c99.594-42.125,195.653-94.263,285.508-154.968c89.002-60.128,172.694-129.181,248.752-205.239
   c76.061-76.06,145.113-159.752,205.241-248.754c60.705-89.854,112.843-185.912,154.968-285.507
   c42.905-101.437,75.856-207.587,97.939-315.505c22.659-110.73,34.146-224.697,34.146-338.738
   C3682.787,1778.209,3671.3,1664.242,3648.641,1553.511z M2259.281,3514.882c-86.615,13.965-175.199,21.046-263.291,21.046
   c-67.508,0-135.711-4.184-202.811-12.445c-32.126-1.359-57.291-27.626-57.291-59.798c0-33.009,26.855-59.863,59.864-59.863
   c4.107,0,8.224,0.423,12.323,1.271c64.201,8.121,129.535,12.24,194.187,12.24c79.058,0,158.538-6.093,236.324-18.125
   c4.522-1.082,9.147-1.629,13.743-1.629c32.457,0,58.864,26.405,58.864,58.862
   C2311.194,3486.248,2288.896,3511.371,2259.281,3514.882z M2001.99,3387.884c-826.017,0-1495.636-669.618-1495.636-1495.636
   S1175.974,396.612,2001.99,396.612c826.018,0,1495.636,669.619,1495.636,1495.636S2828.008,3387.884,2001.99,3387.884z"/>
 </g>
</g>
<g id="circle-l6" opacity="0.9">
 <g>
  <defs>
   <rect id="SVGID_3_" x="504.111" y="394.469" width="2995.759" height="2995.558"/>
  </defs>
  <clipPath id="SVGID_4_">
   <use xlink:href="#SVGID_3_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_4_)" fill="#6250CC" d="M2003.554,3390.027c-100.32-0.001-201.47-10.251-300.639-30.465
   c-198.086-40.374-382.338-118.337-547.644-231.722c-79.449-54.496-154.03-117.105-221.672-186.089
   c-66.997-68.327-127.773-143.501-180.638-223.434c-52.865-79.932-98.255-165.28-134.91-253.676
   c-37.007-89.249-65.431-182.384-84.483-276.82c-39.643-196.496-39.271-396.564,1.105-594.649
   c35.365-173.511,99.97-337.23,192.018-486.609c88.944-144.342,201.223-271.788,333.718-378.799
   c131.429-106.151,278.554-188.84,437.287-245.771c161.934-58.08,331.079-87.528,502.734-87.528
   c100.312,0,201.462,10.249,300.639,30.463c198.085,40.376,382.339,118.34,547.643,231.725
   c79.448,54.497,154.028,117.106,221.669,186.089c66.997,68.326,127.773,143.5,180.638,223.434
   c52.866,79.936,98.256,165.285,134.908,253.678c37.006,89.242,65.43,182.378,84.483,276.821
   c39.642,196.498,39.269,396.567-1.106,594.65c-35.365,173.51-99.969,337.227-192.017,486.607
   c-88.943,144.343-201.221,271.789-333.716,378.8c-131.427,106.149-278.551,188.839-437.285,245.77
   c-161.927,58.077-331.064,87.525-502.715,87.525H2003.554z M2597.964,2868.633c-5.396,0-10.772,1.368-15.55,3.957l-81.45,44.149
   c-7.677,4.16-13.273,11.062-15.761,19.435c-2.483,8.369-1.561,17.209,2.6,24.887l123.196,233.408
   c5.718,10.546,16.741,17.101,28.765,17.101c5.396,0,10.771-1.367,15.544-3.955l81.453-44.149
   c7.678-4.16,13.274-11.062,15.761-19.434c2.485-8.371,1.563-17.21-2.598-24.888l-123.197-233.411
   C2621.01,2875.188,2609.988,2868.633,2597.964,2868.633 M2001.029,784.633c-126.831,0-251.81,21.764-371.463,64.686
   c-117.289,42.075-226,103.185-323.113,181.632c-97.899,79.082-180.856,173.262-246.566,279.923
   c-68.004,110.384-115.724,231.362-141.836,359.572c-29.807,146.358-30.058,294.175-0.747,439.345
   c14.088,69.772,35.1,138.58,62.452,204.511c27.091,65.307,60.637,128.361,99.706,187.414
   c39.07,59.054,83.982,114.588,133.489,165.062c49.983,50.958,105.093,97.207,163.799,137.461
   c122.142,83.752,258.285,141.332,404.642,171.14c73.223,14.912,147.9,22.474,221.956,22.474
   c126.83,0,251.808-21.763,371.463-64.687c117.289-42.074,226-103.185,323.112-181.632
   c97.901-79.082,180.855-173.263,246.564-279.923c68.004-110.384,115.726-231.36,141.836-359.57
   c29.807-146.358,30.059-294.176,0.748-439.346c-14.088-69.777-35.1-138.585-62.452-204.513
   c-27.092-65.306-60.636-128.361-99.706-187.413c-39.064-59.047-83.977-114.581-133.488-165.063
   c-49.982-50.957-105.092-97.206-163.799-137.461c-122.143-83.753-258.285-141.332-404.644-171.14
   C2149.766,792.194,2075.091,784.633,2001.029,784.633"/>
 </g>
</g>
<g id="circle-l5" opacity="0.9">
 <g>
  <defs>
   
    <rect id="SVGID_5_" x="892.197" y="782.456" transform="matrix(-0.6474 -0.7622 0.7622 -0.6474 1855.9 4643.1074)" width="2219.588" height="2219.584"/>
  </defs>
  <clipPath id="SVGID_6_">
   <use xlink:href="#SVGID_5_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_6_)" fill="#600875" d="M1156.158,2610.723c-96.975-114.171-168.693-243.922-213.164-385.649
   c-21.373-68.118-36.2-138.737-44.064-209.897c-7.79-70.483-8.821-142.11-3.065-212.892
   c5.756-70.782,18.346-141.301,37.422-209.599c19.259-68.954,45.3-136.25,77.4-200.019
   c66.788-132.68,158.534-249.137,272.691-346.136c114.17-97.012,243.927-168.762,385.665-213.257
   c68.122-21.385,138.747-36.22,209.913-44.092c70.488-7.798,142.123-8.835,212.911-3.083
   c70.789,5.751,141.315,18.339,209.621,37.414c68.962,19.258,136.266,45.3,200.043,77.402
   c132.695,66.792,249.166,158.548,346.177,272.718l0.116,0.136c96.978,114.167,168.699,243.916,213.17,385.642
   c21.375,68.118,36.2,138.737,44.065,209.898c7.791,70.484,8.819,142.111,3.065,212.892
   c-5.756,70.783-18.347,141.303-37.423,209.603c-19.261,68.954-45.302,136.25-77.404,200.02
   c-66.788,132.682-158.536,249.14-272.693,346.14c-114.17,97.012-243.925,168.761-385.663,213.256
   c-68.124,21.385-138.749,36.219-209.914,44.093c-70.49,7.797-142.123,8.834-212.912,3.083
   c-70.789-5.754-141.316-18.341-209.622-37.415c-68.961-19.259-136.265-45.3-200.041-77.402
   c-132.695-66.792-249.166-158.548-346.177-272.719L1156.158,2610.723z M2715.987,1280.863
   c-82-96.535-180.455-174.122-292.626-230.607c-108.346-54.557-224.866-87.234-346.322-97.121
   c-121.456-9.888-241.726,3.511-357.47,39.825c-119.831,37.597-229.538,98.239-326.073,180.24
   c-96.536,82.001-174.123,180.454-230.608,292.626c-54.557,108.347-87.233,224.866-97.123,346.323
   c-9.887,121.456,3.512,241.726,39.827,357.47c37.597,119.831,98.238,229.538,180.239,326.073
   c82.002,96.537,180.455,174.124,292.627,230.608c108.347,54.558,224.866,87.234,346.322,97.123
   c121.457,9.886,241.727-3.513,357.471-39.828c119.831-37.597,229.538-98.238,326.074-180.239s174.123-180.455,230.607-292.626
   c54.558-108.347,87.234-224.866,97.122-346.321c9.888-121.457-3.512-241.727-39.826-357.471
   C2858.63,1487.107,2797.989,1377.399,2715.987,1280.863 M932.392,1981.417c0.631,10.614,4.611,20.516,11.509,28.636
   c8.432,9.922,20.224,15.967,33.201,17.022c12.979,1.053,25.591-3.009,35.514-11.441c11.87-10.086,18.233-25.402,17.022-40.968
   l-0.111-1.425l0.168-0.011c-9.578-113.265,0.454-226.354,29.828-336.173l-0.136-0.038l0.339-1.346
   c3.85-15.271,0.078-31.536-10.091-43.507c-8.44-9.931-20.23-15.977-33.209-17.031c-12.978-1.055-25.589,3.008-35.512,11.439
   c-7.291,6.196-12.555,14.317-15.224,23.483l-0.39,1.342l-0.029-0.008c-32.236,120.369-43.348,244.352-33.031,368.553l0.035-0.003
   L932.392,1981.417z"/>
 </g>
</g>
<path id="circle-l4" fill="#E21E26" d="M2001.792,2834.114c-33.627,0-67.734-1.843-101.375-5.478
 c-125.319-13.536-245.186-51.739-356.269-113.548c-111.077-61.809-206.732-143.523-284.306-242.877
 c-74.922-95.964-129.908-204.257-163.431-321.871c-33.52-117.617-43.885-238.627-30.809-359.668
 c13.535-125.316,51.738-245.18,113.547-356.266c61.821-111.09,143.537-206.745,242.88-284.306
 c95.962-74.925,204.255-129.911,321.87-163.431c84.49-24.079,171.398-36.288,258.312-36.288c33.621,0,67.722,1.842,101.357,5.475
 c125.315,13.539,245.18,51.744,356.266,113.554c111.088,61.811,206.741,143.527,284.305,242.879
 c74.927,95.962,129.913,204.254,163.432,321.869c33.52,117.614,43.887,238.624,30.811,359.667
 c-13.537,125.317-51.74,245.184-113.547,356.268c-61.816,111.087-143.531,206.741-242.877,284.305
 c-95.961,74.923-204.254,129.908-321.873,163.43C2175.601,2821.906,2088.698,2834.114,2001.792,2834.114 M2000.197,1254.975
 c-51.842,0-103.776,6.416-154.361,19.07c-82.859,20.729-159.761,57.504-228.573,109.305
 c-71.914,54.133-130.386,121.136-173.79,199.146c-59.259,106.502-86.722,227.296-79.419,349.322
 c7.491,125.146,51.469,244.454,127.179,345.027c51.802,68.819,115.533,125.43,189.422,168.264
 c71.371,41.374,149.164,68.222,231.219,79.798c29.832,4.208,60.082,6.342,89.91,6.343h0.015c51.834,0,103.762-6.416,154.35-19.068
 c82.851-20.728,159.755-57.503,228.574-109.307c71.91-54.135,130.382-121.138,173.789-199.148
 c59.258-106.496,86.72-227.288,79.418-349.32c-7.484-125.133-51.46-244.441-127.174-345.026
 c-51.8-68.813-115.533-125.426-189.425-168.268c-71.373-41.374-149.166-68.221-231.222-79.795
 C2060.272,1257.108,2030.022,1254.975,2000.197,1254.975 M1322.123,1960.018c-0.796,0-1.602,0.061-2.395,0.182l-207.379,31.588
 c-4.887,0.74-9.067,3.645-11.468,7.968c-1.72,3.089-2.346,6.575-1.812,10.08c0.638,4.188,2.865,7.874,6.272,10.38
 c2.744,2.02,5.978,3.087,9.352,3.087c0.805,0,1.619-0.063,2.422-0.185l207.382-31.592c4.883-0.738,9.063-3.644,11.47-7.969
 c1.719-3.089,2.344-6.572,1.81-10.075C1336.606,1965.806,1329.876,1960.018,1322.123,1960.018"/>
<g id="circle-l3" opacity="0.9">
 <g>
  <defs>
   
    <rect id="SVGID_7_" x="1359.715" y="1249.978" transform="matrix(0.0042 -1 1 0.0042 101.4478 3886.3657)" width="1284.55" height="1284.54"/>
  </defs>
  <clipPath id="SVGID_8_">
   <use xlink:href="#SVGID_7_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_8_)" fill="#420351" d="M2387.222,1378.378c-283.801-212.757-686.34-155.166-899.097,128.634
   c-212.759,283.802-155.166,686.346,128.634,899.1c283.802,212.76,686.343,155.166,899.101-128.637
   C2728.614,1993.674,2671.025,1591.134,2387.222,1378.378 M1827.783,2459.995c-11.949,15.937-33.229,20.743-50.551,12.521
   c-51.833-20.053-101.82-47.429-148.475-82.406c-32.185-24.127-61.344-50.792-87.433-79.493
   c-15.5-14.118-18.02-37.974-5.183-55.095c13.637-18.19,39.437-21.882,57.63-8.243c3.044,2.283,5.672,4.911,7.893,7.782
   c22.746,25.08,48.18,48.374,76.281,69.442c40.122,30.079,83.078,53.696,127.622,71.057c4.911,1.322,9.655,3.571,13.97,6.806
   C1837.726,2416.003,1841.419,2441.805,1827.783,2459.995 M1886.993,2393.569c-276.461-63.945-448.74-339.896-384.794-616.359
   c63.945-276.46,339.897-448.739,616.359-384.794c276.458,63.946,448.737,339.896,384.792,616.359
   C2439.406,2285.237,2163.452,2457.515,1886.993,2393.569"/>
 </g>
</g>
<g id="circle-l2" opacity="0.9">
 <g>
  <defs>
   
    <rect id="SVGID_9_" x="1486.775" y="1377.038" transform="matrix(0.2791 -0.9602 0.9602 0.2791 -373.8815 3286.4509)" width="1030.43" height="1030.419"/>
  </defs>
  <clipPath id="SVGID_10_">
   <use xlink:href="#SVGID_9_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_10_)" fill="#EE4723" d="M1505.475,1754.715c18.568-67.027,49.707-128.417,92.553-182.457
   c41.385-52.2,91.893-95.38,150.124-128.348c58.227-32.97,121.241-54.064,187.295-62.696c68.385-8.934,137.046-4.05,204.072,14.517
   c66.957,18.542,128.286,49.638,182.286,92.417c52.158,41.317,95.326,91.743,128.308,149.879
   c32.977,58.135,54.113,121.056,62.818,187.018c9.013,68.286,4.244,136.863-14.18,203.829l-0.25,0.905
   c-18.568,67.026-49.707,128.416-92.551,182.455c-41.385,52.198-91.893,95.381-150.124,128.35
   c-58.229,32.968-121.244,54.061-187.294,62.689c-68.387,8.935-137.049,4.052-204.075-14.514
   c-66.954-18.543-128.285-49.639-182.284-92.418c-52.16-41.313-95.331-91.741-128.308-149.877
   c-32.98-58.134-54.115-121.054-62.821-187.018c-9.011-68.282-4.243-136.859,14.177-203.82L1505.475,1754.715z M1814.624,1971.048
   c0.972-3.53,0.747-7.189-0.65-10.584c-1.669-4.053-4.816-7.217-8.864-8.906c-4.048-1.685-8.508-1.695-12.561-0.029
   l-241.407,99.339c-4.729,1.946-8.224,5.896-9.581,10.834c-0.973,3.53-0.745,7.193,0.654,10.591
   c1.667,4.055,4.81,7.216,8.858,8.904c4.048,1.685,8.507,1.696,12.563,0.027l241.404-99.339
   C1809.771,1979.938,1813.267,1975.987,1814.624,1971.048 M2176.272,1940.152c17.249-62.7-0.518-130.235-46.365-176.256
   c-70.575-70.835-185.62-71.046-256.454-0.479c-22.334,22.25-38.534,49.982-46.844,80.199
   c-17.249,62.702,0.518,130.24,46.362,176.259c34.19,34.315,79.692,53.264,128.129,53.352c48.438,0.09,94.013-18.69,128.329-52.875
   C2151.764,1998.098,2167.963,1970.367,2176.272,1940.152"/>
 </g>
</g>
<g id="circle-l1" opacity="0.9">
 <g>
  <defs>
   <rect id="SVGID_11_" x="1818.64" y="1708.893" width="366.701" height="366.71"/>
  </defs>
  <clipPath id="SVGID_12_">
   <use xlink:href="#SVGID_11_"  overflow="visible"/>
  </clipPath>
  <path clip-path="url(#SVGID_12_)" fill="#600875" d="M2001.76,2075.607c-31.688-0.003-63.063-8.355-90.733-24.156
   c-87.78-50.125-118.418-162.321-68.297-250.104c32.564-57.027,93.631-92.453,159.369-92.453c31.683,0,63.058,8.353,90.734,24.157
   c42.525,24.281,73.049,63.668,85.95,110.907c12.899,47.238,6.631,96.672-17.651,139.198
   c-32.563,57.025-93.627,92.452-159.356,92.452H2001.76z M1937.229,1983.269c-9.241,0-17.825,4.979-22.402,12.992
   c-3.413,5.976-4.294,12.923-2.48,19.563c1.813,6.641,6.103,12.177,12.081,15.591c0.832,0.474,1.746,0.925,2.719,1.34
   c22.98,12.237,48.777,18.694,74.648,18.694c12.949,0,25.902-1.588,38.5-4.719c7.924-1.184,14.697-5.813,18.638-12.71
   c3.412-5.976,4.294-12.923,2.48-19.563c-1.813-6.641-6.103-12.176-12.08-15.586c-3.882-2.22-8.286-3.393-12.736-3.393
   c-2.396,0-4.783,0.334-7.097,0.992c-9.037,2.39-18.337,3.6-27.65,3.6c-17.795,0-35.51-4.502-51.231-13.019l-0.149-0.092
   c-0.161-0.103-0.322-0.203-0.488-0.298C1946.089,1984.442,1941.681,1983.269,1937.229,1983.269"/>
 </g>
</g>
</svg></div>