Вот как я это сделал.Следующий код позволяет указать начальный и конечный угол, а также внутренний и внешний радиус (полезно для выполнения этих модных круговых диаграмм в стиле пончика).Решение не основано на аппроксимации кривой с отрезками линий и может быть анимировано в соответствии с примером часов, упомянутым в исходном вопросе.
Сначала создайте область рисования Рафаэля;в следующем примере предполагается, что в вашем HTML-файле есть div с идентификатором «raphael_paper»:
var paper = Raphael("raphael_paper", 800, 800);
к этому объекту Raphael мы добавляем пользовательский атрибут arc
, который принимает центр круга (x и yкоординаты), начальный угол, конечный угол, внутренний радиус и внешний радиус:
paper.customAttributes.arc = function (centerX, centerY, startAngle, endAngle, innerR, outerR) {
var radians = Math.PI / 180,
largeArc = +(endAngle - startAngle > 180);
// calculate the start and end points for both inner and outer edges of the arc segment
// the -90s are about starting the angle measurement from the top get rid of these if this doesn't suit your needs
outerX1 = centerX + outerR * Math.cos((startAngle-90) * radians),
outerY1 = centerY + outerR * Math.sin((startAngle-90) * radians),
outerX2 = centerX + outerR * Math.cos((endAngle-90) * radians),
outerY2 = centerY + outerR * Math.sin((endAngle-90) * radians),
innerX1 = centerX + innerR * Math.cos((endAngle-90) * radians),
innerY1 = centerY + innerR * Math.sin((endAngle-90) * radians),
innerX2 = centerX + innerR * Math.cos((startAngle-90) * radians),
innerY2 = centerY + innerR * Math.sin((startAngle-90) * radians);
// build the path array
var path = [
["M", outerX1, outerY1], //move to the start point
["A", outerR, outerR, 0, largeArc, 1, outerX2, outerY2], //draw the outer edge of the arc
["L", innerX1, innerY1], //draw a line inwards to the start of the inner edge of the arc
["A", innerR, innerR, 0, largeArc, 0, innerX2, innerY2], //draw the inner arc
["z"] //close the path
];
return {path: path};
};
теперь мы можем использовать это для рисования дуг определенной толщины, начиная и заканчивая везде, где мы хотим, чтобы они, например,.
var redParams = {stroke: "#f00", "stroke-width": 1, fill:"#eee"},
greenParams = {stroke: "#0f0", "stroke-width": 1, fill:"#eee"},
blueParams = {stroke: "#00f", "stroke-width": 1, fill:"#eee"},
cx = 300, cy = 300, innerRadius = 100, outerRadius = 250,
var red = paper.path().attr(redParams).attr({arc: [cx, cy, 0, 90, innerRadius, outerRadius]});
var green = paper.path().attr(greenParams).attr({arc: [cx, cy, 270, 320, innerRadius, outerRadius]});
var blue = paper.path().attr(blueParams).attr({arc: [cx, cy, 95, 220, innerRadius, outerRadius]});
В результате должны появиться три сегмента серой дуги с красными, синими и зелеными границами в 1 пиксель.