Html2canvas: Ne rend que ce qui est en vue

Créé le 25 juin 2015  ·  22Commentaires  ·  Source: niklasvh/html2canvas

Il semblerait que la taille de l'image résultante soit aussi grande que tout le contenu de la fenêtre, y compris ce qui est débordé, mais ce qui est réellement visible limité uniquement à la fenêtre d'affichage.

C'est avec moi que je prends le débordement de tout ce dont je peux l'enlever. Il n'y a donc pas de CSS qui interfère avec cela. Est-il possible d'obtenir un contenu en dehors de la fenêtre d'affichage inclus dans l'image ? J'ai remarqué que même si je fais défiler la page vers le bas et que je réessaye, le résultat ne captera même pas ce qui se trouve dans la fenêtre de défilement, mais contiendra toujours ce qui se trouve dans la fenêtre à hauteur de défilement 0.

campaignperformance 30

Needs More Information

Commentaire le plus utile

Curieusement, il n'est rendu qu'à partir de la limite supérieure actuellement visible de l'élément donné.

Essayez https://jsfiddle.net/bianjp/bpc3nq69/1/. Faites défiler jusqu'à "Impr écran" et cliquez dessus. L'image générée n'inclura pas les lignes supérieures qui ne sont pas visibles lorsque vous cliquez dessus.
En utilisant la version 0.5.0.beta4.

La solution consiste à appeler $('html, body').scrollTop(0) (ou tout autre moyen de rendre le haut de l'élément visible) avant d'appeler html2canvas.

Tous les 22 commentaires

D'une manière ou d'une autre, sur vos exemples sur la page d'accueil, cela montre tout dans le corps, même ce qui n'est pas visible... comment avez-vous fait cela ?

Duplicata possible à partir de : https://github.com/niklasvh/html2canvas/issues/117

Alors Je veux savoir comment capturer un élément spécifié ? est-ce que quelqu'un a une solution?

@justein Essayez ceci

<div id="test-case">Test-me</div>
html2canvas(document.getElementById("test-case")).then(function(canvas) {
    document.body.appendChild(canvas);
});

Je peux confirmer ce comportement avec la dernière version. Il restituera la taille correcte de l'objet demandé, mais ne restituera pas réellement sur le canevas tout ce qui est hors écran de la fenêtre actuelle. Donc si le

<div id="test-case">Test-me</div>

est actuellement visible dans le navigateur, il sera rendu. S'il est hors écran, le canevas est vierge (mais de la bonne taille). Partiellement visible : Partiellement rendu. Le mien n'agit pas comme scrollHeight = 0, il rend tout ce qui est visible lorsque le code est exécuté. (Mon bouton est en bas).

Comme le commentaire de btm, j'aimerais savoir comment c'est fait sur le site d'exemple. Pourrait-il s'appuyer sur quelque chose dans Angular ou Bootstrap pour obtenir les ressources hors écran ?

@cchubb Je ne comprends pas ce que Angle et Bootstrap ont à voir avec cela. Le problème de John, me semble être une question de rendu d'un élément spécifique.

Si vous voulez un rendu en dehors de la fenêtre d'affichage, utilisez simplement

html2canvas(document.body).then(function (canvas) {});

Si vous souhaitez rendre les éléments "débordement", supprimez le "débordement" au moment de l'exécution et ajoutez à nouveau après le processus en utilisant javascript pour ajouter className, comme ceci :

.no-scroll {
     overflow: visible !important;
}

#main {
     overflow: auto;
     height: 200px;
}

<div id="main">
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
</div>

document.getElementById("main").className = "no-scroll";
html2canvas(document.body).then(function (canvas) {
      document.getElementById("main").className = "";
});

Ou pointez simplement le html2canvas pour rendre l'élément dans l'élément avec "débordement", comme ceci :

#parent {
     overflow: auto;
     height: 200px;
}

#child {
background-color: #fc0;
height: 600px;
}
<div id="parent">
<div id="main">
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
test<br> test<br> test<br> test<br> test<br> test<br> test<br> test<br> 
</div>
</div>

html2canvas(document.getElementById("main")).then(function (canvas) {});

A vraiment de nombreuses suggestions de fonctionnalités qui sont inutiles de mon point de vue, ciblez simplement les éléments DOM corrects et utilisez le "CSS" en leur faveur.

Je l'ai compris. Vous l'avez corrigé dans 0.5.0-alpha2. Si j'utilise la version 0.5.0-alpha1, il se clipse, mais pas la version alpha2. Je n'ai même pas remarqué qu'alpha2 était disponible car la page des versions se concentrait sur alpha1.

Voici un violon qui démontre qu'il fonctionne maintenant avec alpha2. https://jsfiddle.net/cchubb/fy7tw7ek/1/ si vous redéfinissez la ressource externe en alpha1, elle se coupera lorsque vous cliquerez sur le lien du bas. (Vous devez enregistrer le fichier de téléchargement au format .png pour l'afficher, les violons ne me laisseront pas changer la fenêtre de sortie href en données.)

@btm1 , essayez de passer à Alpha2.

@cchubb, je vais

@cchubb le problème sous-jacent est résolu dans l'alpha 2 et vous avez raison c'est bien caché je n'ai même pas remarqué qu'il y avait un alpha 2.

Hmm, pour moi, même dans alpha2, seule la partie de l'élément qui est "visible" dans la fenêtre est rendue. Voir http://jsfiddle.net/NPC42/ykvL6a17/ pour une démonstration — html2canvas n'exporte que les lignes qui défilent dans la fenêtre d'affichage (indépendamment du fait qu'elles soient visibles dans le conteneur div ou non).

Est-ce que j'appelle mal html2canvas d'une manière ou d'une autre ? Lorsque je le teste sur mon code réel (pas celui de JSFiddle, que j'ai créé juste pour la démo), cette suggestion aide à rendre l'élément entier : https://github.com/niklasvh/html2canvas/issues/650 , mais j'espère pour éviter de pirater la bibliothèque.

@NPC Il ne rendra pas seulement ce qui n'est pas en vue sans que vous ne fassiez quoi que ce soit, vous devez le modifier pour qu'il déborde visible ---> exporter très rapidement ---> puis le redéfinir pour faire défiler à nouveau ou cela ne fonctionnera pas. Pas idéal OMI, je pense qu'il devrait y avoir une option pour que cela fonctionne, mais au moins c'est le cas.

@btm1 , oui, je suppose que ce n'est pas l'intention, puisque je transmets l'élément qui se trouve dans celui qui a fait défiler, l'élément lui-même n'a pas de rognage de débordement.

Pour l'instant, dans mon application, j'ai trouvé que je devais rattacher tout mon élément au corps, en forçant une largeur/hauteur spécifique dessus (puisqu'il contient des éléments absolument positionnés), en attendant de couvrir toute cette cuisine par un "Préparation de l'exportation en plein écran, veuillez patienter", car html2canvas prend plus de 10 secondes pour tout rendre. Une fois le rendu terminé, je l'attache à l'emplacement d'origine (à l'intérieur d'un conteneur avec défilement), en désactivant la largeur/hauteur.

Encombrant, mais ça marche.

Curieusement, il n'est rendu qu'à partir de la limite supérieure actuellement visible de l'élément donné.

Essayez https://jsfiddle.net/bianjp/bpc3nq69/1/. Faites défiler jusqu'à "Impr écran" et cliquez dessus. L'image générée n'inclura pas les lignes supérieures qui ne sont pas visibles lorsque vous cliquez dessus.
En utilisant la version 0.5.0.beta4.

La solution consiste à appeler $('html, body').scrollTop(0) (ou tout autre moyen de rendre le haut de l'élément visible) avant d'appeler html2canvas.

merci @bianjp pour le correctif proposé.

Curieusement, il n'est rendu qu'à partir de la limite supérieure actuellement visible de l'élément donné.

Est-ce un comportement normal... Cela me paraît très étrange !

+1

Cette réponse SO a fonctionné pour moi.

Avant d'appeler html2canvas, faites défiler l'élément que vous souhaitez afficher dans la fenêtre.

const el = document.querySelector('#test')
el.scrollIntoView()
setTimeout(function () {
  html2canvas(el, {
    onrendered: function (canvas) {
      document.body.appendChild(canvas)
    },
    useCORS: true
  })
}, 10)

Ça marche pour moi.
L'utilisation de la version est 0.5.0-beta4.

Est-ce toujours un problème avec la v1.0.0 ? Si oui, pourriez-vous s'il vous plaît partager un exemple sur jsfiddle .

Ce problème a été automatiquement fermé car il n'y a pas eu de réponse à notre demande d'informations supplémentaires de la part de l'auteur original. Avec seulement les informations qui sont actuellement dans le problème, nous n'avons pas assez d'informations pour prendre des mesures. Veuillez nous contacter si vous avez ou trouvez les réponses dont nous avons besoin afin que nous puissions approfondir nos recherches.

Hé, @niklashvh

J'étais également confronté au problème de la prise d'instantané uniquement visible par le DOM. J'ai la version 0.5.0-beta4
Donc, je suis d'accord avec la solution @ziyoung . J'ai fait la même chose comme il l'a suggéré.

           `$('html,body').scrollTop(0);

     html2canvas( $("#rectangular_div"), {
         useCORS: true,
         dpi: 200,

          onrendered:function(canvas) {

              var str = canvas.toDataURL("image/png");
              var contentType = 'image/png';
              console.log(str);
              b64Data =str;
              imgFrameSave();
          }
        })`

J'ai donc défini la position div en haut de 0 sur le corps, puis j'ai appelé html2canvas . Donc, d'après mon expérience, j'ai recommandé d'utiliser la version 0.5.0-beta4 de @eKoopmans afin d'éviter le problème de pix-elation d'image ainsi que de capturer l'image complète à partir du DOM.

Cela fonctionne sur le bureau mais cela ne fonctionne pas sur le mobile

Ce que j'ai fait, c'est window.scrolTo(0,0) avant d'appeler htmltocanvas(), si vous êtes en haut de l'écran, le div est imprimé complet

Cette page vous a été utile?
0 / 5 - 0 notes