Mode SVG pur pour adapter le texte à une boîte

Taille de la boîte connue. Longueur de la chaîne de texte inconnue. Ajuster le texte à la boîte sans nuire à son format.

entrer la description de l'image ici

Après une soirée de googler et de lire les spécifications SVG, je suis presque sûr que ce n’est pas possible sans JavaScript. Le plus proche que je pouvais obtenir était d’utiliser les atsortingbuts de texte textLength et lengthAdjust, mais cela étend le texte le long d’un seul axe.

 UGLY TEXT  

entrer la description de l'image ici

Je suis au courant de SVG Scaling Text pour adapter le conteneur et le texte de assembly dans la boîte

Je n’ai pas trouvé le moyen de le faire directement sans Javascript, mais j’ai trouvé une solution JS assez facile, sans boucles et sans modification de la taille de la police et s’adapte bien à toutes les dimensions, c’est-à-dire que le texte se développe jusqu’à la limite de le côté le plus court

Fondamentalement, j’utilise la propriété transform , en calculant la bonne proportion entre la taille souhaitée et la taille actuelle.

Ceci est le code:

   MY UGLY TEXT   

Dans l'exemple précédent, le texte croît jusqu'à la width == 500 , mais si j'utilise une taille de boîte de width = 500 et de height = 30 , le texte augmente jusqu'à la height == 30 .

Tout d’abord: il suffit de voir que la réponse ne répond pas précisément à votre besoin – cela pourrait toujours être une option, alors voici:

vous observez à juste titre que svg ne supporte pas directement le retour à la ligne. Cependant, vous pouvez tirer foreignObject éléments foreignObject servant de wrapper pour les fragments xhtml lorsque le retour à la ligne est disponible.

jetez un coup d’œil à cette démo autonome (disponible en ligne ):

     simulated wrapping in svg A foreignObject container     Demo test that is supposed to be word-wrapped somewhere along the line to show that it is indeed possible to simulate ordinary text containers in svg.      

J’ai développé @Roberto answer, mais au lieu de transformer (redimensionner) le textNode, nous avons simplement:

  • donnez-lui font-size de 1em pour commencer
  • calculer l’échelle basée sur getBBox
  • définir la font-size la font-size à cette échelle

(Vous pouvez également utiliser 1px etc.)

Voici le HOC de React qui fait ceci:

 import React from 'react'; import TextBox from './TextBox'; const AutoFitTextBox = TextBoxComponent => class extends React.Component { constructor(props) { super(props); this.svgTextNode = React.createRef(); this.state = { scale: 1 }; } componentDidMount() { const { width, height } = this.props; const textBBox = this.getTextBBox(); const widthScale = width / textBBox.width; const heightScale = height / textBBox.height; const scale = Math.min(widthScale, heightScale); this.setState({ scale }); } getTextBBox() { const svgTextNode = this.svgTextNode.current; return svgTextNode.getBBox(); } render() { const { scale } = this.state; return (  ); } }; export default AutoFitTextBox(TextBox); 

Je ne pense pas que ce soit la solution pour ce que vous voulez faire, mais vous pouvez utiliser textlenght avec pourcentage ="100%" pour la largeur totale.

  blabla  

vous pouvez également append textanchor="middle" et changer la position x pour centrer parfaitement votre texte

cela ne changera pas la taille de la police et vous aurez un espace de lettres étrange …

JSFIDDLE DEMO