J'essaye d'implémenter un outil de seau de peinture avec des fonctions d'annulation et de rétablissement. Le problème est que l'annulation et le rétablissement fonctionnent correctement la première fois, mais quand je répète plusieurs fois, le code échoue. Quelqu'un peut-il m'aider à comprendre le problème? Le zoom fonctionne également, mais peindre après le zoom ne fonctionne pas correctement. Ceci est mon code complet. Vous pouvez simplement copier coller et cela fonctionnera à votre fin.Annuler/rétablir ne fonctionne pas correctement et peindre après que le zoom ne fonctionne pas correctement
<!DOCTYPE html>
<html>
<head>
<title>Painitng</title>
<style>
body {
width: 100%;
height: auto;
text-align: center;
}
.colorpick {
widh: 100%;
height: atuo;
}
.pick {
display: inline-block;
width: 30px;
height: 30px;
margin: 5px;
cursor: pointer;
}
canvas {
border: 2px solid silver;
}
</style>
</head>
<body>
<button id="zoomin">Zoom In</button>
<button id="zoomout">Zoom Out</button>
<button onclick="undo()">Undo</button>
<button onclick="redo()">Redo</button>
<div id="canvasDiv"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript">
var colorYellow = {
r: 255,
g: 207,
b: 51
};
var context;
var canvasWidth = 500;
var canvasHeight = 500;
var myColor = colorYellow;
var curColor = myColor;
var outlineImage = new Image();
var backgroundImage = new Image();
var drawingAreaX = 0;
var drawingAreaY = 0;
var drawingAreaWidth = 500;
var drawingAreaHeight = 500;
var colorLayerData;
var outlineLayerData;
var totalLoadResources = 2;
var curLoadResNum = 0;
var undoarr = new Array();
var redoarr = new Array();
var uc = 0;
var rc = 0;
// Clears the canvas.
function clearCanvas() {
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
}
function undo() {
if (undoarr.length <= 0)
return;
if (uc==0) {
redoarr.push(undoarr.pop());
uc = 1;
}
var a = undoarr.pop();
colorLayerData = a;
redoarr.push(a);
clearCanvas();
context.putImageData(a, 0, 0);
context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight);
context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight);
console.log(undoarr);
}
function redo() {
if (redoarr.length <= 0)
return;
if (rc==0) {
undoarr.push(redoarr.pop());
rc = 1;
}
var a = redoarr.pop();
colorLayerData = a;
undoarr.push(a);
clearCanvas();
context.putImageData(a, 0, 0);
context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight);
context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight);
console.log(redoarr);
}
// Draw the elements on the canvas
function redraw() {
uc = 0;
rc = 0;
var locX,
locY;
// Make sure required resources are loaded before redrawing
if (curLoadResNum < totalLoadResources) {
return; // To check if images are loaded successfully or not.
}
clearCanvas();
// Draw the current state of the color layer to the canvas
context.putImageData(colorLayerData, 0, 0);
undoarr.push(context.getImageData(0, 0, canvasWidth, canvasHeight));
console.log(undoarr);
redoarr = new Array();
// Draw the background
context.drawImage(backgroundImage, 0, 0, canvasWidth, canvasHeight);
// Draw the outline image on top of everything. We could move this to a separate
// canvas so we did not have to redraw this everyime.
context.drawImage(outlineImage, 0, 0, drawingAreaWidth, drawingAreaHeight);
}
;
function matchOutlineColor(r, g, b, a) {
return (r + g + b < 100 && a === 255);
}
;
function matchStartColor(pixelPos, startR, startG, startB) {
var r = outlineLayerData.data[pixelPos],
g = outlineLayerData.data[pixelPos + 1],
b = outlineLayerData.data[pixelPos + 2],
a = outlineLayerData.data[pixelPos + 3];
// If current pixel of the outline image is black
if (matchOutlineColor(r, g, b, a)) {
return false;
}
r = colorLayerData.data[pixelPos];
g = colorLayerData.data[pixelPos + 1];
b = colorLayerData.data[pixelPos + 2];
// If the current pixel matches the clicked color
if (r === startR && g === startG && b === startB) {
return true;
}
// If current pixel matches the new color
if (r === curColor.r && g === curColor.g && b === curColor.b) {
return false;
}
return true;
}
;
function colorPixel(pixelPos, r, g, b, a) {
colorLayerData.data[pixelPos] = r;
colorLayerData.data[pixelPos + 1] = g;
colorLayerData.data[pixelPos + 2] = b;
colorLayerData.data[pixelPos + 3] = a !== undefined ? a : 255;
}
;
function floodFill(startX, startY, startR, startG, startB) {
var newPos,
x,
y,
pixelPos,
reachLeft,
reachRight,
drawingBoundLeft = drawingAreaX,
drawingBoundTop = drawingAreaY,
drawingBoundRight = drawingAreaX + drawingAreaWidth - 1,
drawingBoundBottom = drawingAreaY + drawingAreaHeight - 1,
pixelStack = [[startX, startY]];
while (pixelStack.length) {
newPos = pixelStack.pop();
x = newPos[0];
y = newPos[1];
// Get current pixel position
pixelPos = (y * canvasWidth + x) * 4;
// Go up as long as the color matches and are inside the canvas
while (y >= drawingBoundTop && matchStartColor(pixelPos, startR, startG, startB)) {
y -= 1;
pixelPos -= canvasWidth * 4;
}
pixelPos += canvasWidth * 4;
y += 1;
reachLeft = false;
reachRight = false;
// Go down as long as the color matches and in inside the canvas
while (y <= drawingBoundBottom && matchStartColor(pixelPos, startR, startG, startB)) {
y += 1;
colorPixel(pixelPos, curColor.r, curColor.g, curColor.b);
if (x > drawingBoundLeft) {
if (matchStartColor(pixelPos - 4, startR, startG, startB)) {
if (!reachLeft) {
// Add pixel to stack
pixelStack.push([x - 1, y]);
reachLeft = true;
}
} else if (reachLeft) {
reachLeft = false;
}
}
if (x < drawingBoundRight) {
if (matchStartColor(pixelPos + 4, startR, startG, startB)) {
if (!reachRight) {
// Add pixel to stack
pixelStack.push([x + 1, y]);
reachRight = true;
}
} else if (reachRight) {
reachRight = false;
}
}
pixelPos += canvasWidth * 4;
}
}
}
;
// Start painting with paint bucket tool starting from pixel specified by startX and startY
function paintAt(startX, startY) {
var pixelPos = (startY * canvasWidth + startX) * 4,
r = colorLayerData.data[pixelPos],
g = colorLayerData.data[pixelPos + 1],
b = colorLayerData.data[pixelPos + 2],
a = colorLayerData.data[pixelPos + 3];
if (r === curColor.r && g === curColor.g && b === curColor.b) {
// Return because trying to fill with the same color
return;
}
if (matchOutlineColor(r, g, b, a)) {
// Return because clicked outline
return;
}
floodFill(startX, startY, r, g, b);
redraw();
}
;
// Add mouse event listeners to the canvas
function createMouseEvents() {
$('#canvas').mousedown(function (e) {
// Mouse down location
var mouseX = e.pageX - this.offsetLeft,
mouseY = e.pageY - this.offsetTop;
if ((mouseY > drawingAreaY && mouseY < drawingAreaY + drawingAreaHeight) && (mouseX <= drawingAreaX + drawingAreaWidth)) {
paintAt(mouseX, mouseY);
}
});
}
;
resourceLoaded = function() {
curLoadResNum += 1;
//if (curLoadResNum === totalLoadResources) {
createMouseEvents();
redraw();
//}
};
function start() {
var canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
document.getElementById('canvasDiv').appendChild(canvas);
if (typeof G_vmlCanvasManager !== "undefined") {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
backgroundImage.onload = resourceLoaded();
backgroundImage.src = "images/t1.png";
outlineImage.onload = function() {
context.drawImage(outlineImage, drawingAreaX, drawingAreaY, drawingAreaWidth, drawingAreaHeight);
try {
outlineLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
} catch (ex) {
window.alert("Application cannot be run locally. Please run on a server.");
return;
}
clearCanvas();
colorLayerData = context.getImageData(0, 0, canvasWidth, canvasHeight);
resourceLoaded();
};
outlineImage.src = "images/d.png";
}
;
getColor = function() {
};
</script>
<script type="text/javascript"> $(document).ready(function() {
start();
});</script>
<script language="javascript">
$('#zoomin').click(function() {
if ($("#canvas").width()==500){
$("#canvas").width(750);
$("#canvas").height(750);
var ctx = canvas.getContext("2d");
ctx.drawImage(backgroundImage, 0, 0, 749, 749);
ctx.drawImage(outlineImage, 0, 0, 749, 749);
redraw();
} else if ($("#canvas").width()==750){
$("#canvas").width(1000);
$("#canvas").height(1000);
var ctx = canvas.getContext("2d");
ctx.drawImage(backgroundImage, 0, 0, 999, 999);
ctx.drawImage(outlineImage, 0, 0, 999, 999);
redraw();
}
});
$('#zoomout').click(function() {
if ($("#canvas").width() == 1000) {
$("#canvas").width(750);
$("#canvas").height(750);
var ctx = canvas.getContext("2d");
ctx.drawImage(backgroundImage, 0, 0, 749, 749);
ctx.drawImage(outlineImage, 0, 0, 749, 749);
redraw();
} else if ($("#canvas").width() == 750) {
$("#canvas").width(500);
$("#canvas").height(500);
var ctx = canvas.getContext("2d");
ctx.drawImage(backgroundImage, 0, 0, 499, 499);
ctx.drawImage(outlineImage, 0, 0, 499, 499);
redraw();
}
});
</script>
<div class="colorpick">
<div class="pick" style="background-color:rgb(150, 0, 0);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(0, 0, 152);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(0, 151, 0);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(255, 0, 5);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(255, 255, 0);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(0, 255, 255);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(255, 0, 255);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(255, 150, 0);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(255, 0, 150);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(0, 255, 150);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(150, 0, 255);" onclick="hello(this.style.backgroundColor);"></div>
<div class="pick" style="background-color:rgb(0, 150, 255);" onclick="hello(this.style.backgroundColor);"></div>
</div>
<script>
function hello(e) {
var rgb = e.replace(/^(rgb|rgba)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(',');
myColor.r = parseInt(rgb[0]);
myColor.g = parseInt(rgb[1]);
myColor.b = parseInt(rgb[2]);
curColor = myColor;
console.log(curColor);
}
</script>
</body>
</html>
Eh bien, laissez-moi jouer un peu. Je vous le ferai savoir. –
Cela a résolu les deux problèmes. Merci beaucoup. Tu es un sauveur. Merci beaucoup. –
Une dernière chose. En zoom, le zoom fonctionne sur chrome mais pas sur firefox. quel pourrait être le problème? –