2013-11-19 5 views
1

Я пытаюсь заполнить границы круга, в зависимости от переменной, например, так:Заполните внешний круг, с Рафаэлем JS

enter image description hereenter image description here

Я нашел this example, но это не то, что я хочу. Я хочу, чтобы внешняя граница заполнялась снизу вверх, по обе стороны от круга.

Вот код, у меня есть:

var completion = '5%'; 

drawcircle("js-raphael-completion", completion); 

function drawcircle(div, rate) { 
    var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%"); 
    archtype.customAttributes.arc = function (xloc, yloc, value, total, R) { 
    var alpha = 360/total * value, 
     a = (90 - alpha) * Math.PI/180, 
     x = xloc + R * Math.cos(a), 
     y = yloc - R * Math.sin(a), 
     path; 
    if (total == value) { 
     path = [ 
      ["M", xloc, yloc - R], 
      ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R] 
     ]; 
    } else { 
     path = [ 
      ["M", xloc, yloc - R], 
      ["A", R, R, 0, +(alpha > 180), 1, x, y] 
     ]; 
    } 
    return { 
     path: path 
    }; 
    }; 

    // inner ring 
    var circle = archtype.circle("50%", "50%", "40%").attr({ 
     "stroke": "#2787d3", 
     "stroke-width": 1 
    }); 

    // text 
    var text = archtype.text("95%", "50%", rate).attr({ 
     'font-size': 14, 'font-family': 'Avenir', 
     "fill": "#2787d3" 
    }); 

    // outer ring (filling) 
    var my_arc = archtype.path().attr({ 
     "stroke": "#2787d3", 
     "stroke-width": 10, 
     arc: [100, 100, 0, 100, 50] 
    }); 

    // animation of outer ring 
    my_arc.animate({ 
    arc: [100, 100, 100, 100, 50] 
    }, 1000); 
} 

Смотреть демо: http://jsfiddle.net/SUBn6/

В настоящее время, потому что я не использую проценты для наружного кольца (закачка), он не центрирован с границей круг (внутренний).

Другой вопрос, который у меня есть, - это номер «5%». Он должен следить за внешним кольцом (заполнением), когда он заполняется снизу вверх ...

Любые идеи? Благодарю.

ответ

2

Похоже, у Рафаэля нет таких настроек для окончания штриха. Таким образом, другой подход к этому состоял бы в том, чтобы иметь две дуги и заполнить пространство между ними, чтобы имитировать штрих.

Это включает в себя немного больше геометрии :), но это должно работать:

var completion = '5%'; 

drawcircle("js-raphael-completion", completion); 

// JSFiddle needs not onload 
// window.onload = function() { 
// drawcircle("js-raphael-completion", completion); 
// }; 

function drawcircle(div, rate) { 
    var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%"); 
    archtype.customAttributes.arc = function (xloc, yloc, value, total, R,lineWidth) { 
     var alpha = 360/total * value, 
      a = value/total * Math.PI, 
      w = R * Math.sin(a), 
      h = R * Math.cos(a), 
      gamma = Math.asin(R/(R + lineWidth) * Math.sin(Math.PI/2 + a)), 
      beta = Math.PI/2 - a - gamma, 

      xOffset = (R + lineWidth) * Math.sin(beta)/Math.sin(Math.PI/2 + a), 
      x = xloc - R * Math.sin(a), 
      y = yloc + R * Math.cos(a), 
      path; 

     if (Math.abs(a - Math.PI/2) < 0.0001) { 
      xOffset = lineWidth; 
     } 

     if (total == value) { 
      path = [ 
       ["M", x, y], 
       ["A", R , R , 1, 1, 1, x - 0.01, y], 
       ["L", x - 0.01,y-lineWidth], 
       ["A", R + lineWidth, R + lineWidth, 1, 1, 0, x, y - lineWidth], 
       ["Z"] 

       /* 
       ["M", xloc, yloc - R], 
       ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R] 
       */ 
      ]; 
     } else { 
      path = [ 
       ["M", x, y], 
       ["A", R , R , 0, +(alpha > 180), 0, x + 2 * w, y], 
       ["L", x+ 2 * w + xOffset,y], 
       ["A", R + lineWidth, R + lineWidth, 0 , +(alpha > 180) , 1, x - xOffset, y], 
       ["Z"] 
      ]; 
     } 
     return { 
      path: path 
     }; 
    }; 

    // inner ring 
    var circle = archtype.circle(100, 100, 50).attr({ 
     "stroke": "#2787d3", 
      "stroke-width": 3 
    }); 

    // text 
    var text = archtype.text("95%", "50%", rate).attr({ 
     'font-size': 14, 
     'font-family': 'Avenir', 
      "fill": "#2787d3" 
    }); 

    // outer ring (filling) 
    var my_arc = archtype.path().attr({ 
     "stroke": "#FF0000", 
     "fill": "#2787d3", 
     "stroke-width" : 0, 
     arc: [100, 100, 0, 100, 51,10] 
    }); 

    // animation of outer ring 
    my_arc.animate({ 
     arc: [100, 100, 100, 100, 51,10] 
    }, 1000); 

} 

См http://jsfiddle.net/Xp77x/2/

2

Я думаю, что вы испортили вещи из космоса и греха :). В основном исходная точка дуги варьируется в зависимости от отношения (xloc - R * sin (a), yloc + R * cos (a)), а ширина также является переменной (2 * R * sin (a)).

Я изменил немного свой материал:

var completion = '5%'; 

drawcircle("js-raphael-completion", completion); 

// JSFiddle needs not onload 
// window.onload = function() { 
// drawcircle("js-raphael-completion", completion); 
// }; 

function drawcircle(div, rate) { 
    var archtype = Raphael(document.getElementsByClassName(div)[0], "90%", "90%"); 
    archtype.customAttributes.arc = function (xloc, yloc, value, total, R) { 
     var alpha = 360/total * value, 
      a = value/total * Math.PI, 
      w = R * Math.sin(a), 
      h = R * Math.cos(a), 
      x = xloc - R * Math.sin(a), 
      y = yloc + R * Math.cos(a), 
      path; 

     if (total == value) { 
      path = [ 
       ["M", xloc, yloc - R], 
       ["A", R, R, 0, 1, 1, xloc - 0.01, yloc - R] 
      ]; 
     } else { 
      path = [ 
       ["M", x, y], 
       ["A", R, R, 0, +(alpha > 180), 0, x + 2 * w, y] 
      ]; 
     } 
     return { 
      path: path 
     }; 
    }; 

    // inner ring 
    var circle = archtype.circle(100, 100, 50).attr({ 
     "stroke": "#2787d3", 
      "stroke-width": 1 
    }); 

    // text 
    var text = archtype.text("95%", "50%", rate).attr({ 
     'font-size': 14, 
     'font-family': 'Avenir', 
      "fill": "#2787d3" 
    }); 

    // outer ring (filling) 
    var my_arc = archtype.path().attr({ 
     "stroke": "#2787d3", 
      "stroke-width": 10, 
     arc: [100, 100, 0, 100, 50] 
    }); 

    // animation of outer ring 
    my_arc.animate({ 
     arc: [100, 100, 100, 100, 55] 
    }, 1000); 
} 

смотри: http://jsfiddle.net/Xp77x/1/

Однако я использовал абсолютные координаты. Чтобы иметь относительные координаты, вам нужно немного разобрать вход для% и перевести его на холст 0-100.

+0

Спасибо за это. Пара проблем. Когда внешний круг начинает заполняться, на внутреннем круге есть некоторое совпадение. Но это фиксировано ближе к концу (вверху): http://oi41.tinypic.com/x0occ0.jpg. И вторая проблема связана с Рафаэлем. Возможно ли сделать путь горизонтальным, а не вращаться вокруг круга? Трудно объяснить (см. Скриншот выше) ... Как если бы вы заполняли эту пустую границу жидкостью ... – Alex

Смежные вопросы