Html2canvas: كيفية التجسيد الكامل للجزء المخفي في "overflow: auto" div

تم إنشاؤها على ٢٢ فبراير ٢٠١٢  ·  34تعليقات  ·  مصدر: niklasvh/html2canvas

لدي div يحتوي على جميع العناصر التي يجب تحويلها إلى صورة. ويتم تعيين div على " overflow: auto ". أريد أن أعرف كيف يمكنني تصدير جميع العناصر (حتى المخفية في التمرير) إلى صورة. أقدر وأرحب بجميع تعليقاتكم وإجاباتكم ...... شكرا مقدما ...

التعليق الأكثر فائدة

@ ruthraprakash ، لدي مشكلة مماثلة. يعمل هذا من أجل أغراضي البسيطة على أحدث إصدار:

function fullhtml2canvas(el) {
    return new Promise(resolve => {
        html2canvas(el, {
            width: el.scrollWidth,
            height: el.scrollHeight,
        }).then(canvas => {
            resolve(canvas);
        });
    });
}

ال 34 كومينتر

لا يوجد حاليًا خيار لعرض الصفحة بخيارات محددة ، لذلك ستحتاج إلى تعديل الصفحة لتبدو بالشكل الذي تريده.

بمعنى آخر ، إذا قمت بإزالة حد الارتفاع / العرض ، وقمت بتشغيل html2canvas ، ثم عادت الارتفاع / العرض إلى القيمة التي كانت عليها ، فيجب أن تحقق ما تبحث عنه.

شكرا جزيلا لك .... سأجرب ما قلته ...

حاولت لفترة طويلة ... لكنها تسبب الكثير من المشاكل ... لم أستطع تحقيق ما قلته. اكتشفت أنه يعمل بشكل جيد عندما يكون "جسمًا" حتى لو كان هناك تمرير ... أريد تحقيق الشيء نفسه بالنسبة إلى div الذي يحتوي على عناصر مع التمرير ... إذا كان بإمكانك مساعدتي في حل هذه المشكلة ، فسيكون ذلك مساعدة كبيرة لي ... أتطلع إلى تعليقاتكم ...

niklasvh ، لدي نفس المشكلة ، والحلول الوحيدة التي html2canvas (ليس خيارًا دائمًا) ، أو الاتصال بـ html2canvas مرتين متتاليتين على نفس العنصر. إليك كمان لتوضيح المشكلة:

http://jsfiddle.net/fMeRC/1/ (هذا المثال المحدد يعمل فقط مع Chrome ؛ عليك العبث بالعرض لمعرفة المشكلة في المتصفحات الأخرى)

يحدث هذا بشكل أساسي فقط عندما يكون العنصر أوسع من النافذة أو (document.width - 8) ، لست متأكدًا من العنصر الذي له صلة مباشرة / أكثر أهمية ، وقد يتغير هذا في المتصفحات الأخرى).

من المحتمل أن يكون ذا صلة: # 199 و # 108.

هل حاولت childElement أو ضبط "overflow = مرئي" وبعد تعيين "overflow = auto | hidden | ورث"؟

عنصر childElement بدون نمط ، فقط لتلقي محتويات div مع تجاوز السعة:

<div id="main"><!--// main div -->
<div class="mainContent"><!--// div without style (height: auto, width: auto, margin: 0, padding: 0) -->
...content...
html2canvas([$("#main div.mainContent").get(0)],...)

شكرا على الاقتراحاتbrcontainer. لقد جربت الأسلوب overflow: visible -> html2canvas( ... ) -> overflow: [old overflow] ، على الرغم من أن وميض المحتوى المخفي / غير المخفي / المخفي مجددًا كان ملحوظًا للغاية (ربما لأن العنصر المستهدف الخاص بي معقد نسبيًا). على الرغم من أنني توصلت للتو إلى متغير محسن قليلاً من الحل البديل الذي يبدو أنه يحدث فرقًا في هذا الصدد:

html2canvas( targetElement, {
  onpreloaded: function(){ /* set parent overflow to visible */},
  onparsed: function(){  /* reset parent overflow */ },
  // ... onrendered, etc.
});

يؤدي هذا إلى ضبط الفائض على "مرئي" فقط (ما أعتقد أنه) لأقصر فترة زمنية ضرورية لـ h2c لتحليل الهدف بشكل صحيح ، وبالتالي القضاء على الفلاش بالكامل تقريبًا ، على الأقل في حالتي. أي أننا لم نعد مضطرين إلى انتظار انتهاء خطوة عرض اللوحة القماشية قبل إعادة تعيين / إعادة إخفاء الفائض. ليس لدي أي فكرة عما إذا كان هذا النهج المعدل سيعمل مع الجميع ، لكنني أعتقد أنه حل بديل أفضل من استدعاء html2canvas( ... ) مرتين على التوالي أو إضافة أشياء إضافية إلى DOM لتغليف المحتوى الهدف.

على أي حال ، لا يزال هذا خطأ حقيقيًا أرغب في إصلاحه بشكل صحيح. (خاصة وأن أيًا من الحلين لا يبدو أنه يعمل بشكل صحيح بالنسبة لي في IE9 و 10 ، على الأقل - لم أجرب في IE11.)

_ ملاحظة: لن يعمل الحل البديل المذكور أعلاه مع الإصدار الأحدث الموجود حاليًا في الإصدار الرئيسي. لم أختبر ، ولكن يبدو أنك ستحتاج إلى الاستفادة من الخيار oncloned بدلاً من ذلك ، وسيتم الآن استدعاء إعادة تعيين الوالد الزائد في رد الاتصال إلى .then() . (يجب أن يكون من الممكن أيضًا جعل تجاوز الوالدين مرئيًا داخل المستند المستنسخ ولا تقلق بشأن إعادة تعيين أي شيء على الإطلاق.) _

لا أفهم سبب استخدامك بهذه الطريقة ، سيكون من الأفضل مثل هذا:

function SnapShotDOM(target,call){
    var data = {};

    //use jquery or getComputedStyle|style.overflow
    data.overflow = /*get overflow property*/;
    data.width = /*get width property*/;
    data.height = /*get height property*/;
    data.maxWidth = /*get maxWidth property*/;
    data.maxHeight = /*get maxHeight  property*/;

    target.style.overflow="visible !important";
    target.style.height="auto !important";
    target.style.maxHeight="auto !important";

    html2canvas(target, {
        "onrendered": function(canvas) {
            target.style.overflow = data.overflow;
            target.style.width = data.width;
            target.style.height = data.height;
            target.style.maxWidth = data.maxWidth;
            target.style.maxHeight = data.maxHeight;
            call(canvas);
        }
    });
}

SnapShotDOM(document.body,function(canvas){
    console.log(canvas);
});

أو استخدم الفصل:

<style>
*.html2canvasreset{
    overflow: visible !important;
    width: auto !important;
    height: auto !important;
    max-height: auto !important;
}
</style>
<script>
function SnapShotDOM(target,call){
    var data = target.className;
    target.className += " html2canvasreset";//set className - Jquery: $(target).addClass("html2canvasreset");
    html2canvas(target, {
        "onrendered": function(canvas) {
            target.className = data;//old className - Jquery: $(target).removeClass("html2canvasreset");
            call(canvas);
        }
    });
}

SnapShotDOM(document.body,function(canvas){
    console.log(canvas);
});
</script>

السبب في أنني لا أضع أي شيء متعلق بالفيضان في onrendered هو أن الوقت بين التحليل والعرض يمكن أن يكون ملحوظًا ، وإعادة تعيين الفائض في أسرع وقت ممكن (على سبيل المثال ، بعد التحليل مباشرة ، قبل التقديم) هو الأفضل لتجنب وميض المحتوى المرئي. يؤدي وضع إعادة تعيين الفائض إلى onparsed بدلاً من ذلك إلى تحقيق ذلك.

كنت أشير إلى "onpreloaded".

جرب هذا:

function SnapShotDOM(target,call){
    var data = target.className;
    target.className += " html2canvasreset";//set className - Jquery: $(target).addClass("html2canvasreset");
    html2canvas(target, {
        "onparsed": function() {
            target.className = data;//old className - Jquery: $(target).removeClass("html2canvasreset");
        },
        "onrendered": function(canvas) {
            call(canvas);
        }
    });
}

SnapShotDOM(document.body,function(canvas){
    console.log(canvas);
});

استخدامي لـ onpreloaded للسبب نفسه - إنه تحسين يسمح لي بنقل جزء إخفاء الفائض إلى آخر لحظة ممكنة ، قبل خطوة التحليل مباشرة ، وبالتالي تقليل مقدار الوقت الذي يستغرقه يكون المحتوى مرئيًا تمامًا على الشاشة. يمكنك أن ترى كيف يعمل هذا في الكود هنا وهنا .

niklasvh ، هل هذه المشكلة على الإطلاق مرتبطة بـ TODO الموجود هنا ( options.useOverflow

ما هو الإصدار الذي استخدمته يا رفاق؟ .. يمكنني أن أجد طريقة واحدة ومُحمَّلة مسبقًا في إصداري ..
im باستخدام html2canvas-0.5.0-alpha1

ejlocop تم تقديم هذه المشكلة منذ سنوات لإصدار سابق وقد لا تكون ذات صلة بحالة الاستخدام الخاصة بك (# 511).

لقد حلوا المشكلة؟ حل paraa أنا أبحث عن شيء ما باستخدام مخطط جانت الخاص بي ، أحتاجك تمامًا ...
overflow

انها لا تعمل.

http://jsfiddle.net/fMeRC/368/

pkpatels لماذا لا تعمل؟ ركضت على كمانك وصدرت الجمل دون أن تقطع ...
لدي أيضًا هذه المشكلة والحل الذي نجح معي هو الحل المقترح في: # 117

uriklar إنه يعمل من أجل التمرير الأفقي وليس التمرير الرأسي. تحقق من div. هناك ثلاثة عناصر مختلفة.

uriklar الحل الذي تقترحه لا يعمل أيضًا عند التمرير لأسفل في div والنقر على "مرئي تمامًا".
screen shot 2016-03-16 at 1 41 09 pm

ماذا عن تعيين ارتفاع #text div على auto قبل التقديم وإعادة التعيين بعد ذلك؟ هذا سيعمل.

كنت لا أزال أواجه مشكلات في تجاوز السعة في أحدث إصدار (0.5.0-beta4). أخذت الحل البديل من usmonster وقمت بتكييفه مع التغييرات الأخيرة على h2c و Promises (كما هو موضح في ملاحظة usmonster ):

ملاحظة: لن يعمل الحل البديل المذكور أعلاه مع الإصدار الأحدث الموجود حاليًا في المستوى الرئيسي. لم أختبر ، ولكن يبدو أنك ستحتاج إلى الاستفادة من الخيار oncloned بدلاً من ذلك ، وسيتم الآن استدعاء إعادة تعيين الوالد الفائض في رد الاتصال الخاص بك إلى. ثم (). (يجب أن يكون من الممكن أيضًا جعل الفائض الخاص بالوالد مرئيًا داخل المستند المستنسخ ولا تقلق بشأن إعادة تعيين أي شيء على الإطلاق.)

لذلك بدون تغيير DOM الفعلي لصفحة الويب الخاصة بك ، يمكنك تغيير المستند المنسوخ المستخدم للعرض بواسطة h2c باستخدام رد الاتصال onclone . الأمر بسيط جدًا في الواقع ، ها هي مكالمة h2c الخاصة بي:

var renderingPromise = html2canvas($(item), {
    width: item.clientWidth,
    height: item.clientHeight,
    onclone: function(clone) {
            $(clone).find('.grid-stack-item-content')
                .css('overflow-x', 'auto')
                .css('overflow-y', 'auto');
        return true;
    }
}).then(
    function(c) {/* success */},
    function() {/* fail */}
);

الشيء الوحيد الذي نجح بالنسبة لي هو وضع اللوحة القماشية في إطار iframe ، واستدعاء html2canvas بداخلها ، واستدعاء toDataURL () على اللوحة القماشية ، ثم إعادة تلك الصورة إلى النافذة العلوية باستخدام رد الاتصال. أفترض أنه يمكنك أيضًا تمرير قطعة قماشية للخلف.

return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) { if (typeof(options.onrendered) === "function") { log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"); options.onrendered(canvas); } return canvas; });
تغيير إلى
var width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth; var height = options.height != null ? options.height+node.ownerDocument.defaultView.innerHeight : node.ownerDocument.defaultView.innerHeight; return renderDocument(node.ownerDocument, options, width, height, index).then(function (canvas) { if (typeof(options.onrendered) === "function") { log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"); options.onrendered(canvas); } return canvas; });

هذا يمكن أن يحل السؤال حول تجاوز الشاشة (العرض والارتفاع)

يحتوي xzw123 على حل سيئ: يؤدي تعيين ownerDocument.defaultView.innerHeight يدويًا إلى فك ارتباطه بأحداث تحجيم النافذة الفعلية. أعتقد أنه سيكون من الأفضل إجراء ذلك في إطار iframe. أنا حريص على تجربة حل الأردن.

جوردان ، كيف انتهى بك الأمر باستخدام قماش في إطار iframe؟ أنا أحاول ذلك الآن. أعتقد أن هذا يجب أن يكون الحل النهائي في html2canvas ... يجب أن يكون اتصال iframe غير مرئي خارج واجهة برمجة التطبيقات.

آه نعم ، القيام بذلك في إطار iframe باستخدام window.postMessage(myData, ... ) يفي بالغرض. يمكنك إعادة نشر عنوان url للبيانات الكاملة لوحدات البكسل المعروضة. لقد قمت للتو بوضع كود العرض الخاص بي في HTML الخاص بإطار iframe ، وتم تمريره في البيانات اللازمة لعرض مصدر HTML ، وجعله يتم عرضه على قماش الرسم ، ثم اجعله يبصق بيانات toDataUrl مرة أخرى.

+1

أهلا. بعد البحث عن حلول ومراقبة كيفية تشغيل الكود ، أكتب الحل الصعب الخاص بي.

https://gist.github.com/simonmysun/c6da13ce2827a374e71ccf07d9f08e2d

إنه يعمل معي وآمل أن يساعد شخصًا يحتاج.

ومع ذلك ، ما زلت آمل أن يتم دعمها في هذه المكتبة في المستقبل.

ما زلت لا أحصل عليه ، لكن مشكلتي هي أن الصورة مقطوعة. عند استخدام إصدار الكروم 54.0.2840.99 م
(تم التقاط نصف الصورة ، لكن النصف الآخر حصل على شاشة سوداء)

// the timeline show up 100%, but cut off, cause its static and not dynamic.
// (its cut off from the screen,but the size, and picture show as normal, 100% show)
// after moving to the canvas, everthing that not in the screen will get blank in chrome  
// it depends to the user screen, if i zoom out my chrome, i get 100% image.

ولكن عند استخدام Mozilla 50.0.2 ، فإنه يعمل بشكل جيد دون تصغير. (صورة 100٪) ،

لا اعلم لماذا.

الشفرة :

var zenleft = $("#leftPanel").width();  //calculate left side
var zenright = $(".dataPanel").width();  //calculate right side
var after = zenright + zenleft + 250;  // add all

//add the css, even after add overflow still not working
$("#timelineTarget").css({"background-color":"white","width":after});   

 html2canvas(canvTimeline, {
    onrendered: function (canvas) {
            $("#previewImage").html(canvas);
            getCanvas = canvas;
   }
});

image

أخيرًا ، قمت بحل هذه المشكلة عن طريق إضافة

$("body").css({"width": "+="+after}); //after is a total of the width of the element i want to view

وبالتالي

var zenleft = $("#leftPanel").width();  //calculate left side
var zenright = $(".dataPanel").width();  //calculate right side
var after = zenright + zenleft + 250;  // add all
$("body").css({"width": "+="+after});  //add the body

//add the css
$("#timelineTarget").css({"background-color":"white","width":after});   

 html2canvas(canvTimeline, {
    onrendered: function (canvas) {
            $("#previewImage").html(canvas);
            $("#timelineTarget").css({"background-color":"white","width":old});   //turn it back
            $("body").css({"width": "-="+after});   //turn it back
            getCanvas = canvas;
   }
});

آمل أن تحل مشكلتك.

قد يكون onclone هو الطريقة الصحيحة. يمكنك تغيير css لتحصل على ما تريد ....

مرحباً بالجميع ، لدي div وهو قابل للتمرير. عندما أرسل إدخال div كمعامل canvas ، فإنه يقوم فقط بعرض ما هو متاح في منفذ العرض. لقد ذهبت من خلال جميع الحلول. لم افهم. هل يمكن لأي شخص معرفة كيفية أخذ محتوى كامل في div كلقطة شاشة.

@ ruthraprakash ، لدي مشكلة مماثلة. يعمل هذا من أجل أغراضي البسيطة على أحدث إصدار:

function fullhtml2canvas(el) {
    return new Promise(resolve => {
        html2canvas(el, {
            width: el.scrollWidth,
            height: el.scrollHeight,
        }).then(canvas => {
            resolve(canvas);
        });
    });
}

لدي مشكلة في أخذ لقطة شاشة لمخطط المخطط الزمني. أنا لا أقوم بتثبيت قيمة المحور س. إنه مجرد إنشاء صورة مخطط الخط الزمني.
`demoFromHTML (e) {
e.preventDefault () ؛

  let input = window.document.getElementById('divToPDF');


  html2canvas(input)
  .then((canvas) => {

    const imgData = canvas.toDataURL('image/jpeg');

    const pdf = new pdfConverter("l", "pt");
    pdf.addImage(imgData, 'JPEG', 15, 110, 800, 250);
    pdf.save('test.pdf');
  });


}

"

حاولت لفترة طويلة ... لكنها تسبب الكثير من المشاكل ... لم أستطع تحقيق ما قلته. اكتشفت أنه يعمل بشكل جيد عندما يكون "جسمًا" حتى لو كان هناك تمرير ... أريد تحقيق الشيء نفسه بالنسبة إلى div الذي يحتوي على عناصر مع التمرير ... إذا كان بإمكانك مساعدتي في حل هذه المشكلة ، فسيكون ذلك مساعدة كبيرة لي ... أتطلع إلى تعليقاتكم ...

من فضلك ، هل يمكنك أن تريني كيف حصلت على الجسم للعمل

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

stevencherry1 picture stevencherry1  ·  3تعليقات

Loki180 picture Loki180  ·  4تعليقات

arzyu picture arzyu  ·  3تعليقات

celik75 picture celik75  ·  4تعليقات

anthonymejia picture anthonymejia  ·  4تعليقات