2017-09-29 2 views
2

J'essaie actuellement de dessiner une flèche sous mon élément speechbubble canvas.Dessiner une flèche en utilisant Javascript lineTo

Mon problème:

Le côté droit de la flèche semble être plus long chemin puis le côté gauche.

Qu'ai-je essayé:

J'ai essayé de créer la flèche de la manière suivante:

ctx.moveTo(x, y); 
ctx.lineTo(30, 30); 
ctx.lineTo(50, 10); 

Ce qui semble fonctionner comme on peut le voir ici: https://jsfiddle.net/eefja4kk/1/

Mais peu importe ce que j'essaie, je ne peux pas le faire fonctionner dans mon code actuel. J'apprécie toute forme d'aide et de suggestions.

Mon code actuel:

var canvas = document.getElementById('canvas'); 
 
var ctx = canvas.getContext("2d"); 
 
ctx.font = "12px Helvetica"; 
 
var text = 'Speechbubble Speechbubble Speechbubble'; 
 
var fontHeight = getTextHeight(text, ctx.font); 
 
component(ctx, ctx.measureText(text).width, fontHeight, "#37f", 10, 10, 16, text); 
 

 
function component(ctx, width, height, color, x, y, radius, text) 
 
{ 
 
    var r = radius; 
 
    var w = width + 40; 
 
    var h = height + 40; 
 
    var pi2 = Math.PI * 2; 
 
    var ap = w * 0.15; 
 
    var aw = 5; 
 
    var ah = 10; 
 

 
    ctx.beginPath(); 
 
    ctx.arc(r, r, r, pi2 * 0.5 , pi2 * 0.75); 
 
    ctx.arc(w - r, r, r, pi2 * 0.75, pi2); 
 
    ctx.arc(w - r, h - r, r, 0, pi2 * 0.25); 
 

 
    // Speechbubble arrow 
 
    ctx.lineTo(w - ap, h); 
 
    ctx.lineTo(w - (ap * 2), h + ah); 
 
    ctx.lineTo(w - (ap * 2) - (aw * 2), h); 
 

 
    ctx.arc(r , h - r, r, pi2 * 0.25, pi2 * 0.5); 
 
    ctx.fillStyle = '#37f'; 
 
    ctx.fill(); 
 

 
    // Text fillstyle 
 
    ctx.fillStyle = "#fff"; 
 
    ctx.fillText(text, w - ctx.measureText(text).width - 20, h - fontHeight - 10); 
 
} 
 

 
function getTextHeight(txt, font) 
 
{ 
 
    var el = document.createElement('div'), height; 
 
    el.style.cssText = "position:fixed; padding:0; left:-9999px; top:-9999px; font:" + font; 
 
    el.textContent = txt; 
 

 
    document.body.appendChild(el); 
 
    height = parseInt(getComputedStyle(el).getPropertyValue('height'), 10); 
 
    document.body.removeChild(el); 
 

 
    return height; 
 
}
<canvas width="500" height="500" id="canvas"></canvas>

Répondre

2

Vos calculs sont éteints. Vous pouvez le changer à ce qui suit pour obtenir la flèche pour être correcte:

// Speechbubble arrow 
ctx.lineTo(w - ap, h); 
ctx.lineTo(w - (ap * 2), h + ah); 
ctx.lineTo(w - (ap * 3), h); 

Here is a working example


Cela dit, votre nom de la variable suggère peut-être ce n'est pas ce que vous voulez. Je suppose que aw est censé être la largeur de flèche, dans ce cas, vous pouvez utiliser:

// Speechbubble arrow 
ctx.lineTo(w - ap, h); 
ctx.lineTo(w - ap - (aw/2), h + ah); 
ctx.lineTo(w - ap - aw, h); 

Mais je vous suggère de vous changer aw à quelque chose de plus, peut-être 20, as per this example.


Il est difficile de dire avec certitude sans savoir exactement ce que vous les variables sont appelés à représenter (c.-à-ce qui est ap réellement censé être? Dans mes exemples, il agit comme le décalage pour le début de la flèche), mais vous avoir l'idée, j'espère que mes solutions vous ramèneront sur la bonne voie.

+0

Le second est le résultat exact que j'ai essayé d'archiver! Merci beaucoup. – dane