Pixi.js: عند تغيير حجم اللوحة القماشية ، هناك وميض في الخلفية البيضاء

تم إنشاؤها على ٣ ديسمبر ٢٠١٦  ·  7تعليقات  ·  مصدر: pixijs/pixi.js

أقوم بتغيير حجم اللوحة القماشية بوظيفة بسيطة قائمة بذاتها ، مثل هذا:

function resizeCanvas(width, height) {
    game.canvas.width = width;
    game.canvas.height = height;
    game.canvas.style.width = width / game.resolution + 'px';
    game.canvas.style.height = height / game.resolution + 'px';
}

وعند بدء تشغيل اللعبة ، أفعل شيئًا كالتالي:

game.renderer = new PIXI.WebGLRenderer(
    game.canvas.width,
    game.canvas.height,
    {
         view: game.canvas,
         backgroundColor: 0x000000,
     }
);

// recompute viewport size & canvas size with  browser window size 
game.scaler.update();  

// resize  renderer with new size.
game.renderer.resize(game.viewportWidth, game.viewportHeight);

حالة الاختبار بسيطة للغاية: ارسم صورة png صغيرة.

المتصفح: Chrome 55 لنظام macOS 10.12

سفاري على ما يرام.

أعلم أنه ربما تكون هذه مشكلة في Chrome ، لكنني آمل أن تكون هناك طريقة اختراق لإصلاحها.

شكرا

💾 v4.x (Legacy)

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

اوه شكرا! mickdekkers هذا رائع ، استدعاء العرض على الفور يجعله يعمل مع عمليات رد النداء ResizeObserver .

ال 7 كومينتر

أستخدم الكود مثل هذا لإصلاح هذا الخطأ:

    game.renderer.resize(game.viewportWidth - 1, game.viewportHeight);
    setTimeout(function() {
        game.renderer.resize(game.viewportWidth, game.viewportHeight);
    }, 1);

إنه قبيح جدًا , من يمكنه أن يعطيني اقتراحًا أفضل

بالتأكيد , أفضل طريقة هي إبلاغ فريق Chrome بذلك.
من يستطيع فعلها؟ لغتي الإنجليزية أضعف من أن أصف هذا الخطأ。

كروم جديد لا توجد هذه المشكلة.

أود أن أؤكد أن هذا لا يزال يحدث على سطح المكتب Safari (الأحدث) و Edge. Pixi v4.3.0.

تحرير: في pseudocode ، كنا نفعل شيئًا مثل

handleWindowDimensionChange(function() {
renderer.resize(window.innerWidth, window.innerHeight)
});

يؤدي تغيير حجم النافذة إلى حدوث وميض قبيح في كلا المستعرضين المذكورين. ليس كروم أو فايرفوكس.

هل لدى أي شخص فكرة عما يمكن أن يتسبب في حدوث وميض عند تغيير الحجم؟ لدي نفس المشكلة في Electron (تم اختباره بإصدارات مختلفة ، ولكن بشكل أساسي ، Chromium 56 و 58 و 59) و Pixi 4.5.5 (تم اختباره على Linux و macOS) ولكن فقط في سيناريو غريب:

أقوم بتغيير حجم العارض (webgl) استنادًا إلى عنصر الحاوية في DOM: يمكن لعنصر الحاوية تغيير الحجم إذا تم تغيير حجم النافذة أو تشغيلها بواسطة عنصر واجهة مستخدم يمكن تغيير حجمه في Javascript. الآن ، إذا قمت بتغيير حجم العارض في النافذة resize ومعالج الأداة resize المخصص للأداة (استنادًا إلى أحداث mousemove ) ، فكل شيء على ما يرام ، ولكن إذا استخدمت ResizeObserver الجديد

بضع ملاحظات:

  • يحدث الخفقان بسبب مسح اللوحة بالكامل (كما هو مذكور في OP ، في حالتي ليست بيضاء ولكنها شفافة): هذا مرئي بوضوح عندما أقوم بتسجيل أداء مع لقطات شاشة في أدوات التطوير: اللوحة فارغة لحوالي 100 مللي ثانية أثناء تغيير الحجم.
  • لقد افترضت أن هذه مشكلة في الأداء / التوقيت في أن الحرائق التي تحدث بشكل متكرر أكثر من ResizeObserver ، لكن هذا ليس هو الحال: أحصل على تكرار مماثل في كلا السيناريوهين.
  • علاوة على ذلك ، فإنني أقوم بتقييد تغيير الحجم نفسه ، لذا فإن تكرار المكالمة الفعلية إلى renderer.resize هو نفسه في كلتا الحالتين ؛ كما أن المكالمة لا تحدث في أي من معالجي الأحداث ولكنها تأخرت ، لذلك يبدو من غير المرجح أن يقع اللوم على التوقيت.
  • كان تخميني التالي هو أن القيم التي تم الإبلاغ عنها بواسطة ResizeObserver مختلفة ؛ يُبلغ عن مربع محتوى الحاوية وليس المربع المحيط ، ولكن نظرًا لعدم وجود حدود أو حشوة متضمنة ، فإن القيم هي نفسها. علاوة على ذلك ، أقوم بتقريب الأبعاد إلى وحدات بكسل كاملة في كلا السيناريوهين. حقًا ، كل من الأبعاد التي يتم ضبطها والتردد متشابهان جدًا في كلتا الحالتين.
  • يتوقف الخفقان إذا قمت بزيادة مهلة الخانق إلى حوالي 500 مللي ثانية أو أعلى
  • باستخدام معالجات أحداث النافذة / عنصر واجهة المستخدم ، أحتاج إلى قياس الحاوية باستخدام getBoundingClientRect() - لحفظ هذه المكالمة (تسبب في إعادة الطلاء) هو في الواقع سبب كبير لاستخدام ResizeObserver لكنني اكتشفت قد يتسبب عدم وجود إعادة طلاء إضافية في حدوث وميض لسبب ما. لذلك أضفت مكالمة غير ضرورية إلى getBoundingClientRect() قبل تغيير الحجم ، لكن دون جدوى.

لست قلقًا للغاية ، لأن هناك حلًا قابلاً للتطبيق (باستخدام المعالجات المنفصلة ، بدلاً من ResizeObserver ) ، لكني أرغب حقًا في معرفة سبب ذلك. لقد قمت أيضًا بإيقاف تشغيل autoResize و antialias لكن ذلك لم يحدث فرقًا. أي أفكار ماذا يمكنني أن أجرب؟

inukshuk في حالتي ، اتضح أن الحل بسيط حقًا: فقط اتصل بـ render بعد تغيير الحجم.

app.renderer.resize(width, height)
// Immediately render because resizing clears the canvas
app.render()

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

اوه شكرا! mickdekkers هذا رائع ، استدعاء العرض على الفور يجعله يعمل مع عمليات رد النداء ResizeObserver .

تم قفل سلسلة الرسائل هذه تلقائيًا نظرًا لعدم وجود أي نشاط حديث بعد إغلاقه. الرجاء فتح قضية جديدة للأخطاء ذات الصلة.

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

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

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

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

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

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

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