与Raphael.js的弧文本

时间:2013-10-30 07:07:28

标签: javascript raphael

我正在尝试对文本实现圆弧效果,如下面的屏幕:

enter image description here

我尝试使用它几个小时,但无法让它正常工作,最大限度地我能够实现的是:

enter image description here

以下是我的代码中的代码段:

JSBin

有人可以指出我正确的方向吗?

//更新: 好的,我设法在其上设置了文本,但是如何旋转它以匹配图像?

拉斐尔JS:

var paper = Raphael("urp");

//var path = paper.path("M50,10 A40,40,0,1,1,49.9,10z");
//var path = paper.path("M 140, 300 C 180, 100, 420, 100, 460, 300").attr({stroke:"#ccc"});
//var path = paper.path("M10,10 L90,90");
//var c = paper.circle(50, 50, 40);

var path1 = paper.path(getCircletoPath(286, 318, 190)).attr({stroke:"#ccc"});
var message = "55,8% Да";
var txt1 = textOnPath(message, path1, 13, 1.3, 3, 3);

var path2 = paper.path(getCircletoPath(286, 318, 170)).attr({stroke:"#ccc"});
var message = "43,3% Нет";
var txt2 = textOnPath(message, path2, 13, 1.3, 3, 3);

var path3 = paper.path(getCircletoPath(286, 318, 150)).attr({stroke:"#ccc"});
var message = "0,4% Не знаю как связаться";
var txt3 = textOnPath(message, path3, 13, 1.3, 3, 3);

var path4 = paper.path(getCircletoPath(286, 318, 130)).attr({stroke:"#ccc"});
var message = "0,5% Не смог связаться";
var txt4 = textOnPath(message, path4, 13, 1.3, 3, 3);

txt1.transform("r45, 286, 31");

 function getCircletoPath(x, y, r) { // x and y are center and r is the radius
       var s = "M";
       s = s + "" + (x) + "," + (y-r) + "A"+r+","+r+",0,1,1,"+(x-0.1)+","+(y-r)+"z";
       //alert(s);
       return s;
   }

function textOnPath(message, path, fontSize, letterSpacing, kerning, geckoKerning) {
    var gecko = /rv:([^\)]+)\) Gecko\/\d{8}/.test(navigator.userAgent||'') ? true : false;

    var letters = [], places = [], messageLength = 0;
    for (var c=0; c < message.length; c++) {
        var letter = paper.text(0, 0, message[c]).attr({"text-anchor" : "middle"});
        var character = letter.attr('text'), kern = 0;
        letters.push(letter);

        if (kerning) {
            if(gecko && geckoKerning) {
                kerning = geckoKerning;
            }
            var predecessor = letters[c-1] ? letters[c-1].attr('text') : '';
            if (kerning[c]) {
                kern = kerning[c];
            } else if (kerning[character]) {
                if( typeof kerning[character] === 'object' ) {
                    kern = kerning[character][predecessor] || kerning[character]['default'] || 0;
                } else {
                    kern = kerning[character];
                }
            }
            if(kerning['default'] ) {
                kern = kern + (kerning['default'][predecessor] || 0);
            }            
        }

    messageLength += kern;
    places.push(messageLength);
    //spaces get a width of 0, so set min at 4px
    messageLength += Math.max(4.5, letter.getBBox().width);
}

if( letterSpacing ){
    if (gecko) {
        letterSpacing = letterSpacing * 0.83;
    }
} else {
    letterSpacing = letterSpacing || path.getTotalLength() /  messageLength;
}
fontSize = fontSize || 10 * letterSpacing;

for (c = 0; c < letters.length; c++) {
    letters[c].attr("font-size", fontSize + "px");
    p = path.getPointAtLength(places[c] * letterSpacing);
    var rotate = 'R' + (p.alpha < 180 ? p.alpha + 180 : p.alpha > 360 ? p.alpha - 360 : p.alpha )+','+p.x+','+p.y;
letters[c].attr({ x: p.x, y: p.y, transform: rotate });

}
}

CSS:

#urp { 
  background: url('http://img9.imageshack.us/img9/1980/13s4.png') no-repeat;
  background-position: 50px 120px;
} 

HTML:

<!DOCTYPE html>
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>

  <div id="urp">
  </div>

</body>
</html>

http://jsbin.com/UJIYAco/14/

1 个答案:

答案 0 :(得分:1)

我想在经过一天和几个小时的尝试各种解决方案后如何解决它。 最后一个例子是http://jsbin.com/UJIYAco/15/edit