[英]How to step back in HTML5 Canvas history
我有一個使用Imgly HTML5 Canvas插件的圖像裁剪器。 我需要能夠為種植者設置歷史記錄堆棧,才能撤消種植操作。 當前,我可以在單擊按鈕時清除畫布,但是我需要能夠保留原始圖像,並且在裁剪步驟執行不正確的情況下,只需回顧一下畫布中圖像的變化歷史即可。
我有以下內容可以簡單地清除畫布:
$("#renderButton").click(function() {
var elem = $(".imgly-canvas");
var canvas = elem.get(0);
var context = canvas.getContext("2d");
$('#file').val('');
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
});
該插件在圖像加載時使用以下命令創建canvas元素:
Utils.getImageDataForImage = function(image) {
var canvas, context;
canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
return context.getImageData(0, 0, image.width, image.height);
};
這用於調整大小:
Utils.cloneImageData = function(imageData) {
var i, newImageData, _i, _ref;
newImageData = this.sharedContext.createImageData(imageData.width, imageData.height);
for (i = _i = 0, _ref = imageData.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
newImageData.data[i] = imageData.data[i];
}
return newImageData;
};
/*
@param {Object} dimensions
@param {Integer} dimensions.width
@param {Integer} dimensions.height
@returns {HTMLCanvasElement}
*/
Utils.newCanvasWithDimensions = function(dimensions) {
var canvas;
canvas = document.createElement("canvas");
canvas.width = dimensions.width;
canvas.height = dimensions.height;
return canvas;
};
/*
@param {imageData} imageData
@returns {HTMLCanvasElement}
*/
Utils.newCanvasFromImageData = function(imageData) {
var canvas, context;
canvas = document.createElement("canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
context = canvas.getContext("2d");
context.putImageData(imageData, 0, 0);
return canvas;
};
因此,我不確定如何構建一個調用堆棧來引用每個更改,並回溯到對畫布中圖像的修改歷史。
HTML5畫布很好地轉換為JSON,然后可用於重新加載畫布。 您可以將其存儲在全局對象中。
var myObj = window.myObj || {};
myObj = {
history: [],
canvas: null
};
獲取畫布數據:
myObj.canvas = document.getElementById('canvas-id');
var ctx = myObj.canvas.getContext('2d');
var data = JSON.stringify(ctx.getImageData(0, 0, myObj.canvas.width, myObj.canvas.height));
myObj.history.push(data);
重新加載數據:
var reloadData = JSON.parse(myObj.history[someIndex]);
var ctx = myObj.canvas.getContext('2d');
ctx.putImageData(reloadData, 0, 0);
一旦可以存儲/加載數據,最棘手的部分就是管理myObj.history
數組。
您應該查看命令模式 。 基本上,您需要為用戶可以執行的每個操作編寫一個函數。 當他們單擊按鈕或加載圖像時,請勿立即調用該函數。 而是創建一個命令對象,其中包含執行命令所需的所有信息以及撤消命令所需的信息。
命令應用於數據模型(圖像和裁切標記)。 命令“加載圖像”需要記錄新的和先前的圖像URL,以便在瀏覽歷史記錄時可以加載正確的圖像。
對於裁切命令,您需要存儲新舊裁切矩形-如果您保留原始圖像的副本。 執行命令后,將新的裁切矩形應用於原始裁切矩形並將其繪制在畫布上。
對於撤消,使用原始圖像和先前的裁剪矩形。
因此,訣竅是定義一個數據模型,其中包含UI外觀的所有信息(通常很難直接從UI獲取-在將裁剪后的圖像渲染到畫布后無法獲取裁剪信息)。 然后,這些命令將操縱該狀態(以便下一個命令可以將其保存為撤消操作)並更新UI。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.