Ich bin gerade dabei mich in Canvas einzuarbeiten und habe ein kleines Problem in meinem Canvas-Script beim "Undo" von Objekten (Pfeile, Kreise, Quadrate...), die ich auf ein Foto im Canvas setze. Bei dem Script handelt es sich um das bekannte "CanvasPaint.js" Script, welches ich aus dem Internet gezogen habe.
Ausgangssituation:
Wenn ich z.B. vier Pfeile auf das Foto setze, dann werden diese Pfeile nacheinander in das Array hineingeschrieben.
Bei einem "UNDO", also das "Rückgängig machen der letzten Aktionen" soll rückwärts der Reihenfolge nach wieder diese Objekte aus dem Array entfernt werden aber auch vom Canvas verschwinden.
Problem:
Das funktioniert leider nur teilweise. Das Script löscht wahllos array-nodes, also ohne die Reihenfolge zu berücksichtigen, wobei sich ein node nicht löschen lässt.
Code:
Hier das Script. Ich würde mich sehr freuen, wenn mir jemand helfen würde den Fehler zu beheben.
HTML
CanvasPaint.js
Ausgangssituation:
Wenn ich z.B. vier Pfeile auf das Foto setze, dann werden diese Pfeile nacheinander in das Array hineingeschrieben.
Bei einem "UNDO", also das "Rückgängig machen der letzten Aktionen" soll rückwärts der Reihenfolge nach wieder diese Objekte aus dem Array entfernt werden aber auch vom Canvas verschwinden.
Problem:
Das funktioniert leider nur teilweise. Das Script löscht wahllos array-nodes, also ohne die Reihenfolge zu berücksichtigen, wobei sich ein node nicht löschen lässt.
Code:
Hier das Script. Ich würde mich sehr freuen, wenn mir jemand helfen würde den Fehler zu beheben.
HTML
HTML:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Foto speichern</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<script src="libs/export_canvas/createjs-2013.09.25.min.js"></script>
<script src="libs/export_canvas/jquery-2.0.3.js"></script>
<script src="libs/export_canvas/base64.js" type="text/javascript"></script>
<script src="libs/export_canvas/canvas2image.js" type="text/javascript"></script>
<script type="text/javascript" src="libs/export_canvas/canvasPaint.js"></script>
<style type="text/css">
#container { position: relative; }
#canvas { border: 1px solid #000; }
#imageTemp { position: absolute; top: 1px; left: 1px; }
</style>
</head>
<body onload="init()" bgcolor="#3399CC">
<table border="0">
<tr>
<label>Markierungswerkzeug:
<select id="dtool">
<option value="line">Pfeil</option>
<option value="circ">Kreis</option>
<option value="rect">Viereck</option>
<option value="pencil">Stift</option>
</select></label>
</td>
</tr>
</td>
<td>
<!--<button onclick="javascript:init();return false;">Neu beginnen</button>-->
<button onclick="javascript:location.href=location.href">Neu beginnen</button>
Linienstärke : <select id="selWidth">
<option value="1">1</option>
<option value="3">3</option>
<option value="5">5</option>
<!-- <option value="7">7</option>
<option value="9" selected="selected">9</option>
<option value="11">11</option>-->
</select>
Farbe : <select id="selColor">
<option value="black">Schwarz</option>
<option value="blue" selected="selected">Blau</option>
<option value="red">Rot</option>
<option value="green">Grün</option>
<option value="yellow">Gelb</option>
<option value="gray">Grau</option>
</select>
<button onclick="javascript:cUndo();return false;">Rückgängig</button>
<button onclick="javascript:cRedo();return false;">Redo</button>
</td>
</tr>
<tr><td align="right">
<div id="container">
<canvas width="800" height="600" id="canvas"></canvas>
</div>
</td>
</tr>
</table>
CanvasPaint.js
Code:
// Keep everything in anonymous function, called on window load.
if(window.addEventListener) {
window.addEventListener('load', function () {
var canvas, context, canvaso, contexto;
// The active tool instance.
var tool;
var tool_default = 'line';
var cPushArray = new Array();
var cStep = -1;
var mousePressed=false;
function init () {
// Find the canvas element.
canvaso = document.getElementById('canvas');
if (!canvaso) {
alert('Fehler: Es konnte kein Canvas-Element gefunden werden.<br>Bitte wenden Sie sich an Ihren Anwendungsadministrator!');
return;
}
if (!canvaso.getContext) {
alert('Fehler: no canvas.getContext!');
return;
}
// Get the 2D canvas context.
contexto = canvaso.getContext('2d');
if (!contexto) {
alert('Fehler: failed to getContext!');
return;
}
// Add the temporary canvas.
var container = canvaso.parentNode;
canvas = document.createElement('canvas');
if (!canvas) {
alert('Fehler: Es konnte kein neues Canvas-Element erzeugt werden.<br>Bitte wenden Sie sich an Ihren Anwendungsadministrator!');
return;
}
canvas.id = 'imageTemp';
canvas.width = canvaso.width;
canvas.height = canvaso.height;
container.appendChild(canvas);
context = canvas.getContext('2d');
// Get the tool select input.
var tool_select = document.getElementById('dtool');
if (!tool_select) {
alert('Es ist ein Fehler bei der Wahl des dtool-Elements aufgetreten.<br>Bitte wenden Sie sich an Ihren Anwendungsadministrator!');
return;
}
tool_select.addEventListener('change', ev_tool_change, false);
// Activate the default tool.
if (tools[tool_default]) {
tool = new tools[tool_default]();
tool_select.value = tool_default;
}
// Attach the mousedown, mousemove and mouseup event listeners.
canvas.addEventListener('mousedown', ev_canvas, false);
canvas.addEventListener('mousemove', ev_canvas, false);
canvas.addEventListener('mouseup', ev_canvas, false);
}
// The general-purpose event handler. This function just determines the mouse
// position relative to the canvas element.
function ev_canvas (ev) {
if (ev.layerX || ev.layerX == 0) { // Firefox
ev._x = ev.layerX;
ev._y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
ev._x = ev.offsetX;
ev._y = ev.offsetY;
}
// Call the event handler of the tool.
var func = tool[ev.type];
if (func) {
func(ev);
}
}
// The event handler for any changes made to the tool selector.
function ev_tool_change (ev) {
if (tools[this.value]) {
tool = new tools[this.value]();
}
}
// This function draws the #imageTemp canvas on top of #imageView, after which
// #imageTemp is cleared. This function is called each time when the user
// completes a drawing operation.
function img_update () {
contexto.drawImage(canvas, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
cPush();
}
// This object holds the implementation of each drawing tool.
var tools = {};
// 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;
img_update();
};
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.strokeStyle = $('#selColor').val();
context.lineWidth = $('#selWidth').val();
// draw the ending arrowhead
var endRadians=Math.atan((ev._y-tool.y0)/(ev._x-tool.x0));
endRadians+=((ev._x>tool.x0)?90:-90)*Math.PI/180;
tool.drawArrowhead(context,ev._x,ev._y,endRadians);
context.closePath();
};
tool.drawArrowhead=function(context,_x,_y,radians){
context.save();
context.beginPath();
context.translate(_x,_y);
context.rotate(radians);
context.moveTo(0,0);
context.lineTo(5,20);
context.lineTo(-5,20);
context.closePath();
context.restore();
context.fill();
context.fillStyle = $('#selColor').val();
//context.lineWidth = $('#selWidth').val();
}
// end drawing ending arrowhead
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
}
};
};
ctx = document.getElementById('canvas').getContext("2d");
//function cPush() {
this.cPush = function (ev) {
cStep++;
if (cStep < cPushArray.length) { cPushArray.length = cStep;}
cPushArray.push(document.getElementById('canvas').toDataURL());
document.title = cStep + ":" + cPushArray.length;
}
this.cUndo = function (ev) {
if (cStep > 0) {
cStep--;
var canvasPic = new Image();
canvasPic.src = cPushArray[cStep];
canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); }
document.title = cStep + ":" + cPushArray.length;
//alert(cPushArray.length);
}
}
init();
}, false);}