2016-05-16 14 views
1

Ich bin auf der Suche nach einer effizienteren Möglichkeit, Text in Raphael zu beschränken/setzen.Constrain RaphaelJS Drucken to Grenzen und Position

Ich habe Text, der in einer Box geschrieben werden kann. Dieser Text sollte zentriert sein (basierend auf einer Zahl, die sich ändern könnte, wenn der Benutzer Text nach links/rechts verschieben wollte) und der Text nicht über die Grenzen des Papiers hinausgehen kann.

Dies ist, was ich jetzt tun und es ist nicht überschaubar Leistung klug

// Build a path 
var path = this.paper.print(x, x, text, font, size, 'middle') 

// Center line by getting bounding box and shifting to half of that 
var bb = path.getBBox() 
path.transform('...T' + [-bb.width/2, 0]) 

// Compare paper size vs bb 
// if it goes beyond I adjust X and Y accordingly and redo the above 

So ideal würde Ich mag die Größe des Textes vorherzusagen, bevor er druckt - ich bin nicht sicher, dies allerdings möglich ist, wie es ist wahrscheinlich schriftartabhängig. Ich habe nach einem Befehl gesucht, um dem Text zu widersprechen, sehe aber keinen?

Der andere Gedanke, den ich hatte, war es, eine Art Schattenpapier zu erstellen, das nicht auf den Bildschirm gedruckt wird und damit die Größe bestimmt, bevor ich es dem Benutzer rende. Ich bin mir nicht sicher, wo die Verzögerung ist - wenn es auf dem Bildschirm Rendering gut ist, aber wenn es in der allgemeinen Logik der Erstellung der Svg dann wird das nicht helfen.

Ich würde schätzen Vorschläge

Antwort

0

Sie opentype.js zur Messung von Text verwenden können, können Sie auch svg Pfad erhalten, indem Path.toPathData Methode. Es gibt keine Notwendigkeit von Cunfon kompilierten js Schriftarten. Erstellen Sie für Textmaße ein Canvas-Element irgendwo in Ihrem DOM.

<canvas id="canvas" style="display: none;"></canvas> 

diese Funktion Text und Zählung Breite, Höhe

function measureText(text, font_name, size) { 
    var dfd = $.Deferred(); 
    opentype.load('/fonts/' + font_name + '.ttf', function (err, font) { 
     if (err) { 
      dfd.reject('Font is not loaded'); 
      console.log('Could not load font: ' + err); 
     } else { 
      var canvas = document.getElementById('canvas'); 
      var ctx = canvas.getContext('2d'); 
      ctx.clearRect(0, 0, canvas.width, canvas.height); 
      var tmp_path = font.getPath(text, 100, 100, size); 
      tmp_path.draw(ctx); // Draw path on the canvas 
      var ascent = 0; 
      var descent = 0; 
      var width = 0; 
      var scale = 1/font.unitsPerEm * size; 
      var glyphs = font.stringToGlyphs(text_string); 
      for (var i = 0; i < glyphs.length; i++) { 
       var glyph = glyphs[i]; 
       if (glyph.advanceWidth) { 
        width += glyph.advanceWidth * scale; 
       } 
       if (i < glyphs.length - 1) { 
        var kerningValue = font.getKerningValue(glyph, glyphs[i + 1]); 
        width += kerningValue * scale; 
       } 
       ascent = Math.max(ascent, glyph.yMax); 
       descent = Math.min(descent, glyph.yMin); 
      } 
      return dfd.resolve({ 
       width: width, 
       height: ascent * scale, 
       actualBoundingBoxDescent: descent * scale, 
       fontBoundingBoxAscent: font.ascender * scale, 
       fontBoundingBoxDescent: font.descender * scale 
      }); 
     } 
    }); 
    return dfd.promise(); 
}, 

dann diese Funktion verwenden, um Textgrößen laden:

$.when(measureText("ABCD", "arial", 48)).done(function(res) { 
    var height = res.height, 
    width = res.width; 
    ... 
});