globalcompositeoperation - javascript canvas properties




Come cancellare la tela per il ridisegno (14)

Dopo aver sperimentato operazioni composite e disegnato immagini sulla tela, sto cercando di rimuovere immagini e compositing. Come faccio a fare questo?

Ho bisogno di cancellare la tela per ridisegnare altre immagini; questo può andare avanti per un po 'quindi non penso che disegnare un nuovo rettangolo ogni volta sia l'opzione più efficiente.


Usa: context.clearRect(0, 0, canvas.width, canvas.height);

Questo è il modo più rapido e più descrittivo per cancellare l'intera tela.

Non utilizzare: canvas.width = canvas.width;

Il reset di canvas.width reimposta tutti gli stati del canvas (es. Trasformazioni, lineWidth, strokeStyle, ecc.), È molto lento (rispetto a clearRect), non funziona su tutti i browser e non descrive ciò che stai effettivamente provando fare.

Trattare con le coordinate trasformate

Se è stata modificata la matrice di trasformazione (ad esempio utilizzando la scale , la rotate o la translate ), allora context.clearRect(0,0,canvas.width,canvas.height) probabilmente non cancellerà l'intera porzione visibile del canvas.

La soluzione? Reimposta la matrice di trasformazione prima di cancellare la tela:

// 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();

Modifica: ho appena eseguito alcune operazioni di profilazione e (in Chrome) è circa il 10% più veloce per cancellare una tela di 300 x 150 (dimensioni predefinite) senza reimpostare la trasformazione. A mano a mano che le dimensioni della tua tela aumentano, questa differenza diminuisce.

Questo è già relativamente insignificante, ma nella maggior parte dei casi ti attirerai molto più di quello che stai schiarendo e credo che questa differenza di prestazioni sia irrilevante.

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

Altri hanno già svolto un ottimo lavoro rispondendo alla domanda, ma se un semplice metodo clear() sull'oggetto di contesto ti sarebbe stato utile (era per me), questa è l'implementazione che uso in base alle risposte qui:

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();
    }           
};

Uso:

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
};

Questi sono tutti ottimi esempi di come si cancella una tela standard, ma se si utilizza paperjs, allora funzionerà:

Definisci una variabile globale in JavaScript:

var clearCanvas = false;

Dal tuo PaperScript definisci:

function onFrame(event){
    if(clearCanvas && project.activeLayer.hasChildren()){
        project.activeLayer.removeChildren();
        clearCanvas = false;
    }
}

Ora, ovunque tu abbia impostato clearCanvas su true, cancellerà tutti gli elementi dallo schermo.


Questo è il 2018 e ancora non esiste un metodo nativo per cancellare completamente la tela per il ridisegno. clearRect() non cancella completamente il canvas. I disegni di tipo non di riempimento non vengono cancellati (ad esempio rect() )

1. Per cancellare completamente la tela indipendentemente dal modo in cui disegni:

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

Pro: preserva strokeStyle, fillStyle ecc .; Nessun ritardo;

Contro: non necessario se stai già utilizzando beginPath prima di disegnare qualcosa

2.Utilizzo della modifica della larghezza / altezza:

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

O

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

Pro: funziona con IE Contro: reimposta strokeStyle, fillStyle su nero; lag;

Mi stavo chiedendo perché una soluzione nativa non esiste. In realtà, clearRect() è considerata la soluzione a linea singola poiché la maggior parte degli utenti fa beginPath() prima di disegnare qualsiasi nuovo percorso. Anche se beginPath deve essere usato solo mentre si disegnano linee e non il percorso chiuso come rect().

Questo è il motivo per cui la risposta accettata non ha risolto il mio problema e ho finito per perdere ore a provare diversi hack. Maledetti mozilla


Questo ha funzionato per il mio grafico a torta in 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

Se stai disegnando linee, assicurati di non dimenticare:

context.beginPath();

Altrimenti le linee non verranno cancellate.


Un modo rapido è quello di fare

canvas.width = canvas.width

Idk come funziona ma lo fa!


Un modo semplice, ma non molto leggibile è quello di scrivere questo:

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

// after doing some rendering

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

ci sono un sacco di buone risposte qui. un'ulteriore nota è che a volte è divertente cancellare solo parzialmente la tela. cioè "dissolve" l'immagine precedente invece di cancellarla completamente. questo può dare effetti di sentieri piacevoli.

è facile. supponendo che il colore dello sfondo sia bianco:

// 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);

modo più veloce:

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

Context.clearRect(starting width, starting height, ending width, ending height);

Esempio: context.clearRect(0, 0, canvas.width, canvas.height);


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

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

function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}

  • Chrome risponde bene a: context.clearRect ( x , y , w , h ); come suggerito da @ Pentium10 ma IE9 sembra ignorare completamente questa istruzione.
  • IE9 sembra rispondere a: canvas.width = canvas.width; ma non cancella linee, solo forme, immagini e altri oggetti a meno che tu non usi la soluzione di @John Allsopp di cambiare prima la larghezza.

Quindi se hai una tela e un contesto creato in questo modo:

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

Puoi usare un metodo come questo:

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




composite