2014-09-13 3 views
0
나는 Adobe Photoshop과 같은 응용 프로그램을 다시 이동하거나 처음부터 각각의 스트로크를 다시 그릴 필요없이 래스터 그래픽에 스트로크를 취소 할 수있는 능력과 자신의 그림의 역사를 구현하는 방법을 알고 궁금

...HTML5 캔버스 그리기 역사

내가 작업하고있는 HTML5 드로잉 응용 프로그램에서 비슷한 역사 함수를 구현하고 싶지만 모든 스 토크 후에 캔버스를 복제하는 것은 실용적인 접근 방법, 특히 큰 캔버스에서 너무 많은 메모리를 사용하는 것처럼 보입니다. '

실용적이고 효율적인 방식으로 구현되는 방법에 대한 제안이 있으십니까? 나는 해결책을 가지고 있습니다

+2

각 획 이후에 전체 캔버스를 저장하지 마십시오. 각 그리기 명령을 배열에 저장하십시오. 그런 다음 배열 끝에서 마지막 요소를 터뜨리고 캔버스를 지우고 나머지 요소를 모두 다시 그립니다 (== 나머지 모든 드로잉 명령을 다시 실행). – markE

+0

그래, 다시 그리는 데 너무 오래 걸리기 때문에 피하기 위해 노력하고있어 ... Photoshop 및 유사한 응용 프로그램이 어떻게 처리하는지, 처음부터 모든 것을 다시 그려 내지 않는지 궁금합니다. – user1960364

+0

캔버스가 충분히 빠릅니다. 대부분의 그림을 처음부터 다시 그릴 수 있습니다. Photoshop 소스가 없어도 PS가 실제로 래스터 중단 점 전체를 저장하는 대신 명령을 사용하여 처음부터 다시 그립니다. 추신 : PS 기록에 모든 명령이 나와 있기 때문에이 말을합니다. PS 액션은 확실히 명령을 실행하여 작동합니다. – markE

답변

1

.....

var ctx = document.getElementById("canvasId").getContext("2d"); 
var DrawnSaves = new Array(); 
var Undo = new Array(); 
var FigureNumber = 0; 
var deletingTimer; 
function drawLine(startX, startY, destX, destY) { 
    ctx.beginPath(); 
    ctx.moveTo(startX, startY); 
    ctx.lineTo(destX, destY); 
    ctx.stroke(); 
    var Para = new Array(); 
    Para["type"] = "line"; 
    Para["fromX"] = startX; 
    Para["fromY"] = startY; 
    Para["toX"] = destX; 
    Para["toY"] = destY; 
    DrawnSaves.push(Para); 
    FigureNumber++; 
} 
function undo() { 
    ctx.beginPath(); 
    ctx.clearRect(0, 0, 500, 500); 
    Undo[FigureNumber] = DrawnSaves[FigureNumber]; 
    DrawnSaves[FigureNumber] = "deleted"; 
    FigureNumber--; 
    drawEverything(); 
    startTimeoutOfDeleting(); 
} 
function undoTheUndo() { 
    FigureNumber++; 
    DrawnSaves[FigureNumber] = Undo[FigureNumber]; 
    drawEverything(); 
    clearTimeout(deletingTimer); 
} 
function drawEverything() { 
    for (i = 0; i < DrawnSaves.length; i++) { 
     if (DrawnSaves[i].type == "line") { 
      ctx.beginPath(); 
      ctx.moveTo(DrawnSaves[i].fromX, DrawnSaves[i].fromY); 
      ctx.lineTo(DrawnSaves[i].toX, DrawnSaves[i].toY); 
      ctx.stroke(); 
     } 
    } 
} 
function startTimeoutOfDeleting() { 
    setTimeout(function() {Undo[FigureNumber] = "deleted";}, 5000); 
} 

이 정말 간단합니다, 처음에는 함수가 호출 될 때 라인을 그리고 배열에 자신의 모든 매개 변수를 저장합니다. 그런 다음 실행 취소 기능에서 타이머를 시작하여 그림을 2000 밀리 초로 삭제하고 전체 캔버스를 지우고 다시 그릴 수 없습니다. undoTheUndo 함수에서 타이머를 중지하여 그림을 삭제하고 그림을 다시 그릴 수있게합니다. drawEverything 함수에서 배열의 모든 것을 그 유형 ("여기에 줄")에 따라 그립니다. 그게 전부예요 :-) 다음은 작동하는 예제입니다.