如何围绕圆圈移动元素

时间:2017-05-17 20:26:39

标签: javascript svg

我是新来的;]。如何计算translateX&在.loader-marker元素的matrix()中的translateY位置。我有角度,它可能是0,60,120,180,240,300,360度。 .loader标记应围绕最大的圆圈滚动并标记数字。我可以根据角度计算歪斜和比例,但我找不到一种方法来根据我的方式计算平移(XY)位置。代码示例在这里

var loadedAngel = 60;
var angelRadians = 60 * (Math.PI / 180);
var radius = 178;
var cx = 260;
var cy = 264;
var matrix=[1,0,0,1,0,0];

var svg = document.getElementById("box-loader-svg");
var loader = document.getElementById("path-loader");
var marker = document.getElementById('loader-marker');

document.getElementById("path-loader").setAttribute("d", describeArc(cx, cy, radius, 0, loadedAngel));

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ].join(" ");

    return d;       
}

// for example
// rotate 60 degrees clockwise from 0 degrees
// so the .loader-marker element should mark text "2nd" in my case
rotate(loadedAngel*Math.PI/180);

// plug our transform array into the <g>
marker.setAttribute('transform', 'matrix(' + matrix.join(', ') + ')');

// do the scale to the array
function scale(x,y){
    matrix[0] *= x;
    matrix[1] *= x;
    matrix[2] *= y;
    matrix[3] *= y;    
}

// do the rotate to the array
function rotate(radians){
    var cos = Math.cos(radians);
    var sin = Math.sin(radians);
    var m11 = matrix[0] * cos + matrix[2] * sin;
    var m12 = matrix[1] * cos + matrix[3] * sin;
    var m21 = -matrix[0] * sin + matrix[2] * cos;
    var m22 = -matrix[1] * sin + matrix[3] * cos;
    matrix[0] = m11;
    matrix[1] = m12;
    matrix[2] = m21;
    matrix[3] = m22;   
}
body {
  background: #000;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 520 520" class="box-loader-svg">
    <g class="loader-circles">
        <g transform="rotate(-90 260 264)">
            <circle class="loader-outer"
                    cx="260"
                    cy="264"
                    r="200"
                    fill="none"
                    stroke="#64d3de"
                    stroke-miterlimit="10"
                    opacity="0.6"
                    transform="matrix(1,0,0,1,0,0)"
                    style="stroke-dashoffset: 1e-05; stroke-dasharray: none;">
            </circle>
        </g>
        <g transform="rotate(-90 260 264)">
            <circle class="loader-track"
                    cx="260"
                    cy="264"
                    r="178"
                    fill="none"
                    stroke="#50afb8"
                    stroke-miterlimit="10"
                    stroke-width="20"
                    transform="matrix(1,0,0,1,0,0)"
                    style="stroke-dashoffset: 1e-05; stroke-dasharray: none;">
            </circle>
        </g>
        <g transform="rotate(-90 260 264)">
            <circle class="loader-track-perc"
                    cx="260"
                    cy="264"
                    r="178"
                    fill="none"
                    stroke="#fff"
                    stroke-miterlimit="10"
                    stroke-width="20"
                    transform="matrix(1,0,0,1,0,0)"
                    style="stroke-dashoffset: 0; display: none;">
            </circle>
        </g>
        <g>
            <path id="path-loader" fill="none" stroke="#FFFFFF" stroke-miterlimit="10" stroke-width="20" d="">
            </path>
        </g>
    </g>
    <g class="loader-stages" fill="#64d3de">
        <rect x="260" y="55" width="1" height="9" transform="matrix(1,0,0,1,0,0)" style="transform-origin: 0px 0px 0px;"></rect>
        <rect x="260" y="55" width="1" height="9" transform="matrix(0.5,-0.86602,0.86602,0.5,-98.38070659909181,357.5996176858462)" style="transform-origin: 0px 0px 0px;"></rect>
        <rect x="260" y="55" width="1" height="9" transform="matrix(-0.5,-0.86602,0.86602,-0.5,162.11929340090836,621.5996176858464)" style="transform-origin: 0px 0px 0px;"></rect>
        <rect x="260" y="55" width="1" height="9" transform="matrix(-1,0,0,-1,521,528)" style="transform-origin: 0px 0px 0px;"></rect>
        <rect x="260" y="55" width="1" height="9" transform="matrix(-0.49999,0.86602,-0.86602,-0.49999,619.3807065990918,170.40038231415366)" style="transform-origin: 0px 0px 0px;"></rect>
        <rect x="260" y="55" width="1" height="9" transform="matrix(0.5,0.86602,-0.86602,0.5,358.88070659909175,-93.59961768584628)" style="transform-origin: 0px 0px 0px;"></rect>
    </g>
    <g class="loader-stages-text" fill="#fff" font-size="18">
        <text x="250" y="44">6th</text>
        <text x="445" y="155">1st</text>
        <text x="445" y="385">2nd</text>
        <text x="250" y="496">3th</text>
        <text x="50" y="385">4th</text>
        <text x="50" y="155">5th</text>
    </g>
    <g class="voc-word">
        <text x="50%"
              y="50%"
              stroke="none"
              text-anchor="middle"
              stroke-width="1px"
              dy=".3em"
              fill="#fff"
        >
            text
        </text>
    </g>
    <g id="loader-marker">
        <g class="loader-marker-pointer">
            <circle cx="260" cy="35" fill="none" r="20" stroke="#fff" stroke-width="2"></circle>
        </g>
        <rect class="loader-marker-line" fill="#fff" height="35" width="2" x="260" y="55"></rect>
    </g>
</svg>

1 个答案:

答案 0 :(得分:0)

您的轮换中心位于(260, 264)。例如,您的.loader-marker最初可能会以(260, 35)(大约)位于传奇&#34; 6th&#34;的中心显示:

<g class="loader-marker" stroke="#fff" stroke-width="2" fill="none">
    <circle x="260" y="35" r="20" />
    <path d="M 260 55 260 90" transform="rotate(45, 260, 35)" />
</g>

然后将标记放在图例中#34; nth&#34;没有它失去方向可以表示为

var marker = document.getElementById('loader-marker');

var cx = 260,
    cy = 264,
    mx = 260,
    my = 35;

function positionMarker (number) {
    var angle = 60 * number;
    var transform = 'rotate(' + angle + ' cx cy) rotate(-' + angle + ' mx my)';
    marker.setAttribute('transform', transform);
}