2014-06-10 9 views
5

Jestem całkowicie nowym elementem tego płótna. Jestem w stanie narysować linię na płótnie, ale nie jestem w stanie usunąć tylko określonej linii. Całe płótno staje się puste.Jak wyczyścić określoną linię w obszarze Canvas: HTML5

Tried to: 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

Z tego co wiem, nie można uzyskać dostępu do konkretnego elementu w obszarze roboczym, należy go całkowicie usunąć. Nie wiem, jakie są twoje wymagania, ale jeśli rysujesz coś na kształt wykresów i chcesz uzyskać dostęp do poszczególnych przedmiotów, reaguj na wydarzenia itp., Spójrz na svg ... –

+3

Nie możesz tego zrobić. Płótno jest bitmapą. Wszystko, co na nim rysujesz, zostaje. Nie możesz później manipulować konkretnymi rysunkami. Możesz to wyczyścić tylko jako całość. Jeśli chcesz móc rysować "obiekty" na płótnie i manipulować nimi później i usuwać je, musisz śledzić te obiekty samodzielnie (w tablicy), a następnie mieć funkcję rysowania, która regularnie aktualizuje płótno i przetwarza wszystkie bieżące obiekty w tablicy. Aby wyczyścić określony obiekt, po prostu wyczyść go z tablicy i przerysuj. – HaukurHaf

+0

Aby zarządzać dwiema liniami, Czy muszę utworzyć dwa elementy Canvas? –

Odpowiedz

8

O płótnie, 'elementy' płótno, a widoczność `elementów ...

Kiedy każdy element na płótnie musi się zmienić (ruch, usunąć itd.), standardową metodą jest całkowite usunięcie płótna i ponowne narysowanie płótna z elementami w ich nowych pozycjach (lub nieodświeżanie elementów, jeśli są wymazywane).

To dlatego, że płótno nie "pamięta", gdzie narysowało żadnego indywidualnego elementu i dlatego nie może indywidualnie przenosić ani wymazywać żadnego elementu.

Od ciebie zależy, czy "zapamiętasz" wystarczająco dużo informacji o elemencie, aby przerysować go po usunięciu płótna.

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

Więc w swojej przykład można utworzyć obiektów javascript a i b reprezentować swój prawy górny i ścieżek linii lewy-dolny.

Każdy obiekt będzie miał punkty, które definiują jego ścieżkę linii i flagę wskazującą, czy jest widoczna (widoczna == przerysowana na płótnie).

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

Dla łatwego przetwarzania można umieścić wszystkie swoje line-ścieżka obiektów w tablicy:

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

Wtedy, kiedy jasne płótno po prostu użyć każdą informację obiekty liniowe ścieżki odświeżenia linii. Jeśli znacznikiem widoczności poszczególnych obiektów jest false, nie przerysuj tego konkretnego obiektu.

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

Mając to wszystko na swoim miejscu, twoje przyciski po prostu zmienić flagę widoczność danego obiektu liniowego toru a następnie clear/przerysować całą płótnie.

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

Myślę, że to idealne rozwiązanie, którego szukam. –

+1

Tylko dla zachowania kompletności, jeśli ktoś chciałby wyczyścić konkretną linię lub kształt (tak jak ja), zamiast prostokątnego regionu, można ustawić "context.globalCompositeOperation =" destination-out "' - jak wspomniano w rozwiązaniu andrewmu na [podobne pytanie] (http://stackoverflow.com/questions/3328906/erasing-in-html5-canvas) - zasadniczo sprawi, że operacje wypełniania/obrysu będą działać jak narzędzie gumki. Zobacz ten samouczek dotyczący komponowania i wycinania (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing). Nie pozwoliłoby to jednak na usunięcie elementów warstwowych. – TheMadDeveloper

+1

@MadDeveloper. Wspominasz dobry punkt obserwacyjny. Należy pamiętać, że wymazywanie obrysowanej linii z kompozycją docelową jest czasami nieefektywne, ponieważ wygładzanie, które jest dodawane do linii, często nie jest wymazywane. Ale docelowa funkcja działa dobrze dla kontekstu.fill. :-) – markE

2

Płótno jest przezroczysty. Nie jest możliwe acheive in single canvas tag. ponieważ funkcja clearRect służy do czyszczenia na podstawie szerokości i wysokości. nie podaliśmy dokładnej pozycji, aby wyczyścić płótno. Spróbuj skrzypce. realizujesz scenariusz za pomocą dwóch tagów canvas.

Fiddle

+0

Dzięki temu otrzymałem dokładnie –

+0

@sudharsan. Istnieje lepszy sposób (i bardziej standardowy sposób) radzenia sobie z "elementami", takimi jak ścieżki linii na płótnie. Proszę zobaczyć mój post. ;-) – markE

0

Po prostu trzeba re-paint the lines który powinien utrzymywać się po usunięciu płótna.
Może tak: http://jsfiddle.net/8YNvu/10/

+0

Tworzę funkcje typu wykresu przepływu, więc sugerowana przez ciebie propozycja może nie działać. Użytkownik może utworzyć liczbę N linii i obiektów w nim. W takim przypadku to nie zadziała. Popraw mnie, jeśli się mylę. –