如何使用数组添加撤消列表?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用数组添加撤消列表?相关的知识,希望对你有一定的参考价值。
我正在尝试用javascript制作一个绘图程序,我想要包含一个undo-function(不是橡皮擦)。如何将所有事件添加到数组中,然后逐个删除它们?
我有一个工具下拉列表(到目前为止只有四个工作)。我添加了一个带id的撤消按钮。我已经尝试了几个小时(实际上是几天)来了解如何做到这一点。我找到了一些例子,我想我必须同时使用push和一个空数组来进一步发展?
这是工具选择和按钮的代码
<label>
Object type:
<select id="selectTool">
<option value="line">Linje</option>
<option value="pencil">Blyant</option>
<option value="rect">Rektangel</option>
<option value="circle">Sirkel</option>
<option value="oval">Oval</option>
<option value="polygon">Polygon</option>
</select>
Shape drawn:
<select id="shapeDrawn">
<option value=""></option>
</select>
<input type="button" id="cmbDelete" value="Undo last action">
</label>
撤消功能可能是这样的,但这个功能
var shapes = [];
shapes.push(newShape);
function cmbDeleteClick()
if(shapes.length > 0)
var selectedShapeIndex = selectShape.selectedIndex;
shapes.splice(selectedShapeIndex,1);
selectShape.options.remove(selectedShapeIndex);
selectShape.selectedIndex = selectShape.options.length - 1;
cmbDelete = document.getElementById("cmbDelete");
cmbDelete.addEventListener("click",cmbDeleteClick, false);
fillSelectShapeTypes();
drawCanvas();
理想情况下,画布上绘制的所有内容都会添加到下拉菜单中,并且可以通过单击按钮将其删除(撤消)。这是代码JS Bin的“工作”版本
答案
您当前的实现不使用shapes
数组,并且无法在创建它们之后重绘它们。
因此,最简单的方法是将每个操作存储为位图。所以你需要一个位图数组,让我们调用它:
var history = [];
绘制完东西之后,我们创建当前画布的快照并将其存储在该数组中:
history.push(contextTmp.getImageData(0,0,canvasTmp.width,canvasTmp.height))
如果要撤消操作,请弹出历史记录并在画布上绘制最后一个位图:
function cmbDeleteClick()
history.pop()
contextTmp.putImageData(history[history.length-1],0,0)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Paint</title>
<style type="text/css">
#content position: relative;
#cvs border: 1px solid #c00;
#cvsTmp position: absolute; top: 1px; left: 1px;
</style>
</head>
<body>
<p>
<label>
Object type:
<select id="selectTool">
<option value="line">Linje</option>
<option value="pencil">Blyant</option>
<option value="rect">Rektangel</option>
<option value="circle">Sirkel</option>
<option value="oval">Oval</option>
<option value="polygon">Polygon</option>
</select>
Shape drawn:
<select id="shapeDrawn">
<option value=""></option>
</select>
History:
<select id="historySelect">
</select>
<input type="button" id="cmbDelete" value="Undo last action">
</label>
</p>
<div id="content">
<canvas id="cvs" width="1024" height="512"></canvas>
</div>
<script type="text/javascript">
if(window.addEventListener)
window.addEventListener('load', function ()
var canvas;
var context;
var canvasTmp;
var contextTmp;
var tool;
var toolDefault = 'line';
var cmbDelete = null;
var shapes = [];
var history = [];
var historySelect;
// Canvas and temp. canvas
function init ()
canvasTmp = document.getElementById('cvs');
if (!canvasTmp)
return;
if (!canvasTmp.getContext)
return;
historySelect = document.getElementById('historySelect')
historySelect.addEventListener('change', ()=>
restoreHistoryAction(historySelect.value)
)
contextTmp = canvasTmp.getContext('2d');
if (!contextTmp)
return;
// Add the temporary canvas.
var content = canvasTmp.parentNode;
canvas = document.createElement('canvas');
if (!canvas)
return;
canvas.id = 'cvsTmp';
canvas.width = canvasTmp.width;
canvas.height = canvasTmp.height;
content.appendChild(canvas);
context = canvas.getContext('2d');
// Get the tool select input.
var toolSelect = document.getElementById('selectTool');
if (!toolSelect)
return;
toolSelect.addEventListener('change', ev_tool_change, false);
// Activate the default tool.
if (tools[toolDefault])
tool = new tools[toolDefault]();
toolSelect.value = toolDefault;
// Attach the mousedown, mousemove and mouseup event listeners.
canvas.addEventListener('mousedown', evMouse, false);
canvas.addEventListener('mousemove', evMouse, false);
canvas.addEventListener('mouseup', evMouse, false);
drawCanvas()
function evMouse (ev)
if (ev.layerX || ev.layerX == 0)
ev._x = ev.layerX;
ev._y = ev.layerY;
var evHandler = tool[ev.type];
if (evHandler)
evHandler(ev);
// The event handler for any changes made to the tool selector.
function toolChange (ev)
if (tools[this.value])
tool = new tools[this.value]();
// Updates Canvas on interval timeout
function drawCanvas()
contextTmp.drawImage(canvas, 0, 0);
history.push(contextTmp.getImageData(0,0,canvasTmp.width,canvasTmp.height))
updateHistorySelection()
context.clearRect(0, 0, canvas.width, canvas.height);
function ev_tool_change (ev)
if (tools[this.value])
tool = new tools[this.value]();
// Get excact position for mouse coordinates in canvas
function mouseAction (ev)
if (ev.layerX || ev.layerX == 0)
ev._x = ev.layerX;
ev._y = ev.layerY;
// Call the event handler of the tool.
var func = tool[ev.type];
if (func)
func(ev);
function selectShapeChange()
drawCanvas();
var tools = ;
// The drawing pencil.
tools.pencil = function ()
var tool = this;
this.started = false;
this.mousedown = function (ev)
context.beginPath();
context.moveTo(ev._x, ev._y);
tool.started = true;
;
this.mousemove = function (ev)
if (tool.started)
context.lineTo(ev._x, ev._y);
context.stroke();
;
this.mouseup = function (ev)
if (tool.started)
tool.mousemove(ev);
tool.started = false;
drawCanvas();
;
;
// The rectangle tool.
tools.rect = function ()
var tool = this;
this.started = false;
this.mousedown = function (ev)
tool.started = true;
tool.x0 = ev._x;
tool.y0 = ev._y;
;
this.mousemove = function (ev)
if (!tool.started)
return;
var x = Math.min(ev._x, tool.x0),
y = Math.min(ev._y, tool.y0),
w = Math.abs(ev._x - tool.x0),
h = Math.abs(ev._y - tool.y0);
context.clearRect(0, 0, canvas.width, canvas.height);
if (!w || !h)
return;
context.fillRect(x, y, w, h);
context.fillStyle = 'hsl(' + 360 * Math.random() + ', 50%, 50%)';
;
this.mouseup = function (ev)
if (tool.started)
tool.mousemove(ev);
tool.started = false;
drawCanvas();
;
;
// The line tool.
tools.line = function ()
var tool = this;
this.started = false;
this.mousedown = function (ev)
tool.started = true;
tool.x0 = ev._x;
tool.y0 = ev._y;
;
this.mousemove = function (ev)
if (!tool.started)
return;
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.moveTo(tool.x0, tool.y0);
context.lineTo(ev._x, ev._y);
context.stroke();
context.closePath();
;
this.mouseup = function (ev)
if (tool.started)
tool.mousemo以上是关于如何使用数组添加撤消列表?的主要内容,如果未能解决你的问题,请参考以下文章