Add miniPaint as new frontend base
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import Base_tools_class from './../core/base-tools.js';
|
||||
import Base_layers_class from './../core/base-layers.js';
|
||||
import Base_selection_class from './../core/base-selection.js';
|
||||
import GUI_tools_class from './../core/gui/gui-tools.js';
|
||||
import Helper_class from './../libs/helpers.js';
|
||||
import alertify from './../../../node_modules/alertifyjs/build/alertify.min.js';
|
||||
|
||||
var instance = null;
|
||||
|
||||
class Selection_class extends Base_tools_class {
|
||||
|
||||
constructor(ctx) {
|
||||
super();
|
||||
|
||||
//singleton
|
||||
if (instance) {
|
||||
return instance;
|
||||
}
|
||||
instance = this;
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.Base_layers = new Base_layers_class();
|
||||
this.Helper = new Helper_class();
|
||||
this.ctx = ctx;
|
||||
this.name = 'selection';
|
||||
this.type = null;
|
||||
this.tmpCanvas = null;
|
||||
this.tmpCanvasCtx = null;
|
||||
this.selection_coords_from = null;
|
||||
this.selection = {
|
||||
x: null,
|
||||
y: null,
|
||||
width: null,
|
||||
height: null,
|
||||
};
|
||||
|
||||
var sel_config = {
|
||||
enable_background: true,
|
||||
enable_borders: true,
|
||||
enable_controls: false,
|
||||
enable_rotation: false,
|
||||
enable_move: false,
|
||||
data_function: function () {
|
||||
return _this.selection;
|
||||
},
|
||||
};
|
||||
this.mousedown_selection = null;
|
||||
this.Base_selection = new Base_selection_class(ctx, sel_config, this.name);
|
||||
this.GUI_tools = new GUI_tools_class();
|
||||
}
|
||||
|
||||
load() {
|
||||
var _this = this;
|
||||
|
||||
//mouse events
|
||||
document.addEventListener('mousedown', function (event) {
|
||||
_this.dragStart(event);
|
||||
});
|
||||
document.addEventListener('mousemove', function (event) {
|
||||
_this.dragMove(event);
|
||||
});
|
||||
document.addEventListener('mouseup', function (event) {
|
||||
_this.dragEnd(event);
|
||||
});
|
||||
|
||||
// collect touch events
|
||||
document.addEventListener('touchstart', function (event) {
|
||||
_this.dragStart(event);
|
||||
});
|
||||
document.addEventListener('touchmove', function (event) {
|
||||
_this.dragMove(event);
|
||||
});
|
||||
document.addEventListener('touchend', function (event) {
|
||||
_this.dragEnd(event);
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
var code = e.keyCode;
|
||||
if (this.Helper.is_input(e.target))
|
||||
return;
|
||||
|
||||
if (code == 27) {
|
||||
//escape
|
||||
app.State.do_action(new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave()));
|
||||
}
|
||||
if (code == 46) {
|
||||
//delete
|
||||
if (config.TOOL.name == this.name) {
|
||||
this.delete_selection();
|
||||
}
|
||||
}
|
||||
if (code == 65 && (e.ctrlKey == true || e.metaKey)) {
|
||||
//A
|
||||
e.preventDefault();
|
||||
this.select_all();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
dragStart(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
return;
|
||||
_this.mousedown(event);
|
||||
}
|
||||
|
||||
dragMove(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
return;
|
||||
_this.mousemove(event);
|
||||
}
|
||||
|
||||
dragEnd(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
return;
|
||||
_this.mouseup(event);
|
||||
}
|
||||
|
||||
mousedown(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
var layer = config.layer;
|
||||
if (this.Base_selection.is_drag == false || mouse.click_valid == false)
|
||||
return;
|
||||
|
||||
if (config.layer.type != 'image') {
|
||||
alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.mousedown_selection = JSON.parse(JSON.stringify(this.selection));
|
||||
|
||||
if (this.selection.width != null && this.selection.height != null
|
||||
&& mouse.x > this.selection.x
|
||||
&& mouse.x < this.selection.x + this.selection.width
|
||||
&& mouse.y > this.selection.y
|
||||
&& mouse.y < this.selection.y + this.selection.height
|
||||
&& layer.width == layer.width_original && layer.height == layer.height_original
|
||||
) {
|
||||
//move
|
||||
this.type = 'move';
|
||||
|
||||
if (this.tmpCanvas == null) {
|
||||
this.init_tmp_canvas();
|
||||
|
||||
//register tmp canvas for faster redraw
|
||||
config.layer.link_canvas = this.tmpCanvas;
|
||||
config.need_render = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//create new selection
|
||||
this.selection = {
|
||||
x: mouse.x,
|
||||
y: mouse.y,
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
this.type = 'create';
|
||||
this.selection_coords_from = {x: mouse.x, y: mouse.y};
|
||||
}
|
||||
}
|
||||
|
||||
mousemove(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
if (this.Base_selection.is_drag == false || mouse.is_drag == false)
|
||||
return;
|
||||
if (e.type == 'mousedown' && (mouse.click_valid == false) || config.layer.type != 'image') {
|
||||
return;
|
||||
}
|
||||
if (this.selection_coords_from === null) {
|
||||
return;
|
||||
}
|
||||
if (this.type == 'create') {
|
||||
//create new selection
|
||||
this.selection.width = mouse.x - mouse.click_x;
|
||||
this.selection.height = mouse.y - mouse.click_y;
|
||||
config.need_render = true;
|
||||
}
|
||||
}
|
||||
|
||||
mouseup(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
|
||||
if (!this.Base_selection.is_drag) {
|
||||
return;
|
||||
}
|
||||
if ((e.type == 'mousedown' && mouse.click_valid == false) || config.layer.type != 'image') {
|
||||
return;
|
||||
}
|
||||
if (this.type === 'move') {
|
||||
return; // Translate appears to not work at the moment
|
||||
}
|
||||
|
||||
var width = mouse.x - this.selection.x;
|
||||
var height = mouse.y - this.selection.y;
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
//cancel selection
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave())
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.selection.width != null && this.selection.height != null) {
|
||||
//make sure coords not negative
|
||||
var details = this.selection;
|
||||
var x = details.x;
|
||||
var y = details.y;
|
||||
if (details.width < 0) {
|
||||
x = x + details.width;
|
||||
this.selection_coords_from.x = x;
|
||||
}
|
||||
if (details.height < 0) {
|
||||
y = y + details.height;
|
||||
this.selection_coords_from.y = y;
|
||||
}
|
||||
this.selection = {
|
||||
x: x,
|
||||
y: y,
|
||||
width: Math.abs(details.width),
|
||||
height: Math.abs(details.height),
|
||||
};
|
||||
app.State.do_action(
|
||||
new app.Actions.Set_selection_action(this.selection.x, this.selection.y, this.selection.width, this.selection.height, this.mousedown_selection)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
select_all() {
|
||||
if (config.layer.type != 'image') {
|
||||
alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
|
||||
return;
|
||||
}
|
||||
let actions = [];
|
||||
|
||||
if (config.TOOL.name != this.name) {
|
||||
actions.push(
|
||||
new app.Actions.Activate_tool_action(this.name)
|
||||
);
|
||||
}
|
||||
actions.push(
|
||||
new app.Actions.Set_selection_action(0, 0, config.WIDTH, config.HEIGHT, this.selection)
|
||||
);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('select_all', 'Select All', actions)
|
||||
);
|
||||
}
|
||||
|
||||
render(ctx, layer) {
|
||||
//nothing
|
||||
}
|
||||
|
||||
save_translate() {
|
||||
if (this.tmpCanvas == null)
|
||||
return;
|
||||
|
||||
delete config.layer.link_canvas;
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('selection_tool', 'Selection Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
this.reset_tmp_canvas();
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
delete_selection() {
|
||||
var selection = this.selection;
|
||||
var layer = config.layer;
|
||||
|
||||
if (config.layer.type != 'image') {
|
||||
alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (selection == null) {
|
||||
alertify.error('Nothing is selected.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.init_tmp_canvas();
|
||||
|
||||
var mouse_x = selection.x - layer.x;
|
||||
var mouse_y = selection.y - layer.y;
|
||||
|
||||
//adapt to origin size
|
||||
mouse_x = this.adaptSize(mouse_x, 'width');
|
||||
mouse_y = this.adaptSize(mouse_y, 'height');
|
||||
selection.width = this.adaptSize(selection.width, 'width');
|
||||
selection.height = this.adaptSize(selection.height, 'height');
|
||||
|
||||
//do erase
|
||||
this.tmpCanvasCtx.clearRect(mouse_x, mouse_y, selection.width, selection.height);
|
||||
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('delete_selection', 'Delete Selection', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas),
|
||||
new app.Actions.Reset_selection_action(this.selection)
|
||||
])
|
||||
);
|
||||
|
||||
this.reset_tmp_canvas();
|
||||
delete config.layer.link_canvas;
|
||||
this.reset_tmp_canvas();
|
||||
}
|
||||
|
||||
init_tmp_canvas() {
|
||||
this.tmpCanvas = document.createElement('canvas');
|
||||
this.tmpCanvasCtx = this.tmpCanvas.getContext("2d");
|
||||
this.tmpCanvas.width = config.layer.width_original;
|
||||
this.tmpCanvas.height = config.layer.height_original;
|
||||
this.tmpCanvasCtx.drawImage(config.layer.link, 0, 0);
|
||||
}
|
||||
|
||||
on_leave() {
|
||||
let actions = [
|
||||
new app.Actions.Reset_selection_action(this.selection)
|
||||
];
|
||||
delete config.layer.link_canvas;
|
||||
this.reset_tmp_canvas();
|
||||
return actions;
|
||||
}
|
||||
|
||||
clear_selection() {
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave())
|
||||
);
|
||||
}
|
||||
|
||||
reset_tmp_canvas() {
|
||||
if (this.tmpCanvas == null)
|
||||
return;
|
||||
this.tmpCanvas.width = 1;
|
||||
this.tmpCanvas.height = 1;
|
||||
this.tmpCanvas = null;
|
||||
this.tmpCanvasCtx = null;
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
export default Selection_class;
|
||||
Reference in New Issue
Block a user