2010-06-23 15 views
10

Tüm HTML5 ve Javascript'te bir eskizleme uygulamasına sahibim ve bir Geri Alma Düğmesi nasıl oluşturacağımı merak ettim, böylece çizdiğiniz son şeyi geri alabilirsiniz. Herhangi bir fikir?HTML5 Canvas'a nasıl geri-işlevsellik eklenir?

+1

[komut deseni] 'ne göz atın (http://en.wikipedia.org/wiki/Command_pattern) – Anurag

+1

Neden java ve objektif-c etiketleriniz var? –

cevap

13

Tüm değişikliklerin bir veri yapısında depolanması gerekir. Sonra kullanıcı ve geri almak istiyorsa son değişikliği silebilirsiniz. Ardından tüm çizim işlemlerini tekrar veri sayfanızdan yeniden çizersiniz.

+0

Bunun nasıl yapılacağına dair bir örnek için lütfen http://whiffdoc.appspot.com/tests/schema/diagram adresine bakın - bu durumda, tuval bilgisini görünmez bir DIV elemanında temsil eden bir JSON veri yapısını depolayarak. (Link sayfadaki linki takip ediniz) –

+1

@AaronWatters, bu link beni 404'e yönlendiriyor. Güncellenmiş linke sahip misiniz? – link2pk

3

Açık http://arthurclemens.github.io/Javascript-Undo-Manager/ Bir tuval öğesi ile geri alma için çalışan bir örneğim var. Bir değişiklik yaptığınızda, geri alma yöneticisini geri alma ve yeniden yöntemlerini beslersiniz. Geri alma yığındaki konumun izlenmesi otomatik olarak yapılır. Kaynak kodu Github'da.

+0

örneğiniz iyi görünüyor! Paylaşımınız için teşekkürler –

+0

Chrome'da iyi görünüyor, ancak Firefox'ta çalışmaz – waspinator

+0

Demoda birkaç küçük çizim hatası giderdim. –

1

Nesneleri değiştirmeniz gerekiyorsa, diğer seçenek, yeniden yazdırmayı engelleyen Canvas API'sini koruyan bir kitaplık kullanarak tuvalinizi SVG'ye dönüştürmektir. SVGKit

SVG gerçekleştirdikten sonra, tüm tuval yeniden çizmek gerek kalmadan nesneleri ve çok daha fazlası kaldırmak için çok daha kolaydır:

en az bir tür kütüphane bu kez (Kasım 2011) de bulunmaktadır.

+2

Ya da tuval üzerine nesnelerle programlı olarak çalışabilmek için [fabric.js] (http://kangax.github.com/fabric.js/) gibi tuval soyutlama kitaplığını kullanabilir. – kangax

+0

Mükemmel @kangax. Merak ediyorum, fabric.js'nin yüzlerce düğümle tuvalde objeleri düzenlemede performans açısından SVGKit ile nasıl kıyaslanacağını düşünüyorsunuz? –

+0

Nasıl SVGKit ile karşılaştırıldığında emin değilim, ama çok sayıda tuval geldiğinde tuval SVG daha performanslı olma eğilimindedir. Raphael (SVG-based) ve fabric (canvas-based) 'i karşılaştıran bazı kıyaslamalara göz atın - http://fabricjs.com/benchmarks/ – kangax

0

İşte benim için çalışan bir çözüm. Firefox ve Chrome'un en son sürümlerinde denedim ve bu iki tarayıcıda gerçekten iyi çalışıyor.

var isFirefox = typeof InstallTrigger !== 'undefined'; 
var ctx = document.getElementById('myCanvas').getContext("2d"); 
var CanvasLogBook = function() { 
    this.index = 0; 
    this.logs = []; 
    this.logDrawing(); 
}; 
CanvasLogBook.prototype.sliceAndPush = function(imageObject) { 
    var array; 
    if (this.index == this.logs.length-1) { 
     this.logs.push(imageObject); 
     array = this.logs; 
    } else { 
     var tempArray = this.logs.slice(0, this.index+1); 
     tempArray.push(imageObject); 
     array = tempArray; 
    } 
    if (array.length > 1) { 
     this.index++; 
    } 
    return array; 
}; 
CanvasLogBook.prototype.logDrawing = function() { 
    if (isFirefox) { 
     var image = new Image(); 
     image.src = document.getElementById('myCanvas').toDataURL(); 
     this.logs = this.sliceAndPush(image); 
    } else { 
     var imageData = document.getElementById('myCanvas').toDataURL(); 
     this.logs = this.sliceAndPush(imageData); 
    } 
}; 
CanvasLogBook.prototype.undo = function() { 
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height()); 
    if (this.index > 0) { 
     this.index--; 
     this.showLogAtIndex(this.index); 
    } 
}; 
CanvasLogBook.prototype.redo = function() { 
    if (this.index < this.logs.length-1) { 
     ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height()); 
     this.index++; 
     this.showLogAtIndex(this.index); 
    } 
}; 
CanvasLogBook.prototype.showLogAtIndex = function(index) { 
    ctx.clearRect(0, 0, $('#myCanvas').width(), $('#myCanvas').height()); 
    if (isFirefox) { 
     var image = this.logs[index]; 
     ctx.drawImage(image, 0, 0); 
    } else { 
     var image = new Image(); 
     image.src = this.logs[index]; 
     ctx.drawImage(image, 0, 0); 
    } 
}; 
var canvasLogBook = new CanvasLogBook(); 

Yani çalışma fonksiyonu canvasLogBook.logDrawing() tuvale anlık orada saklamak için olacak sonra herhangi bir şey çizmek ve daha sonra canvasLogBook.undo() çağırabilir her zaman geri alabilir ve canvasLogBook.redo için() yeniden yapmak.

+0

Eğer jQuery'ye güvenmediyseniz ve 'isFirefox' boolean'ından kurtulursanız bu iyi bir cevap olur :) – A1rPun