繁体   English   中英

如何退回到HTML5 Canvas历史记录

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM