it-swarm.asia

كيفية مسح قماش لإعادة رسم

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

أحتاج إلى مسح اللوحة لإعادة رسم الصور الأخرى ؛ هذا يمكن أن يستمر لفترة من الوقت لذلك لا أعتقد أن رسم مستطيل جديد في كل مرة سيكون الخيار الأكثر كفاءة.

887
richard
const context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);
1113
Pentium10

الاستخدام: context.clearRect(0, 0, canvas.width, canvas.height);

هذه هي الطريقة الأسرع والأكثر وصفية لمسح القماش بالكامل.

لا تستخدم: canvas.width = canvas.width;

إعادة ضبط canvas.width تعيد ضبط كل حالة قماش (مثل التحويلات ، وخط العرض ، و strokeStyle ، وما إلى ذلك) ، إنها بطيئة جدا (بالمقارنة مع clearRect) ، ولا تعمل في جميع المتصفحات ، ولا تصف ما تحاول فعله فعله .

التعامل مع الاحداثيات المحولة

إذا قمت بتعديل مصفوفة التحويل (على سبيل المثال استخدام scale أو rotate أو translate) ، فمن المحتمل أن context.clearRect(0,0,canvas.width,canvas.height) لن يمسح الجزء المرئي بالكامل من اللوحة القماشية.

الحل؟ إعادة ضبط مصفوفة التحويل قبل مسح اللوحة القماشية:

// Store the current transformation matrix
context.save();

// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);

// Restore the transform
context.restore();

تحرير: لقد انتهيت للتو من وضع التوصيف و (في Chrome) أسرع بحوالي 10٪ لمسح قماش 300 × 150 (الحجم الافتراضي) دون إعادة تعيين التحويل. كما يزيد حجم قماش الخاص بك هذا الفرق يسقط.

هذا بالفعل غير مهم نسبياً ، لكن في معظم الحالات سوف ترسم أكثر بكثير مما تقوم بمسحه وأعتقد أن فرق الأداء هذا غير ذي صلة.

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
691
Prestaul

إذا كنت ترسم خطوطًا ، فتأكد من أنك لا تنسى:

context.beginPath();

وإلا لن يتم مسح الخطوط.

210
trembl

قام البعض بالفعل بعمل ممتاز للإجابة على السؤال ، ولكن إذا كانت طريقة clear() بسيطة على كائن السياق ستكون مفيدة لك (كانت بالنسبة لي) ، فهذا هو التطبيق الذي أستخدمه بناءً على إجابات هنا:

CanvasRenderingContext2D.prototype.clear = 
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }

    this.clearRect(0, 0, this.canvas.width, this.canvas.height);

    if (preserveTransform) {
      this.restore();
    }           
};

الاستعمال:

window.onload = function () {
  var canvas = document.getElementById('canvasId');
  var context = canvas.getContext('2d');

  // do some drawing
  context.clear();

  // do some more drawing
  context.setTransform(-1, 0, 0, 1, 200, 200);
  // do some drawing with the new transform
  context.clear(true);
  // draw more, still using the preserved transform
};
114
JonathanK
  • يستجيب Chrome جيدًا إلى: context.clearRect ( x , y , w , h ); كما هو مقترح بواسطة @ Pentium10 ولكن يبدو أن IE9 يتجاهل هذه التعليمات تمامًا.
  • يبدو أن IE9 يستجيب إلى: canvas.width = canvas.width; لكنه لا يزيل الخطوط والأشكال والصور والكائنات الأخرى ما لم تستخدم حلJohn Allsopp أيضًا لتغيير العرض أولاً.

لذلك إذا كان لديك لوحة قماشية وسياق تم إنشاؤه مثل هذا:

var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');

يمكنك استخدام طريقة مثل هذا:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}
35
grenade

استخدم طريقة clearRect عن طريق تمرير إحداثيات س ، ارتفاع وعرض القماش. سوف ClearRect مسح قماش كله على النحو التالي:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
19
Vishwas

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

من السهل. لنفترض أن لون الخلفية لديك أبيض:

// assuming background color = white and "eraseAlpha" is a value from 0 to 1.
myContext.fillStyle = "rgba(255, 255, 255, " + eraseAlpha + ")";
myContext.fillRect(0, 0, w, h);
14
orion elenzil

هذا هو 2018 وما زال لا توجد طريقة أصلية لمسح القماش بالكامل لإعادة الرسم. clearRect() هل لا مسح قماش تماما. لا يتم مسح الرسومات من النوع غير المملوء (على سبيل المثال ، rect())

1. تماما قماش واضح بغض النظر عن كيفية رسم:

context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.beginPath();

الايجابيات: يحافظ على strokeStyle ، fillStyle وما إلى ذلك ؛ لا تأخير

سلبيات: لا لزوم لها إذا كنت تستخدم بالفعل startPath قبل رسم أي شيء

2. باستخدام الإختراق العرض/الارتفاع:

context.canvas.width = context.canvas.width;

OR

context.canvas.height = context.canvas.height;

الايجابيات: يعمل مع IE سلبيات: إعادة تعيين strokeStyle ، fillStyle إلى black ؛ Laggy.

كنت أتساءل لماذا الحل الأصلي غير موجود. في الواقع ، تعتبر clearRect() بمثابة الحل المفرد لأن معظم المستخدمين يقومون بـ beginPath() قبل رسم أي مسار جديد. على الرغم من أن startPath يجب استخدامه فقط أثناء رسم الخطوط وليس المسار المغلق مثل rect().

هذا هو السبب في أن الإجابة المقبولة لم تحل مشكلتي وانتهى بي الأمر بإضاعة ساعات في محاولة الاختراقات المختلفة. لعنة لك موزيلا

14
sziraqui

طريقة سريعة هي القيام به

canvas.width = canvas.width

أتساءل كيف يعمل لكنه يعمل!

7
Jacob Morris

لقد وجدت أنه في جميع المتصفحات التي أختبرها ، فإن أسرع طريقة هي ملء الواقع باللون الأبيض ، أو أي لون تريده. لديّ شاشة كبيرة جدًا وفي وضع ملء الشاشة ، يكون clearRect بطيئًا بشكل مؤلم ، لكن fillRect معقول.

context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);

العيب هو أن القماش لم يعد شفافاً.

4
John Page

هذا عملت لبلدي pieChart في chart.js

<div class="pie_nut" id="pieChartContainer">
    <canvas id="pieChart" height="5" width="6"></canvas> 
</div>

$('#pieChartContainer').html(''); //remove canvas from container
$('#pieChartContainer').html('<canvas id="pieChart" height="5" width="6"></canvas>'); //add it back to the container
4
Sanal S
function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}
4
Imagine Breaker

في webkit ، تحتاج إلى ضبط العرض على قيمة مختلفة ، ثم يمكنك إعادة تعيينه إلى القيمة الأولية

4
John Allsopp

هذا هو ما أستخدمه ، بغض النظر عن الحدود وتحولات المصفوفة:

function clearCanvas(canvas) {
  const ctx = canvas.getContext('2d');
  ctx.save();
  ctx.globalCompositeOperation = 'copy';
  ctx.strokeStyle = 'transparent';
  ctx.beginPath();
  ctx.lineTo(0, 0);
  ctx.stroke();
  ctx.restore();
}

بشكل أساسي ، يحفظ الحالة الحالية للسياق ، ويرسم بكسلًا شفافًا مع copy كـ globalCompositeOperation . ثم ، يستعيد حالة السياق السابقة.

3
superruzafa

الطريق السريع:

canvas = document.getElementById("canvas");
c = canvas.getContext("2d");

//... some drawing here

i = c.createImageData(canvas.width, canvas.height);
c.putImageData(i, 0, 0); // clear context by putting empty image data
2
elser

هناك طريقة بسيطة ، ولكنها غير قابلة للقراءة ، وهي كتابة هذا:

var canvas = document.getElementId('canvas');

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas
2
Chang

أنا دائما استخدام

cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);
0
GameMaster1928
Context.clearRect(starting width, starting height, ending width, ending height);

مثال: context.clearRect(0, 0, canvas.width, canvas.height);

0
Gavin T
context.clearRect(0,0,w,h)   

املأ المستطيل المعطى بقيم RGBA:
0 0 0 0: مع Chrome
0 0 0 255: مع FF & Safari

لكن

context.clearRect(0,0,w,h);    
context.fillStyle = 'rgba(0,0,0,1)';  
context.fillRect(0,0,w,h);  

اسمحوا المستطيل مليئة
0 0 0 255
بغض النظر عن المتصفح!

0
Philippe Oceangermanique

إذا كنت تستخدم clearRect فقط ، إذا كان لديك نموذج لإرسال الرسم الخاص بك ، فستحصل على إرسال بدلاً من المقاصة ، أو ربما يمكن إزالته أولاً ثم تحميل رسم باطل ، لذلك ستحتاج إلى إضافة منعالتعذر عند بدء الوظيفة:

   function clearCanvas(canvas,ctx) {
        event.preventDefault();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }


<input type="button" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">

آمل أن يساعد شخص ما.

0
JoelBonetR