2017-10-13 26 views
3

Tout d'abord, oui, j'ai cherché et j'ai vu les nombreuses autres réponses disponibles. Mais ils ne travaillaient pas pour moi.Centre du texte en SVG avec React

J'aimerais pouvoir centrer le texte dans mon fichier SVG. Comme je dois pouvoir le mettre à gauche, au centre ou à droite (horizontalement et verticalement), j'ai essayé d'être un peu générique et de calculer par programmation x et y.

est un exemple: https://codesandbox.io/s/ll6ppwkyq7

Vous pouvez voir dans le résultat que le texte ne soit pas centré verticalement.

La zone rouge est la zone de délimitation du texte.

La boîte noire est la boîte dans laquelle je suis censé être centré.

Répondre

1

La relation entre x de coordonnées d'un élément et la coordonnée de la position droite du texte ne soit pas la même que celle de la y de coordonnées d'un élément et la position basse . En fait, c'est inversé. C'est parce que verticalement, le texte est placé au bas d'un élément et les coordonnées y vont de haut en bas, tandis que les coordonnées horizontales vont dans la même direction que le texte.

Ceci est facilement visible lors de l'utilisation de la méthode GetBBbox(), que vous utilisez. Par exemple, lorsque vous ajoutez un élément de texte aux coordonnées 0 pour x et y, vous verrez que getBBbox vous donnera un x = 0 mais un y négatif.

console.log(document.getElementById('testbbox').getBBox());
<svg id="testbbox"><text x=0 y=0>test</text></svg>

déjà, les calculs du centre de votre texte devront être différents. Ce que vous avez maintenant est:

outerRect.x - ((outerRect.width - innerRect.width)/2) 

Cela fonctionne parce que vous supposez que le rectangle interne commence à 0, ce qui n'est pas le cas. Votre boîte englobante est verticalement dans le négatif. formule si complète devrait être quelque chose comme:

outerRect.x - innerRect.x - ((outerRect.width - innerRect.width)/2) 

Ce qui dans votre exemple serait:

x - bboxx + ((width - boxWidth)/2) 

bbox est x de getBBox()

Vous pouvez utiliser base, mais avec dy sur le tspan, cela rend les calculs un peu plus complexes, pas sûr que ce soit la bonne approche. Puisque de toute façon getBBox prend en compte la ligne de base dans le calcul, ce n'est pas vraiment nécessaire.

De plus, si vous regardez ici, la ligne de base pour le texte devrait être la ligne de base dominante, sans alignement-base: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline

voir comment il affecte la zone de délimitation, en particulier y coordonnées:

console.log(document.getElementById('central').getBBox()); 
 
console.log(document.getElementById('top').getBBox());
<svg id="central"> 
 
<text y=10 dominant-baseline="central" >test</text> 
 
</svg> 
 
<svg id="top"> 
 
<text y=10 dominant-baseline="top" >test</text> 
 
</svg>

Voir résultat final: https://codesandbox.io/s/52wl31l8zn

+0

Dieu le simple fait que j'ai inversé 'textAlignV' et' textAlignH' se sent si mal! En tout cas, merci, ça fonctionne parfaitement. C'est un comportement si étrange, je ne comprends pas comment on s'attend à ce que les gens s'en aperçoivent! – Telokis