discard redos and apply change; FIX crop artifact
parent
2950a5236e
commit
201baef3f3
122
Selection.js
122
Selection.js
|
@ -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
69
app.js
|
@ -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){
|
||||
|
|
11
functions.js
11
functions.js
|
@ -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(){
|
||||
|
|
Loading…
Reference in New Issue