discard redos and apply change; FIX crop artifact

main
Isaiah Odhner 2014-06-07 11:39:22 -04:00
parent 2950a5236e
commit 201baef3f3
4 changed files with 109 additions and 96 deletions

View File

@ -21,67 +21,70 @@ Selection.prototype.instantiate = function(_img){
});
sel.position();
if(!undoable()){
if(!undoable(instantiate)){
sel.destroy();
return;
}
if(_img){
sel.canvas = _img;
sel.canvas.width = sel._w;
sel.canvas.height = sel._h;
}else{
sel.canvas = document.createElement("canvas");
sel.canvas.width = sel._w;
sel.canvas.height = sel._h;
sel.ctx = sel.canvas.getContext("2d");
sel.ctx.drawImage(
canvas,
sel._x, sel._y,
sel._w, sel._h,
0, 0,
sel._w, sel._h
);
// cut the selection from the canvas
//@TODO: proper transparency for Free-Form Select
//ctx.globalCompositeOperation = "destination-out";
//ctx.drawImage()...
if(transparency){
ctx.clearRect(sel._x, sel._y, sel._w, sel._h);
function instantiate(){
if(_img){
sel.canvas = _img;
sel.canvas.width = sel._w;
sel.canvas.height = sel._h;
}else{
ctx.fillStyle = colors[1];
ctx.fillRect(sel._x, sel._y, sel._w, sel._h);
sel.canvas = document.createElement("canvas");
sel.canvas.width = sel._w;
sel.canvas.height = sel._h;
sel.ctx = sel.canvas.getContext("2d");
sel.ctx.drawImage(
canvas,
sel._x, sel._y,
sel._w, sel._h,
0, 0,
sel._w, sel._h
);
// cut the selection from the canvas
//@TODO: proper transparency for Free-Form Select
//ctx.globalCompositeOperation = "destination-out";
//ctx.drawImage()...
if(transparency){
ctx.clearRect(sel._x, sel._y, sel._w, sel._h);
}else{
ctx.fillStyle = colors[1];
ctx.fillRect(sel._x, sel._y, sel._w, sel._h);
}
}
}
sel.$ghost.append(sel.canvas);
var mox, moy;
var mousemove = function(e){
var m = e2c(e);
sel._x = Math.max(Math.min(m.x - mox, canvas.width), -sel._w);
sel._y = Math.max(Math.min(m.y - moy, canvas.height), -sel._h);
sel.position();
sel.$ghost.append(sel.canvas);
if(e.shiftKey){
sel.draw();
}
};
$(sel.canvas).on("mousedown", function(e){
e.preventDefault();
var rect = sel.canvas.getBoundingClientRect();
var cx = e.clientX - rect.left;
var cy = e.clientY - rect.top;
mox = ~~(cx / rect.width * sel.canvas.width);
moy = ~~(cy / rect.height * sel.canvas.height);
$G.on("mousemove", mousemove);
$G.one("mouseup", function(){
$G.off("mousemove", mousemove);
var mox, moy;
var mousemove = function(e){
var m = e2c(e);
sel._x = Math.max(Math.min(m.x - mox, canvas.width), -sel._w);
sel._y = Math.max(Math.min(m.y - moy, canvas.height), -sel._h);
sel.position();
if(e.shiftKey){
sel.draw();
}
};
$(sel.canvas).on("mousedown", function(e){
e.preventDefault();
var rect = sel.canvas.getBoundingClientRect();
var cx = e.clientX - rect.left;
var cy = e.clientY - rect.top;
mox = ~~(cx / rect.width * sel.canvas.width);
moy = ~~(cy / rect.height * sel.canvas.height);
$G.on("mousemove", mousemove);
$G.one("mouseup", function(){
$G.off("mousemove", mousemove);
});
});
});
$status_position.text("");
$status_size.text("");
$status_position.text("");
$status_size.text("");
$canvas_area.trigger("resize");
}
};
Selection.prototype.position = function(){
@ -106,9 +109,10 @@ Selection.prototype.destroy = function(){
};
Selection.prototype.crop = function(){
if(this.canvas && undoable()){
canvas.width = this.canvas.width;
canvas.height = this.canvas.height;
ctx.drawImage(this.canvas, 0, 0);
}
var _this = this;
this.canvas && undoable(function(){
canvas.width = _this.canvas.width;
canvas.height = _this.canvas.height;
ctx.drawImage(_this.canvas, 0, 0);
});
};

69
app.js
View File

@ -344,7 +344,7 @@ if(window.file_entry){
}
$canvas.on("user-resized", function(e, width, height){
if(undoable()){
undoable(0, function(){
canvas.width = Math.max(1, width);
canvas.height = Math.max(1, height);
if(transparency){
@ -363,7 +363,7 @@ $canvas.on("user-resized", function(e, width, height){
localStorage.width = width;
localStorage.height = height;
}catch(e){}
}
});
});
$body.on("dragover dragenter", function(e){
@ -536,7 +536,7 @@ $G.on("cut copy paste", function(e){
);
$w.$Button("Enlarge", function(){
//additional undo
if(undoable()){
undoable(function(){
var original = undos[undos.length-1];
canvas.width = Math.max(original.width, img.width);
canvas.height = Math.max(original.height, img.height);
@ -547,7 +547,7 @@ $G.on("cut copy paste", function(e){
ctx.drawImage(original, 0, 0);
paste_img();
$canvas_area.trigger("resize");
}
});
});
$w.$Button("Crop", function(){
paste_img();
@ -691,36 +691,41 @@ $canvas.on("mousedown", function(e){
ctrl = e.ctrlKey;
mouse_start = mouse_previous = mouse = e2c(e);
if(!selected_tool.passive){
if(!undoable()) return;
}
if(selected_tool.paint || selected_tool.mousedown){
tool_go("mousedown");
}
var mousedown_action = function(){
if(selected_tool.paint || selected_tool.mousedown){
tool_go("mousedown");
}
$G.on("mousemove", canvas_mouse_move);
if(selected_tool.continuous === "time"){
var iid = setInterval(function(){
tool_go();
}, 5);
}
$G.one("mouseup", function(e, canceling){
button = undefined;
if(selected_tool.mouseup && !canceling){
selected_tool.mouseup();
}
if(selected_tool.cancel && canceling){
selected_tool.cancel();
}
if(selected_tool.deselect){
selected_tool = previous_tool;
$toolbox && $toolbox.update_selected_tool();
}
$G.off("mousemove", canvas_mouse_move);
if(iid){
clearInterval(iid);
}
});
};
$G.on("mousemove", canvas_mouse_move);
if(selected_tool.continuous === "time"){
var iid = setInterval(function(){
tool_go();
}, 5);
if(selected_tool.passive){
mousedown_action();
}else{
undoable(mousedown_action);
}
$G.one("mouseup", function(e, canceling){
button = undefined;
if(selected_tool.mouseup && !canceling){
selected_tool.mouseup();
}
if(selected_tool.cancel && canceling){
selected_tool.cancel();
}
if(selected_tool.deselect){
selected_tool = previous_tool;
$toolbox && $toolbox.update_selected_tool();
}
$G.off("mousemove", canvas_mouse_move);
if(iid){
clearInterval(iid);
}
});
});
$body.on("contextmenu", function(e){

View File

@ -226,14 +226,15 @@ function render_history_as_gif(){
gif.render();
}
function undoable(){
function undoable(callback, action){
if(redos.length > 5){
var $w = new $Window();
$w.title("Paint");
$w.$content.html("Discard "+redos.length+" possible redo-able actions?<br>(Ctrl+Y or Ctrl+Shift+Z to redo)<br>");
$w.$Button("Discard", function(){
$w.$Button(action ? "Discard and Apply" : "Discard", function(){
$w.close();
redos = [];
action && action();
});
$w.$Button("Keep", function(){
$w.close();
@ -251,6 +252,8 @@ function undoable(){
undos.push(c);
action && action();
callback && callback();
return true;
}
function undo(){
@ -317,7 +320,7 @@ function select_all(){
}
function invert(){
if(undoable()){
undoable(0, function(){
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
for(var i=0; i<id.data.length; i+=4){
id.data[i+0] = 255 - id.data[i+0];
@ -325,7 +328,7 @@ function invert(){
id.data[i+2] = 255 - id.data[i+2];
}
ctx.putImageData(id, 0, 0);
}
});
}
function view_bitmap(){

View File

@ -49,7 +49,8 @@ tools = [{
selection.instantiate();
if(ctrl){
selection.crop();
deselect();
selection.destroy();
selection = null;
}
},
cancel: function(){