我写了这段代码。之前我用纯js,css,html5编程了它,但它在iDevices上看起来很怪异所以我想我也可以在画布上轻松制作它。但我遇到了以下问题。
您可以看到检查文字角度的情况。我试了很多东西,但仍然无法将文字颠倒在“图表”的另一边。有人可以帮我吗?
$(document).ready(function() {
var orange = "#ef5e09";
var c = $("#myChart");
var ctx = c.get(0).getContext("2d");
var dData = function() {
return Math.round(Math.random() * 90) + 10
};
var data = {
labels: ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"],
data: [dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData(), dData()]
}
function draw() {
//check canvas parent width and calculate dimensions
c.css("width", c.parent().width());
c.css("height", c.parent().width());
ctx.canvas.width = c.parent().width();
ctx.canvas.height = ctx.canvas.width;
var d = {
cX: ctx.canvas.width / 2,
cY: ctx.canvas.width / 2,
width: ctx.canvas.width,
height: ctx.canvas.height,
lineWidth: ctx.canvas.width * 0.00934579,
radius: ctx.canvas.width * 0.03,
cW: ctx.canvas.width * 0.002,
fW: ctx.canvas.width * 0.28
};
// draw bg circles
for (var i = 10; i > 0; i--) {
ctx.beginPath();
ctx.arc(d.cX, d.cY, i * d.radius, 0, 2 * Math.PI, false);
if (i % 2) {
ctx.fillStyle = '#f6f7f8';
ctx.fill();
} else {
ctx.fillStyle = '#fff';
ctx.fill();
}
ctx.lineWidth = d.cW;
ctx.strokeStyle = '#babbbc';
ctx.stroke();
}
var sa = 2 * Math.PI / data.data.length;
var font = d.width * (18 / 1000) + 'px Verdana';
for (var i = 0; i < data.data.length; i++) {
var v = 10 * d.radius * (data.data[i] / 100);
var nX = d.cX + v * Math.cos(i * sa);
var nY = d.cY + v * Math.sin(i * sa);
ctx.beginPath();
ctx.moveTo(d.cX, d.cY);
ctx.lineTo(nX, nY);
ctx.strokeStyle = orange;
ctx.lineWidth = d.lineWidth;
ctx.stroke();
var l = data.labels[i];
var nX = Math.floor(d.cX + 11 * d.radius * Math.cos(i * sa));
var nY = Math.floor(d.cY + 11 * d.radius * Math.sin(i * sa));
console.log(l + " [" + nX + ":" + nY + "]");
ctx.save();
var origAlign = ctx.textAlign;
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
//here's the edited part where I tried to rotate the text in place
ctx.translate(-ctx.measureText(l).width,d.width*(18/1000)/2);
ctx.rotate(Math.PI);
//end of edited part
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
}
ctx.restore();
}
}
draw();
$(window).resize(draw);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="col-xs-6">
<canvas id="myChart"></canvas>
</div>
答案 0 :(得分:1)
测量文字时,需要在测量文字之前设置字体。
当围绕非原点的点(例如文本中间)旋转时,您需要翻译,旋转,翻译。
在您的代码中,尝试替换...
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
//here's the edited part where I tried to rotate the text in place
ctx.translate(-ctx.measureText(l).width,d.width*(18/1000)/2);
ctx.rotate(Math.PI);
//end of edited part
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
...与
if (i * sa > Math.PI / 2 && i * sa < 1.5 * Math.PI) {
ctx.translate(d.cX, d.cY);
ctx.rotate((10 - i) * sa);
ctx.font = font;
ctx.translate(10.5 * d.radius + ctx.measureText(l).width / 2, 0);
ctx.rotate(Math.PI);
ctx.translate(-10.5 * d.radius - ctx.measureText(l).width / 2, 0);
ctx.fillStyle = orange;
ctx.fillText(l, 10.5 * d.radius, 5);
} else {
答案 1 :(得分:1)
以下是如何使用转换围绕中心点旋转文本,同时使文本保持任意角度。
您可以使用context.translate
+ context.rotate
以一定角度从中心点向外推送文字。
您可以使用context.scale
根据需要垂直或水平翻转文字。
您可以使用context.textBaseline
将文本显示与中心点保持一致的距离,无论其角度如何。
以下是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var angle=0;
var angleIncrement=Math.PI/180;
var count=0;
var cx=75;
var cy=75;
var radius=3;
var PI2=Math.PI*2;
ctx.beginPath();
ctx.arc(cx,cy,3,0,PI2);
ctx.fill();
requestAnimationFrame(animate);
function animate(time){
var PI2=Math.PI*2;
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
ctx.arc(cx,cy,3,0,PI2);
ctx.fill();
drawLabelAtAngle('Label #'+count,cx,cy,angle,radius);
angle+=angleIncrement;
angle=(angle+PI2)%PI2;
count++;
requestAnimationFrame(animate);
}
function drawLabelAtAngle(text,x,y,angle,offset){
// calc the angle clampled between 0 & PI*2
var normA=(angle+Math.PI*2)%(Math.PI*2);
// get ready to flip the text if it is on the left side
if(normA>=Math.PI*3/2 || normA<=Math.PI/2){
ctx.textAlign='left';
var flip=1;
offset+=5;
}else{
ctx.textAlign='right';
var flip=-1;
offset-=10;
}
// set the baseline to middle
ctx.textBaseline='middle';
// set [0,0] to [x,y]
ctx.translate(x,y);
// rotate
ctx.rotate(angle);
// if the text is on the left side, flip it for readability
ctx.scale(flip,flip);
// draw the text
ctx.fillText(text,offset,0);
// always clean up!
// reset transforms & text styling
ctx.setTransform(1,0,0,1,0,0);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=150 height=150></canvas>