2017-10-09 16 views
0

J'ai essayé d'exporter l'image png à partir de l'élément svg en utilisant Blob. Ici, lorsque je clique sur la balise d'ancrage, l'image a été exportée mais il n'y a pas de contenu en raison de la méthode asynchrone (image.onload()) appelée après avoir terminé l'événement click. Comment résoudre ce problème?comment renvoyer une valeur avec image.onload du côté client

<body> 
    <a id="export">Click To Export</a> 
    <div id="container" width=500px height=200px> 
     <svg id="myViewer" width="500px" height="200px" xmlns="http://www.w3.org/2000/svg"> 
      <rect x="50" y="20" width="150" height="150" style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" 
      /> 
     </svg> 
    </div> 
    <script> 
     document.getElementById('export').onclick = function() { 
      var tag = document.getElementById('export'); 
      tag.download = 'Sample' + "." + 'png'; 
      tag.href = getCanvaElement().toDataURL(); 
     } 

     function getCanvaElement() { 
      var svgText = document.getElementById("myViewer").outerHTML; 
      var svg = new Blob([svgText], { type: "image/svg+xml;charset=utf-8" }); 
      var domURL = self.URL || self.webkitURL || self; 
      var url = domURL.createObjectURL(svg); 
      var element = document.createElement('canvas'); 
      var ctx = element.getContext("2d"); 
      var image = new Image; 
      image.onload = function() { 
       ctx.drawImage(this, 0, 0); 
       domURL.revokeObjectURL(url); 
      }; 
      image.src = url; 
      return element; 
     } 
    </script> 
</body> 

échantillon Lien: http://jsfiddle.net/kyjs655r/347/

+1

Votre première ligne va vous aider à quelques voix en bas. Nous fermons la question car les personnes qui connaissent le vrai problème sont plus susceptibles d'obtenir un doublon plus adapté. Alors s'il vous plaît ne nous demandez pas quoi et quoi ne pas faire. Aussi s'il vous plaît essayez d'écrire votre problème clairement. – Rajesh

+0

Je vais devoir aller de l'avant et marquer cela comme une copie de toute façon, désolé. Il y a déjà de nombreuses explications sur la façon de traiter les appels de fonction asynchrones –

Répondre

0

Vous pouvez utiliser constructeur Promise et async/await, resolve() élément <canvas> au sein <img> événement de chargement

document.getElementById('export').onclick = async function() { 
    var tag = document.getElementById('export'); 
    tag.download = 'Sample' + "." + 'png'; 
    const canvas = await getCanvaElement(); 
    tag.href = canvas.toDataURL(); 
} 

function getCanvaElement() { 
    return new Promise(resolve => { 
    var svgText = document.getElementById("myViewer").outerHTML; 
    var svg = new Blob([svgText], { 
     type: "image/svg+xml;charset=utf-8" 
    }); 
    var domURL = self.URL || self.webkitURL || self; 
    var url = domURL.createObjectURL(svg); 
    var element = document.createElement('canvas'); 
    var ctx = element.getContext("2d"); 
    var image = new Image; 
    image.onload = function() { 
     ctx.drawImage(this, 0, 0); 
     domURL.revokeObjectURL(url); 
     resolve(element) 
    }; 
    image.src = url; 
    }) 
} 

jsFiddle http://jsfiddle.net/kyjs655r/351/

+0

Il peut s'agir d'un commentaire opiniâtre, mais ne devrait-on pas le marquer comme dupe à la place, comme Promise est couvert de dupe – Rajesh

+0

@Rajesh Vous pouvez voter ou non voter comme vous le voyez en forme. – guest271314

+0

@ guest271314 dans votre échantillon ne fonctionne pas .. quand je clique, l'image n'a pas été exportée quand je clique la deuxième fois après que seule l'image a été exportée –