2016-02-29 2 views
-1

Я написал этот код. Я запрограммировал его в чистых js, css, html5, но это выглядит странно на iDevices, поэтому я подумал, что могу легко сделать это в холсте. Но я столкнулся с следующей проблемой.Как я могу повернуть этот текст в холсте html5?

Вы можете увидеть условие, в котором я проверяю угол текста. Я пробовал несколько вещей, но по-прежнему не могу перевернуть текст вверх дном на другой стороне «диаграммы». Может ли кто-нибудь помочь мне в этом?

$(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

'ctx.rotate' должны быть в состоянии поместить текст вверх ногами. Не так ли? –

+0

уверен, что это уже много раз в этом фрагменте, но, пожалуйста, взгляните на код и на результат и посмотрите, что всякий раз, когда я пытаюсь повернуть холст вокруг точки, где находится текст, он исчезает. – jPO

+0

'rotate' вращается вокруг (0,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 { 
+0

Ты мой герой. Большое спасибо. Никогда не думал, что настройка шрифта может нанести большой вред. Спасибо! – jPO

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>

+1

Отличный пример, большое спасибо. Хотя ваш ответ мог помочь мне с моей проблемой, ответ от @Bobby Orndorff решил мою проблему намного быстрее. Спасибо, действительно, кучка! – jPO

+1

@jPO. Рад, что вы его отсортировали :-) Удачи вам в вашем проекте! – markE

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