2014-06-10 14 views
5

Ich bin völlig neu in diesem Canvas Element. Ich bin in der Lage, Linie in Leinwand zu zeichnen, aber nicht in der Lage, nur spezifische Linie zu löschen. Ganze Leinwand wird leer.So löschen Sie bestimmte Zeile in Canvas: HTML5

dies versucht: HTML:

<canvas id="cvs" width="400" height="400"></canvas> 
<hr /> 
<input type="submit" id="reDrowA" value="Draw A" /> 
<input type="submit" id="reDrowB" value="Draw B" /> 
<hr /> 
<input type="submit" id="clearA" value="Clear A" /> 
<input type="submit" id="clearB" value="Clear B" /> 

Script

$(document).ready(function(){ 
    canvas = document.getElementById("cvs");  
    $("#reDrowA").on("click",function(){ 
     a = canvas.getContext('2d'); 
     a.translate(0.5, 0.5); 
     a.beginPath(); 
     a.setLineDash([2,10]); 
     a.moveTo(10,10); 
     a.lineTo(300,10); 
     a.lineTo(300,300); 
     a.stroke(); 
    }); 
    $("#reDrowB").on("click",function(){ 
     b = canvas.getContext('2d'); 
     b.translate(0.5, 0.5); 
     b.beginPath(); 
     b.setLineDash([2,10]); 
     b.moveTo(10,10); 
     b.lineTo(10,300); 
     b.lineTo(300,300); 
     b.stroke(); 
    }); 
    $("#clearA").on("click",function(){ 
     a.clearRect(0, 0, canvas.width, canvas.height); 
    }); 
    $("#clearB").on("click",function(){ 
     b.clearRect(0, 0, canvas.width, canvas.height); 
    }); 

}); 

Fiddle: http://jsfiddle.net/8YNvu/

+3

Soweit ich weiß, können Sie nicht auf ein bestimmtes Element im Canvas zugreifen, Sie müssen es vollständig löschen. Ich weiß nicht, was Ihre Anforderung ist, aber wenn Sie etwas wie Diagramme zeichnen und auf einzelne Elemente zugreifen möchten, reagieren Sie auf seine Ereignisse etc, schauen Sie in Svg ... –

+3

Sie können das nicht tun. Die Zeichenfläche ist eine Bitmap. Alles, was du darauf zeichnest, bleibt dort. Sie können bestimmte Zeichnungen anschließend nicht bearbeiten. Sie können es nur als Ganzes löschen. Wenn Sie "Objekte" auf der Leinwand zeichnen und sie später bearbeiten und entfernen möchten, müssen Sie diese Objekte selbst (in einem Array) verfolgen und dann über eine Zeichenfunktion verfügen, die die Zeichenfläche regelmäßig und im Rohzustand aktualisiert die aktuellen Objekte im Array. Um ein bestimmtes Objekt zu löschen, löschen Sie es einfach aus dem Array und zeichnen Sie es neu. – HaukurHaf

+0

Um zwei Zeilen zu verwalten, muss ich also zwei Canvas-Elemente erstellen? –

Antwort

8

Über Leinwand, Leinwand 'Elemente' und die Sichtbarkeit von `Elemente ...

Wenn ein Element auf der Leinwand ändern muss (verschieben, löschen, usw.), ist die Standardmethode, die Zeichenfläche vollständig zu löschen und die Zeichenfläche mit den Elementen an ihren neuen Positionen neu zu zeichnen (oder die Elemente nicht neu zu zeichnen, wenn sie gelöscht werden).

Das liegt daran, dass sich Canvas nicht "merkt", wo es ein einzelnes Element gezeichnet hat und daher kein Element einzeln bewegen oder löschen kann.

Es liegt an Ihnen, sich genügend Informationen über ein Element zu merken, um es nach dem Löschen des Canvas neu zu zeichnen.

A Demo: http://jsfiddle.net/m1erickson/Wrk2e/

Also in Ihrem Beispiel könnten Sie erstellen JavaScript-Objekte a und b zu Ihrem oberen rechten und linken unteren Leitungswege darstellen.

Jedes Objekt hätte die Punkte, die seinen Linienpfad definieren, und ein Flag, das angibt, ob es sichtbar ist (sichtbar == auf der Zeichenfläche neu gezeichnet).

// an array containing all the line-path objects 
var myObjects=[a,b]; 

Dann, wenn Sie die Leinwand löschen Sie einfach jede Objekte Line-Pfadinformationen verwenden, um die Linie neu zu zeichnen:

// create an object containing the top-right lines 
// the object contains its path points & if it is visible or not 
var a={ 
    path:[10,10, 300,10, 300,300], 
    isVisible:false, 
} 

// create an object containing the left-bottom lines 
// the object contains its path points & if it is visible or not 
var b={ 
    path:[10,10, 10,300, 300,300], 
    isVisible:false, 
} 

Für eine einfache Verarbeitung können Sie alle Ihre Line-Pfad in einem Array-Objekte setzen. Wenn ein Sichtbarkeitsflag für bestimmte Objekte false ist, dann zeichnen Sie dieses bestimmte Objekt nicht neu.

// clear the entire canvas 
// redraw any line-paths that are visible 
function redrawAll(myObjects){ 
    context.clearRect(0,0,canvas.width,canvas.height); 
    for(var i=0;i<myObjects.length;i++){ 
     if(myObjects[i].isVisible){ 
      drawLinePath(myObjects[i]); 
     } 
    } 
} 

// redraw 1 line-path 
function drawLinePath(theObject){ 
    var points=theObject.path; 
    // save the current untranslated context state 
    context.save(); 

    // draw lines through each point in the objects path 
    context.translate(0.5, 0.5); 
    context.beginPath(); 
    context.setLineDash([2,10]); 
    context.moveTo(points[0],points[1]); 
    for(var i=2;i<points.length;i+=2){ 
     context.lineTo(points[i],points[i+1]); 
    } 
    context.stroke(); 

    // restore the context to its untranslated state 
    context.restore(); 
} 

Damit alles an seinem Platz, Ihre Tasten einfach die Sichtbarkeit Flagge auf einem bestimmten Linie-Pfadobjekt ändern und dann klar/neu zeichnen die gesamte Leinwand.

+0

Ich denke, es ist eine perfekte Lösung, nach der ich suche. –

+1

Nur der Vollständigkeit halber, wenn man eine bestimmte Linie oder Form (wie ich) anstatt einer rechteckigen Region löschen wollte, können Sie 'context.globalCompositeOperation =" destination-out "' - wie erwähnt in andrewmus Lösung einer [ähnlichen Frage] (http://stackoverflow.com/questions/3328906/erasing-in-html5-canvas) - wird im Grunde Ihre Fill/Stroke-Operationen genau wie ein Radiergummi-Werkzeug wirken. Sehen Sie dies [Lernprogramm zum Erstellen und Abschneiden] (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing). Dies würde jedoch das Löschen von geschichteten Elementen nicht ermöglichen. – TheMadDeveloper

+1

@TheMadDeveloper. Sie erwähnen einen guten Folgepunkt. Beachten Sie, dass das Löschen einer Konturenlinie mit Ziel-Out-Compositing manchmal ineffektiv ist, da das Anti-Aliasing, das die Leinwand zur Linie hinzufügt, oft nicht gelöscht wird. Aber Ziel-Out funktioniert gut für context.fill. :-) – markE

2

Leinwand transparent ist. Es ist nicht möglich, acheive in single canvas tag. weil die clearRect Funktionalität basierend auf Breite und Höhe zu löschen. Wir haben nicht die genaue Position angegeben, um die Leinwand zu räumen. Probieren Sie die Geige. Sie erhalten das Szenario mit zwei Canvas-Tags.

Fiddle

+0

Dank bekam es genau –

+0

@sudharsan. Es gibt einen besseren Weg (und einen Standardweg) mit "Elementen" wie Linienpfaden in Canvas umzugehen. Bitte sehen Sie meinen Beitrag. ;-) – markE

0

Sie müssen nur re-paint the lines dass beharren sollten, nachdem Sie die Leinwand löschen.
Vielleicht so: http://jsfiddle.net/8YNvu/10/

+0

Ich erstelle eine Flow-Chart-Typ-Funktionalität, also denke ich, dass der vorgeschlagene Vorschlag nicht funktioniert. Der Benutzer kann N Zeilen und Objekte darin erstellen. In diesem Fall wird das nicht funktionieren. korrigiere mich, wenn ich falsch liege. –