fitting text into the box

前端 未结 2 623
长发绾君心
长发绾君心 2021-02-09 07:24

on my website i allow users to create pictures with line of text they specify drawn on the picture

currently i use for that imagemagick convert - i specify svg template

相关标签:
2条回答
  • 2021-02-09 07:57

    solved by abandoning svg and doing everything with imagemagick convert and mvg template

    here's the simplified script example in case anyone's pursuing something similar

    script is putting an image and a title on the canvas. title is created with separate convert command, saved as temporary file and then put onto the canvas

    #!/bin/sh
    
    TEMPLATE="
    push graphic-context
    viewbox 0 0 600 600 
    affine 1 0 0 1 0.0 0.0
    push graphic-context
    fill 'rgb(0,0,0)'
    rectangle 0,0 600,600
    pop graphic-context
    push graphic-context
    image Over 38,38 338,338 '%s' 
    pop graphic-context
    push graphic-context
    image Over 36,400 529,55 '%s' 
    pop graphic-context
    pop graphic-context
    ";
    
    #1. creating label fitting specified proportions 
    #2. converting mvg template to jpeg image (and trimming it in process) 
    #3. removing temp file with label
    
    convert -size 529x55 -background black -family "Times New Roman" -gravity center -fill white label:"$2" "tmp/$1title.jpg" && printf "$TEMPLATE"  "images/$1.jpg" "tmp/$1title.jpg"  | convert mvg:- -trim +repage -bordercolor black -border 36  "images/$1converted.jpg" && rm "tmp/$1title.jpg"
    
    #script parameters: $1 is image id, $2 is title text
    
    0 讨论(0)
  • 2021-02-09 08:04

    You could add a script within the SVG template which called when the SVG is loaded and uses getComputedTextLength() to resize the font. It's a bit of a hacky solution, but it seems to work.

    Here's a quick example that draws a box and some text inside it. The text should be resized to always fit in the box no matter how long it is (up to point at least):

    To call the code when the SVG is loaded include onload="int(evt)" in the SVG tag.

    <?xml version="1.0" encoding="UTF-8" standalone="no"?> 
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 
    <svg xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         width="400" height="80"
         onload="init(evt)"> 
    

    Then the actual script:

      <script type="text/ecmascript">
        <![CDATA[
    
        function init(evt)
        {
            if ( window.svgDocument == null )
            {
                svgDocument = evt.target.ownerDocument;
            }
    
            maximum_length = 300;
            my_text = svgDocument.getElementById('text-to-resize');
    
            for (var font_size=55; font_size>0; font_size--)
            {
                if(my_text.getComputedTextLength() < maximum_length){break;}
                my_text.setAttributeNS(null, "font-size", font_size);
            }
    
        }
    
        ]]>
      </script>
    

    I just used a for loop to decrement the font-size until the text length is less than the maximum specified; I'm sure there's a better way to resize the text.

    Finally the actual text and box:

    <rect id="rect1" x="20" y="10" width="320" height="50" fill="white" stroke="black"/>
    <text id="text-to-resize"
          text-anchor="middle"
          x="170" y="50"
          font-family="Times New Roman" font-size="55">
     whatever text
    </text>
    </svg>
    

    If you change the text, the font-size should change so that it fits inside the box. You'll probably want to change the x- and y- values to correctly centre the text too.

    0 讨论(0)
提交回复
热议问题