2014-01-10 16 views
9

Ich versuche, einige Thumbnails dynamisch erstellten Seiten für eine Website zu erstellen, habe ich eine Lösung gefunden, indem Sie die HTML in einem Svg, die ich dann auf ein Bild in einem Leinwand, die ich skaliere, nachdem das Bild gezeichnet wurde.Zeichnen eines Svg mit HTML in einer Leinwand mit Safari

Diese Lösung funktioniert in Firefox und Chrome, aber nicht in Safari, die SVG scheint nicht gezeichnet zu werden Ich bekomme nur eine leere Seite. Ich bekomme keinen Fehler, auch wenn ich versucht habe, es zu versuchen, und ich konnte keine Lösung im Internet finden.

Mein html ist nur eine grundlegende Testseite mit einer Leinwand, habe ich versucht, einen Meta-Tag auf dem Kopf hinzufügen

<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" /> 

aber es hat nicht funktioniert.

Hier ist der Code, den ich schrieb:

var canvas = document.getElementById('canvasTest'), 
      context = canvas.getContext('2d'); 

      var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" + 
       "<foreignObject width='100%' height='100%'>" + 
        "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" + 
        "<div>TEST<span>TEST</span></div>" + 
        "</div>" + 
       "</foreignObject>" + 
       "</svg>" 
      ; 

      var DOMURL = self.URL || self.webkitURL || self; 
      var img = new Image();                    

      try { 
       var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});      
      } catch(e) {      
       window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; 
       console.log(window.BlobBuilder); 

       if(e.name == 'TypeError' && window.BlobBuilder){ 
        var bb = new BlobBuilder(); 
        bb.append(data); 
        var svg = bb.getBlob("image/svg+xml;charset=utf-8"); 
       } else if(e.name == "InvalidStateError") {      
        var svg = new Blob(data, {type : "image/svg+xml;charset=utf-8"}); 
       } else { 

       } 
      }    

      var url = DOMURL.createObjectURL(svg);    

      img.onload = function() {     
        context.drawImage(img, 100, 100);          
      }; 

      img.src = url; 
      DOMURL.revokeObjectURL(url); 

      context.translate(canvas.width/2, canvas.height/2); 
      context.scale(0.4, 0.4); 

Safari den Blob-Konstruktor verwenden kann, damit es nicht in dem Fang geht. Es scheint, dass das Problem ist, wenn ich die SVG-Referenz (img.src = URL) übergeben, aber ich kann nicht herausfinden, was ich anders machen soll, wenn jemand einige Ideen oder eine Lösung hat, wäre es großartig.

Edit: Konsolausgabe für safari

Blob: Blob {size = 232, type = "image/svg + xml; charset = UTF-8", webkitSlice}

URL: blob: http://myPage.com/96fb502f-46bb-492b-af35-5313bb39bd31

+0

Können Sie '.toDataURL()' danach verwenden, oder erhalten Sie einen Sicherheitsfehler bei Safari? – Bigood

Antwort

13

Grundsätzlich bestand die Lösung darin, den Mime-Typ (Daten: image/svg + xml) in die Variable mit dem svg zu setzen, damit Sie den Blob nicht mehr verwenden müssen und dann den img src mit dem setzen Svg, bevor Sie es auf die Leinwand zeichnen.

var canvas = document.getElementById('canvasTest'), 
      context = canvas.getContext('2d'); 

      var data = "data:image/svg+xml,"+"<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" + 
       "<foreignObject width='100%' height='100%'>" + 
        "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" + 
        "<div xmlns='http://www.w3.org/1999/xhtml'>aaaa<span>aaaa</span></div>" + 
        "</div>" + 
       "</foreignObject>" + 
       "</svg>" 
      ; 

      var img = new Image(); 

      img.src = data; 

      img.onload = function() { 
       context.drawImage(img, 100, 100);     
      }; 

      context.translate(canvas.width/2, canvas.height/2); 
      context.scale(0.4, 0.4); 
+1

Bloody genius! Danke für das super-einfache Beispiel. Ich hatte Code, der in Chrome und FF funktioniert, aber nicht in Safari. Es verwendete das window.URL-Objekt, um einen Blob zu erstellen und den Blob dann auf die Zeichenfläche zu zeichnen. Ihr Beispiel ist hier viel einfacher und funktioniert sowohl in Safari als auch in den anderen Browsern, die ich unterstützen muss. Vielen Dank! – frosty

+2

Wahrscheinlich möchten Sie sagen: "var data =" daten: image/svg + xml; utf8, "+ encodeURIComponent (svgElementCode);" statt für utf-8 und bessere Browser-Unterstützung. [Siehe hier] (http://codepen.io/Rww/pen/Aczds). – amergin

+0

Danke, danke, danke. – cbmtrx

1

Sie geben nicht an, was Sie in der Konsole auf dem Blob noch die URL erhalten.

Nur ein Schuss, aber Sie widerrufen die URL direkt nach der Einstellung als Quelle auf dem Bild. Sie müssen widerrufen, wenn nach das Bild im onload Ereignis geladen ist:

img.onload = function() {     
    DOMURL.revokeObjectURL(url);  /// here 
    context.drawImage(img, 100, 100);          
}; 

img.src = url; 
//DOMURL.revokeObjectURL(url);  /// not here 

See, die aus hilft. Wenn nicht, haben Sie wahrscheinlich mit einem Safari-spezifischen Problem zu tun. (Ihre Canvas-spezifische Übersetzung usw. sollte auch innerhalb des onload -Ereignisses sein oder mindestens aufgerufen werden, bevor Sie die src-Eigenschaft festlegen).

+0

Danke für die Antwort. Ich habe versucht, Ihre Lösungen, aber ich bekomme immer noch eine leere Seite auf Safari. Ich habe meine Frage bearbeitet, um die Konsolenausgabe für den Blob und die URL einzuschließen. Haben Sie eine genauere Vorstellung davon, was das Problem sein könnte? –

+0

Ich habe endlich eine Lösung gefunden, die für ff chrome und safari funktioniert, ich werde es später posten. Danke für deine Antwort. Ich habe dich um die Hilfe gebeten. –