2017-09-29 2 views
1

J'essaie actuellement de créer un speechbubble pour mon canvas en utilisant javascript.Discours en toile créé en Javascript -> measureText height?

Problème 1:

J'ajoute la largeur de la façon suivante: ctx.measureText(text).width + 40 pour vous assurer que la largeur de la speechbubble est flexible et dépend de l'entrée var text = 'Speechbubble test';. Ajout également de 40 pixels pour ajouter une marge gauche et droite!

Comment puis-je obtenir la hauteur du texte pour le rendre également flexible? J'ai vérifié mais je n'ai pas pu trouver quelque chose de similaire à la méthode measureText et il ne semble pas exister.

Est-il possible d'obtenir la hauteur réelle du texte? Je demande parce que je prévois d'ajouter un saut de ligne. eG: prise en charge de plusieurs lignes (cassez la ligne de texte après un nombre spécifique de lettres).

Problème 2:

J'essaie d'ajouter un petit pointeur de la direction de bulle à l'speechbubble. Désolé pour la façon dont je le décris de cette façon, je ne connais pas le mot pour ça. Mais je parle de ce qui suit:

Image to preview what I'm talking about

Comment pourrais-je ajouter ce qui suit à mon speechbubble?

J'apprécie toute suggestion et aide.

L'exemple actuel:

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

 
function component(ctx, width, height, color, x, y, radius, text) 
 
{ 
 
    // Variables 
 
    var width = width + 40; 
 
    var height = height; 
 
    var x = x; 
 
    var y = y; 
 
    var radius = Math.min(radius, Math.min(width, height)/2); 
 
    var color = color; 
 
    var pi2 = Math.PI * 2; 
 
    var r = radius; 
 
    var w = width; 
 
    var h = height; 
 
    
 
    // Transparent background 
 
    //ctx.fillStyle = "rgba(255, 255, 255, 0.5)"; 
 
    ctx.fillStyle = color; 
 
    ctx.setTransform(1, 0, 0, 1, x, y); 
 
\t 
 
    // Draw arc 
 
    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); 
 
    ctx.arc(r , h - r, r, pi2 * 0.25, pi2 * 0.5); 
 
    ctx.fill(); 
 

 
    ctx.setTransform(1, 0, 0, 1, 0, 0); 
 

 
    // Text fillstyle 
 
    ctx.fillStyle = "#fff"; 
 
    ctx.fillText(text, x + 20, y + 40); 
 
}
<canvas width="500" height="500" id="canvas"></canvas>

Répondre

0

Le problème est que même si la specs defines un moyen de mesurer la hauteur par un objet TextMetrics, aucun fournisseur a effectivement mis en œuvre il à l'heure actuelle .

Donc, nous devons tricher un peu pour obtenir la taille réelle de la police.

Une façon de le faire est d'insérer temporaire un élément DOM et obtenir la hauteur de celle:

console.log(getTextHeight("Hello", "20px sans-serif")); 
 

 
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 
 
}

Pour une utilisation avec la toile passent juste context.font comme argument de la police:

var fontHeight = getTextHeight("Hello", ctx.font); 

Quant aux deux problèmes:

Vous pouvez briser le chemin de la ligne de fond pour ainsi dire, du rectangle arrondi en insérant lineTo() appels, comme:

var ctx = c.getContext("2d"), r = 20, w = 290, h = 100, pi2 = Math.PI*2; 
 
var ap = w * 0.2, aw = 20, ah = 30; //arrow position, width, height 
 
ctx.translate(1.5,0.5); 
 

 
// Rounded rectangle 
 
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);  // bottom right corner 
 

 
ctx.lineTo(w - ap, h);       // inserts an arrow (following clock-wise) 
 
ctx.lineTo(w - ap, h + ah); 
 
ctx.lineTo(w - ap - aw, h); 
 

 
ctx.arc(r , h - r, r, pi2 * 0.25, pi2 * 0.5); // bottom left corner 
 
ctx.closePath(); 
 
ctx.stroke();
<canvas id=c></canvas>

+0

Merci pour l'aide. Appréciez-le! – dane