2014-06-10 16 views
5

Sono totalmente nuovo in questo elemento Canvas. Sono in grado di disegnare linee su tela, ma non in grado di cancellare solo la linea specifica. Tutta la tela diventa vuota.Come cancellare una linea specifica in Canvas: HTML5

provato questo: 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

Per quanto ne so, non è possibile accedere a un elemento specifico nell'area di disegno, è necessario eliminarlo completamente. Non so quale sia la tua esigenza, ma se stai disegnando qualcosa come grafici e vuoi accedere a singoli elementi, rispondi ai suoi eventi ecc, guarda in svg ... –

+3

Non puoi farlo. La tela è una bitmap. Tutto ciò che disegni su di esso rimane lì. Non è possibile manipolare disegni specifici in seguito. Puoi solo cancellarlo nel suo complesso. Se vuoi essere in grado di disegnare "oggetti" sulla tela e manipolarli in seguito e rimuoverli, è necessario tenere traccia di questi oggetti da soli (in una matrice) e quindi disporre di una funzione di disegno che aggiorna la tela regolarmente e raws tutti gli oggetti correnti nell'array. Per cancellare un oggetto specifico, basta cancellarlo dalla matrice e ridisegnarlo. – HaukurHaf

+0

Quindi, per gestire due linee, devo creare due elementi Canvas? –

risposta

8

A proposito di tela di canapa, 'elementi' di tela, e la visibilità del `elementi ...

Quando un qualsiasi elemento sulla tela ha bisogno di cambiare (spostamento, cancellazione, ecc.), il metodo standard è di cancellare completamente la tela e ridisegnare la tela con gli elementi nelle loro nuove posizioni (o non ridisegnare gli elementi se vengono cancellati).

Questo perché la tela non "ricorda" dove ha disegnato un singolo elemento e quindi non può spostare o cancellare individualmente alcun elemento.

Spetta a te "ricordare" informazioni sufficienti su un elemento per ridisegnarlo dopo che la tela è stata cancellata.

una demo: http://jsfiddle.net/m1erickson/Wrk2e/

Quindi nel tuo esempio si potrebbe creare oggetti JavaScript a e b per rappresentare i percorsi di linea in basso a sinistra e in alto a destra.

Ogni oggetto avrebbe i punti che definiscono il suo percorso di linea e una bandiera che indica se è visibile (visibile == ridisegnato sull'area di disegno).

// 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, 
} 

Per facilità di lavorazione si può mettere tutti gli oggetti vostra linea-path in un array:

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

Poi, quando si cancella la tela è sufficiente utilizzare ogni informazione oggetti line-percorso per ridisegnare la linea. Se un flag di visibilità di oggetti particolari è false, non ridisegnare quel particolare oggetto.

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

Con tutto questo in luogo, i pulsanti semplicemente cambiare la bandiera visibilità su un particolare oggetto linea-percorso e poi chiaro/ridisegnare l'intera tela.

// use buttons to set & clear the visibility flags on objects 
// In all cases, clear the entire canvas and redraw any visible objects 

$("#reDrowA").on("click",function(){ 
    a.isVisible=true; 
    redrawAll(myObjects); 
}); 
$("#reDrowB").on("click",function(){ 
    b.isVisible=true; 
    redrawAll(myObjects); 
}); 
$("#clearA").on("click",function(){ 
    a.isVisible=false; 
    redrawAll(myObjects); 
}); 
$("#clearB").on("click",function(){ 
    b.isVisible=false; 
    redrawAll(myObjects); 
}); 
+0

Penso che sia una soluzione perfetta che sto cercando. –

+1

Solo per motivi di completezza, se si volesse cancellare una linea o una forma specifica (come ho fatto io), piuttosto che una regione rettangolare, è possibile impostare 'context.globalCompositeOperation =" destination-out "' - come accennato nella soluzione di andrewmu a una [domanda simile] (http://stackoverflow.com/questions/3328906/erasing-in-html5-canvas) - fondamentalmente farà in modo che le operazioni di riempimento/corsa agiscano proprio come uno strumento gomma. Vedi questo [tutorial di compositing e clipping] (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing). Ciò non consentirebbe la cancellazione di elementi sovrapposti, però. – TheMadDeveloper

+1

@ TheMadDeveloper. Lei cita un buon punto di follow-on. Tieni presente che la cancellazione di una linea tratteggiata con compositing di destinazione a volte è inefficace perché l'anti-aliasing che la tela aggiunge alla linea non viene spesso cancellato. La destinazione out-out funziona bene per context.fill. :-) – markE

2

tela è trasparente. Non è possibile acheive in single canvas tag. perché la funzionalità clearRect si cancella in base alla larghezza e all'altezza. non abbiamo dato la posizione esatta per cancellare la tela. Prova il violino. ottieni lo scenario con due tag di tela.

Fiddle

+0

Grazie, ho capito esattamente –

+0

@sudharsan. C'è un modo migliore (e un modo più standard) di trattare gli "elementi" come i percorsi di linea nella tela. Si prega di vedere il mio post. ;-) – markE

0

Devi solo re-paint the lines che dovrebbe persistere dopo aver deselezionato Canvas.
Forse in questo modo: http://jsfiddle.net/8YNvu/10/

+0

Sto creando alcune funzionalità del tipo di diagramma di flusso, quindi suppongo che il suggerimento fornito potrebbe non funzionare. L'utente può creare N numero di linee e oggetti al suo interno. In tal caso, questo non funzionerà. correggimi se sbaglio. –