mirror of
https://github.com/viliusle/miniPaint.git
synced 2026-02-06 11:21:47 +00:00
Get most filters working with history and some tools
This commit is contained in:
parent
2a67ea7782
commit
209524648c
@ -72,13 +72,11 @@ function save_image(){
|
||||
//update image using blob (faster)
|
||||
tempCanvas.toBlob(function (blob) {
|
||||
alert('Data length: ' + blob.size);
|
||||
console.log(blob);
|
||||
}, 'image/png');
|
||||
}
|
||||
else{
|
||||
//slow way for IE, Edge
|
||||
var data = tempCanvas.toDataURL();
|
||||
console.log(data);
|
||||
alert('Data length: ' + data.length);
|
||||
}
|
||||
}
|
||||
|
||||
55
src/js/actions/add-layer-filter.js
Normal file
55
src/js/actions/add-layer-filter.js
Normal file
@ -0,0 +1,55 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Add_layer_filter_action extends Base_action {
|
||||
/**
|
||||
* register new live filter
|
||||
*
|
||||
* @param {int} layer_id
|
||||
* @param {string} name
|
||||
* @param {object} params
|
||||
*/
|
||||
constructor(layer_id, name, params) {
|
||||
super('add_layer_filter', 'Add Layer Filter');
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.filter_id = Math.floor(Math.random() * 999999999) + 1; // A good UUID library would
|
||||
this.name = name;
|
||||
this.params = params;
|
||||
this.reference_layer = null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
var filter = {
|
||||
id: this.filter_id,
|
||||
name: this.name,
|
||||
params: this.params,
|
||||
};
|
||||
this.reference_layer.filters.push(filter);
|
||||
|
||||
config.need_render = true;
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.reference_layer) {
|
||||
this.reference_layer.filters.pop();
|
||||
this.reference_layer = null;
|
||||
}
|
||||
config.need_render = true;
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
free() {
|
||||
this.reference_layer = null;
|
||||
this.params = null;
|
||||
}
|
||||
}
|
||||
@ -4,12 +4,14 @@ export class Base_action {
|
||||
this.action_id = action_id;
|
||||
this.action_description = action_description;
|
||||
this.is_done = false;
|
||||
this.memory_estimate = 0; // Estimate of how much memory will be freed when the free() method is called (in bytes)
|
||||
}
|
||||
do() {
|
||||
this.is_done = true;
|
||||
}
|
||||
undo() {
|
||||
this.is_done = false;
|
||||
this.memory_estimate = 0;
|
||||
}
|
||||
free() {
|
||||
// Override if need to run tasks to free memory when action is discarded from history
|
||||
|
||||
@ -41,6 +41,11 @@ export class Bundle_action extends Base_action {
|
||||
}
|
||||
|
||||
free() {
|
||||
this.actions_to_do = null;
|
||||
if (this.actions_to_do) {
|
||||
for (let action of this.actions_to_do) {
|
||||
action.free();
|
||||
}
|
||||
this.actions_to_do = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/js/actions/clear-layer.js
Normal file
82
src/js/actions/clear-layer.js
Normal file
@ -0,0 +1,82 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Clear_layer_action extends Base_action {
|
||||
/**
|
||||
* clear layer data
|
||||
*
|
||||
* @param {int} layer_id
|
||||
*/
|
||||
constructor(layer_id) {
|
||||
super('clear_layer', 'Clear Layer');
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.update_layer_action = null;
|
||||
this.delete_layer_settings_action = null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
let layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
let new_settings = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
visible: true,
|
||||
opacity: 100,
|
||||
composition: null,
|
||||
rotate: 0,
|
||||
data: null,
|
||||
params: {},
|
||||
status: null,
|
||||
render_function: null,
|
||||
type: null
|
||||
};
|
||||
if (layer.type == 'image') {
|
||||
//clean image
|
||||
new_settings.link = null;
|
||||
}
|
||||
this.update_layer_action = new app.Actions.Update_layer_action(this.layer_id, new_settings);
|
||||
await this.update_layer_action.do();
|
||||
let delete_setting_names = [];
|
||||
for (let prop_name in layer) {
|
||||
//remove private attributes
|
||||
if (prop_name[0] == '_') {
|
||||
delete_setting_names.push(prop_name);
|
||||
}
|
||||
}
|
||||
if (delete_setting_names.length > 0) {
|
||||
this.delete_layer_settings_action = new app.Actions.Delete_layer_settings_action(this.layer_id, delete_setting_names);
|
||||
await this.delete_layer_settings_action.do();
|
||||
}
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.delete_layer_settings_action) {
|
||||
await this.delete_layer_settings_action.undo();
|
||||
this.delete_layer_settings_action.free();
|
||||
this.delete_layer_settings_action = null;
|
||||
}
|
||||
if (this.update_layer_action) {
|
||||
await this.update_layer_action.undo();
|
||||
this.update_layer_action.free();
|
||||
this.update_layer_action = null;
|
||||
}
|
||||
}
|
||||
|
||||
free() {
|
||||
if (this.update_layer_action) {
|
||||
this.update_layer_action.free();
|
||||
this.update_layer_action = null;
|
||||
}
|
||||
if (this.delete_layer_settings_action) {
|
||||
this.delete_layer_settings_action.free();
|
||||
this.delete_layer_settings_action = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
src/js/actions/delete-layer-filter.js
Normal file
60
src/js/actions/delete-layer-filter.js
Normal file
@ -0,0 +1,60 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Delete_layer_filter_action extends Base_action {
|
||||
/**
|
||||
* delete live filter
|
||||
*
|
||||
* @param {int} layer_id
|
||||
* @param {string} filter_id
|
||||
*/
|
||||
constructor(layer_id, filter_id) {
|
||||
super('delete_layer_filter', 'Delete Layer Filter');
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.filter_id = filter_id;
|
||||
this.reference_layer = null;
|
||||
this.filter_remove_index = null;
|
||||
this.old_filter = null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
this.old_filter = null;
|
||||
for (let i in this.reference_layer.filters) {
|
||||
if (this.reference_layer.filters[i].id == this.filter_id) {
|
||||
this.filter_remove_index = i;
|
||||
this.old_filter = this.reference_layer.filters.splice(i, 1)[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!this.old_filter) {
|
||||
throw new Error('Aborted - filter with specified id doesn\'t exist in layer');
|
||||
}
|
||||
config.need_render = true;
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.reference_layer && this.old_filter) {
|
||||
this.reference_layer.filters.splice(this.filter_remove_index, 0, this.old_filter);
|
||||
}
|
||||
this.reference_layer = null;
|
||||
this.old_filter = null;
|
||||
this.filter_remove_index = null;
|
||||
config.need_render = true;
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
free() {
|
||||
this.reference_layer = null;
|
||||
this.old_filter = null;
|
||||
}
|
||||
}
|
||||
50
src/js/actions/delete-layer-settings.js
Normal file
50
src/js/actions/delete-layer-settings.js
Normal file
@ -0,0 +1,50 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Delete_layer_settings_action extends Base_action {
|
||||
/**
|
||||
* Deletes the specified settings in a layer
|
||||
*
|
||||
* @param {int} layer_id
|
||||
* @param {array} setting_names
|
||||
*/
|
||||
constructor(layer_id, setting_names) {
|
||||
super('delete_layer_settings', 'Delete Layer Settings');
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.setting_names = setting_names;
|
||||
this.reference_layer = null;
|
||||
this.old_settings = {};
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
for (let name in this.setting_names) {
|
||||
this.old_settings[name] = this.reference_layer[name];
|
||||
delete this.reference_layer[name];
|
||||
}
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.reference_layer) {
|
||||
for (let i in this.old_settings) {
|
||||
this.reference_layer[i] = this.old_settings[i];
|
||||
}
|
||||
this.old_settings = {};
|
||||
}
|
||||
this.reference_layer = null;
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
free() {
|
||||
this.setting_names = null;
|
||||
this.reference_layer = null;
|
||||
this.old_settings = null;
|
||||
}
|
||||
}
|
||||
@ -76,10 +76,12 @@ export class Delete_layer_action extends Base_action {
|
||||
}
|
||||
if (this.select_layer_action) {
|
||||
await this.select_layer_action.undo();
|
||||
this.select_layer_action.free();
|
||||
this.select_layer_action = null;
|
||||
}
|
||||
if (this.insert_layer_action) {
|
||||
await this.insert_layer_action.undo();
|
||||
this.insert_layer_action.free();
|
||||
this.insert_layer_action = null;
|
||||
}
|
||||
|
||||
@ -91,8 +93,14 @@ export class Delete_layer_action extends Base_action {
|
||||
if (this.deleted_layer) {
|
||||
delete this.deleted_layer.link;
|
||||
}
|
||||
this.insert_layer_action = null;
|
||||
this.select_layer_action = null;
|
||||
if (this.insert_layer_action) {
|
||||
this.insert_layer_action.free();
|
||||
this.insert_layer_action = null;
|
||||
}
|
||||
if (this.select_layer_action) {
|
||||
this.select_layer_action.free();
|
||||
this.select_layer_action = null;
|
||||
}
|
||||
this.deleted_layer = null;
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,21 @@
|
||||
export { Add_layer_filter_action } from './add-layer-filter.js';
|
||||
export { Autoresize_canvas_action } from './autoresize-canvas.js';
|
||||
export { Bundle_action } from './bundle.js';
|
||||
export { Clear_layer_action } from './clear-layer.js';
|
||||
export { Delete_layer_action } from './delete-layer.js';
|
||||
export { Delete_layer_filter_action } from './delete-layer-filter.js';
|
||||
export { Delete_layer_settings_action } from './delete-layer-settings.js';
|
||||
export { Init_canvas_zoom_action } from './init-canvas-zoom.js';
|
||||
export { Insert_layer_action } from './insert-layer.js';
|
||||
export { Prepare_canvas_action } from './prepare-canvas.js';
|
||||
export { Reorder_layer_action } from './reorder-layer.js';
|
||||
export { Reset_layers_action } from './reset-layers.js';
|
||||
export { Reset_selection_action } from './reset-selection.js';
|
||||
export { Select_layer_action } from './select-layer.js';
|
||||
export { Select_next_layer_action } from './select-next-layer.js';
|
||||
export { Select_previous_layer_action } from './select-previous-layer.js';
|
||||
export { Set_selection_action } from './set-selection.js';
|
||||
export { Toggle_layer_visibility_action } from './toggle-layer-visibility.js';
|
||||
export { Update_config_action } from './update-config.js';
|
||||
export { Update_layer_image_action } from './update-layer-image.js';
|
||||
export { Update_layer_action } from './update-layer.js';
|
||||
@ -1,6 +1,7 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
import alertify from './../../../node_modules/alertifyjs/build/alertify.min.js';
|
||||
|
||||
export class Insert_layer_action extends Base_action {
|
||||
/**
|
||||
@ -23,6 +24,7 @@ export class Insert_layer_action extends Base_action {
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
|
||||
this.previous_auto_increment = app.Layers.auto_increment;
|
||||
this.previous_selected_layer = config.layer;
|
||||
let autoresize_as = null;
|
||||
@ -78,7 +80,7 @@ export class Insert_layer_action extends Base_action {
|
||||
// Remove first empty layer
|
||||
|
||||
this.delete_layer_action = new app.Actions.Delete_layer_action(config.layer.id, true);
|
||||
this.delete_layer_action.do();
|
||||
await this.delete_layer_action.do();
|
||||
}
|
||||
|
||||
if (layer.link == null) {
|
||||
@ -179,15 +181,17 @@ export class Insert_layer_action extends Base_action {
|
||||
this.autoresize_canvas_action = null;
|
||||
}
|
||||
if (this.inserted_layer_id) {
|
||||
await new app.Actions.Delete_layer_action(this.inserted_layer_id, true).do();
|
||||
config.layers.pop();
|
||||
this.inserted_layer_id = null;
|
||||
}
|
||||
if (this.update_layer_action) {
|
||||
await this.update_layer_action.undo();
|
||||
this.update_layer_action.free();
|
||||
this.update_layer_action = null;
|
||||
}
|
||||
if (this.delete_layer_action) {
|
||||
await this.delete_layer_action.undo();
|
||||
this.delete_layer_action.free();
|
||||
this.delete_layer_action = null;
|
||||
}
|
||||
config.layer = this.previous_selected_layer;
|
||||
@ -198,8 +202,14 @@ export class Insert_layer_action extends Base_action {
|
||||
}
|
||||
|
||||
free() {
|
||||
this.delete_layer_action = null;
|
||||
this.update_layer_action = null;
|
||||
if (this.delete_layer_action) {
|
||||
this.delete_layer_action.free();
|
||||
this.delete_layer_action = null;
|
||||
}
|
||||
if (this.update_layer_action) {
|
||||
this.update_layer_action.free();
|
||||
this.update_layer_action = null;
|
||||
}
|
||||
this.previous_selected_layer = null;
|
||||
}
|
||||
}
|
||||
64
src/js/actions/reorder-layer.js
Normal file
64
src/js/actions/reorder-layer.js
Normal file
@ -0,0 +1,64 @@
|
||||
import app from '../app.js';
|
||||
import config from '../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Reorder_layer_action extends Base_action {
|
||||
/**
|
||||
* Reorder layer up or down in the layer stack
|
||||
*
|
||||
* @param {int} layer_id
|
||||
* @param {int} direction
|
||||
*/
|
||||
constructor(layer_id, direction) {
|
||||
super('reorder_layer', 'Reorder Layer');
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.direction = direction;
|
||||
this.reference_layer = null;
|
||||
this.reference_target = null;
|
||||
this.old_layer_order = null;
|
||||
this.old_target_order = null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
if (this.direction < 0) {
|
||||
this.reference_target = app.Layers.find_previous(this.layer_id);
|
||||
}
|
||||
else {
|
||||
this.reference_target = app.Layers.find_next(this.layer_id);
|
||||
}
|
||||
if (!this.reference_target) {
|
||||
throw new Error('Aborted - layer has nowhere to move');
|
||||
}
|
||||
this.old_layer_order = this.reference_layer.order;
|
||||
this.old_target_order = this.reference_target.order;
|
||||
this.reference_layer.order = this.old_target_order;
|
||||
this.reference_target.order = this.old_layer_order;
|
||||
|
||||
app.Layers.render();
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.reference_layer) {
|
||||
this.reference_layer.order = this.old_layer_order;
|
||||
this.reference_layer = null;
|
||||
}
|
||||
if (this.reference_target) {
|
||||
this.reference_target.order = this.old_target_order;
|
||||
this.reference_target = null;
|
||||
}
|
||||
app.Layers.render();
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
free() {
|
||||
this.reference_layer = null;
|
||||
this.reference_target = null;
|
||||
}
|
||||
}
|
||||
@ -39,15 +39,28 @@ export class Reset_layers_action extends Base_action {
|
||||
super.undo();
|
||||
if (this.insert_action) {
|
||||
await this.insert_action.undo();
|
||||
this.insert_action.free();
|
||||
this.insert_action = null;
|
||||
}
|
||||
for (let i = this.delete_actions.length - 1; i >= 0; i--) {
|
||||
await this.delete_actions[i].undo();
|
||||
this.delete_actions[i].free();
|
||||
}
|
||||
app.Layers.auto_increment = this.previous_auto_increment;
|
||||
|
||||
app.Layers.render();
|
||||
app.GUI.GUI_layers.render_layers();
|
||||
}
|
||||
|
||||
free() {
|
||||
if (this.insert_action) {
|
||||
this.insert_action.free();
|
||||
this.insert_action = null;
|
||||
}
|
||||
if (this.delete_actions) {
|
||||
for (let action of this.delete_actions) {
|
||||
action.free();
|
||||
}
|
||||
this.delete_actions = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,19 +15,23 @@ export class Reset_selection_action extends Base_action {
|
||||
async do() {
|
||||
super.do();
|
||||
this.settings_reference = app.Layers.Base_selection.find_settings();
|
||||
this.old_settings_data = this.settings_reference.data;
|
||||
this.settings_reference.data = {
|
||||
x: null,
|
||||
y: null,
|
||||
width: null,
|
||||
height: null
|
||||
};
|
||||
this.old_settings_data = JSON.parse(JSON.stringify(this.settings_reference.data));
|
||||
this.settings_reference.data = {
|
||||
x: null,
|
||||
y: null,
|
||||
width: null,
|
||||
height: null
|
||||
}
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
this.settings_reference.data = this.old_settings_data;
|
||||
if (this.old_settings_data) {
|
||||
for (let prop in this.old_settings_data) {
|
||||
this.settings_reference.data[prop] = this.old_settings_data[prop];
|
||||
}
|
||||
}
|
||||
this.settings_reference = null;
|
||||
this.old_settings_data = null;
|
||||
config.need_render = true;
|
||||
|
||||
@ -41,6 +41,7 @@ export class Select_layer_action extends Base_action {
|
||||
|
||||
if (this.reset_selection_action) {
|
||||
await this.reset_selection_action.undo();
|
||||
this.reset_selection_action.free();
|
||||
this.reset_selection_action = null;
|
||||
}
|
||||
|
||||
@ -53,5 +54,9 @@ export class Select_layer_action extends Base_action {
|
||||
|
||||
free() {
|
||||
this.old_layer = null;
|
||||
if (this.reset_selection_action) {
|
||||
this.reset_selection_action.free();
|
||||
this.reset_selection_action = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/js/actions/set-selection.js
Normal file
57
src/js/actions/set-selection.js
Normal file
@ -0,0 +1,57 @@
|
||||
import app from '../app.js';
|
||||
import config from '../config.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
export class Set_selection_action extends Base_action {
|
||||
/**
|
||||
* Sets the selection to the specified position and dimensions
|
||||
*/
|
||||
constructor(x, y, width, height, old_settings_override) {
|
||||
super('set_selection', 'Set Selection');
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.settings_reference = null;
|
||||
this.old_settings_data = null;
|
||||
this.old_settings_override = old_settings_override || null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.settings_reference = app.Layers.Base_selection.find_settings();
|
||||
this.old_settings_data = JSON.parse(JSON.stringify(this.settings_reference.data));
|
||||
if (this.x != null)
|
||||
this.settings_reference.data.x = this.x;
|
||||
if (this.y != null)
|
||||
this.settings_reference.data.y = this.y;
|
||||
if (this.width != null)
|
||||
this.settings_reference.data.width = this.width;
|
||||
if (this.height != null)
|
||||
this.settings_reference.data.height = this.height;
|
||||
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.old_settings_override) {
|
||||
for (let prop in this.old_settings_override) {
|
||||
this.settings_reference.data[prop] = this.old_settings_override[prop];
|
||||
}
|
||||
} else {
|
||||
for (let prop in this.old_settings_data) {
|
||||
this.settings_reference.data[prop] = this.old_settings_data[prop];
|
||||
}
|
||||
}
|
||||
this.settings_reference = null;
|
||||
this.old_settings_data = null;
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
free() {
|
||||
this.settings_reference = null;
|
||||
this.old_settings_override = null;
|
||||
this.old_settings_data = null;
|
||||
}
|
||||
}
|
||||
143
src/js/actions/store/image-store.js
Normal file
143
src/js/actions/store/image-store.js
Normal file
@ -0,0 +1,143 @@
|
||||
import { get } from "jquery";
|
||||
|
||||
let idCounter = 0;
|
||||
let database = null;
|
||||
let databaseInitPromise = null;
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Initializes the database
|
||||
*/
|
||||
async init() {
|
||||
if (!databaseInitPromise) {
|
||||
databaseInitPromise = new Promise(async (resolveInit) => {
|
||||
try {
|
||||
if (window.indexedDB) {
|
||||
// Delete database from a previous page load
|
||||
await new Promise((resolve, reject) => {
|
||||
let deleteRequest = window.indexedDB.deleteDatabase('undoHistoryImageStore');
|
||||
deleteRequest.onerror = () => {
|
||||
reject(deleteRequest.error);
|
||||
};
|
||||
deleteRequest.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
// Initialize database
|
||||
await new Promise((resolve, reject) => {
|
||||
let openRequest = window.indexedDB.open('undoHistoryImageStore', 1);
|
||||
openRequest.onupgradeneeded = function(event) {
|
||||
database = openRequest.result;
|
||||
switch (event.oldVersion) {
|
||||
case 0:
|
||||
database.createObjectStore('images', { keyPath: 'id' });
|
||||
break;
|
||||
}
|
||||
};
|
||||
openRequest.onerror = () => {
|
||||
reject(openRequest.error);
|
||||
}
|
||||
openRequest.onsuccess = () => {
|
||||
resolve();
|
||||
database = openRequest.result;
|
||||
}
|
||||
});
|
||||
if (!database) {
|
||||
throw new Error('indexedDB not initialized');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
database = {
|
||||
isMemory: true,
|
||||
images: {}
|
||||
};
|
||||
}
|
||||
resolveInit();
|
||||
});
|
||||
await databaseInitPromise;
|
||||
} else if (!database) {
|
||||
await databaseInitPromise;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the specified image to the database. Returns a promise that is resolved with an id that can be used to retrieve it again.
|
||||
*
|
||||
* @param {string | canvas | ImageData} imageData the image data to store
|
||||
* @returns {Promise<string>} resolves with retrieval id
|
||||
*/
|
||||
async add(imageData) {
|
||||
await this.init();
|
||||
let imageId = (idCounter++) + '';
|
||||
if (database.isMemory) {
|
||||
database.images[imageId] = imageData;
|
||||
} else {
|
||||
await new Promise((resolve, reject) => {
|
||||
const transaction = database.transaction('images', 'readwrite');
|
||||
const images = transaction.objectStore('images');
|
||||
const image = {
|
||||
id: imageId,
|
||||
data: imageData
|
||||
}
|
||||
const request = images.add(image);
|
||||
request.onsuccess = function() {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = function() {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
return imageId;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the specified image from the database, by imageId retrieved from "add()" method.
|
||||
*
|
||||
* @param {string} imageId the id of the image to get
|
||||
* @returns {Promise<string | canvas | ImageData>} resolves with the image
|
||||
*/
|
||||
async get(imageId) {
|
||||
await this.init();
|
||||
if (database.isMemory) {
|
||||
return database.images[imageId];
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = database.transaction('images', 'readonly');
|
||||
const images = transaction.objectStore('images');
|
||||
const request = images.get(imageId);
|
||||
request.onsuccess = function() {
|
||||
resolve(request.result.data);
|
||||
};
|
||||
request.onerror = function() {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the specified image from the database, by imageId retrieved from "add()" method.
|
||||
*
|
||||
* @param {string} imageId the id of the image to delete
|
||||
* @returns {Promise<string | canvas | ImageData>} resolves with the image
|
||||
*/
|
||||
async delete(imageId) {
|
||||
await this.init();
|
||||
if (database.isMemory) {
|
||||
delete database.images[imageId];
|
||||
} else {
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = database.transaction('images', 'readwrite');
|
||||
const images = transaction.objectStore('images');
|
||||
const request = images.delete(imageId);
|
||||
request.onsuccess = function() {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = function() {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
98
src/js/actions/update-layer-image.js
Normal file
98
src/js/actions/update-layer-image.js
Normal file
@ -0,0 +1,98 @@
|
||||
import app from './../app.js';
|
||||
import config from './../config.js';
|
||||
import Helper_class from './../libs/helpers.js';
|
||||
import alertify from './../../../node_modules/alertifyjs/build/alertify.min.js';
|
||||
import image_store from './store/image-store.js';
|
||||
import { Base_action } from './base.js';
|
||||
|
||||
const Helper = new Helper_class();
|
||||
|
||||
export class Update_layer_image_action extends Base_action {
|
||||
/**
|
||||
* updates layer image data
|
||||
*
|
||||
* @param {canvas} canvas
|
||||
* @param {int} layer_id (optional)
|
||||
*/
|
||||
constructor(canvas, layer_id) {
|
||||
super('update_layer_image', 'Update Layer Image');
|
||||
this.canvas = canvas;
|
||||
this.canvas_data_url = null;
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
this.layer_id = parseInt(layer_id);
|
||||
this.reference_layer = null;
|
||||
this.old_image_id = null;
|
||||
}
|
||||
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
if (this.reference_layer.type != 'image'){
|
||||
alertify.error('Error: layer must be image.');
|
||||
throw new Error('Aborted - layer is not an image');
|
||||
}
|
||||
|
||||
if (!this.canvas_data_url) {
|
||||
if (Helper.is_edge_or_ie() == false) {
|
||||
// Update image using blob (faster)
|
||||
await new Promise((resolve) => {
|
||||
this.canvas.toBlob((blob) => {
|
||||
this.canvas_data_url = window.URL.createObjectURL(blob);
|
||||
resolve();
|
||||
}, 'image/png');
|
||||
});
|
||||
}
|
||||
else {
|
||||
// Slow way for IE, Edge
|
||||
this.canvas_data_url = this.canvas.toDataURL();
|
||||
}
|
||||
this.canvas = null;
|
||||
}
|
||||
|
||||
try {
|
||||
this.old_image_id = await image_store.add(this.reference_layer.link.src);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// TODO - need to delete undo history, how to handle this?
|
||||
}
|
||||
this.reference_layer.link.src = this.canvas_data_url;
|
||||
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async undo() {
|
||||
super.undo();
|
||||
if (this.old_image_id != null) {
|
||||
try {
|
||||
this.reference_layer.link.src = await image_store.get(this.old_image_id);
|
||||
} catch (error) {
|
||||
throw new Error('Failed to retrieve image from store');
|
||||
}
|
||||
try {
|
||||
await image_store.delete(this.old_image_id);
|
||||
} catch (error) {
|
||||
// TODO - Reduce assumed total memory storage by image size
|
||||
}
|
||||
this.old_image_id = null;
|
||||
}
|
||||
this.reference_layer = null;
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async free() {
|
||||
if (this.old_image_id != null) {
|
||||
try {
|
||||
await image_store.delete(this.old_image_id);
|
||||
} catch (error) {
|
||||
// TODO - Reduce assumed total memory storage by image size
|
||||
}
|
||||
this.old_image_id = null;
|
||||
}
|
||||
this.reference_layer = null;
|
||||
this.canvas_data_url = null;
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ import { Base_action } from './base.js';
|
||||
export class Update_layer_action extends Base_action {
|
||||
/**
|
||||
* Updates an existing layer with the provided settings
|
||||
* WARNING: If passing objects or arrays into settings, make sure these are new objects, and not a modified existing object!
|
||||
*
|
||||
* @param {string} layer_id
|
||||
* @param {object} settings
|
||||
@ -20,11 +21,9 @@ export class Update_layer_action extends Base_action {
|
||||
async do() {
|
||||
super.do();
|
||||
this.reference_layer = app.Layers.get_layer(this.layer_id);
|
||||
|
||||
if (!this.reference_layer) {
|
||||
throw new Error('Aborted - layer with specified id doesn\'t exist');
|
||||
}
|
||||
|
||||
for (let i in this.settings) {
|
||||
if (i == 'id')
|
||||
continue;
|
||||
@ -33,6 +32,10 @@ export class Update_layer_action extends Base_action {
|
||||
this.old_settings[i] = this.reference_layer[i];
|
||||
this.reference_layer[i] = this.settings[i];
|
||||
}
|
||||
if (this.settings.data && this.reference_layer.type === 'text') {
|
||||
this.reference_layer._needs_update_data = true;
|
||||
}
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
async undo() {
|
||||
@ -41,9 +44,13 @@ export class Update_layer_action extends Base_action {
|
||||
for (let i in this.old_settings) {
|
||||
this.reference_layer[i] = this.old_settings[i];
|
||||
}
|
||||
if (this.old_settings.data && this.reference_layer[i] === 'text') {
|
||||
this.reference_layer._needs_update_data = true;
|
||||
}
|
||||
this.old_settings = {};
|
||||
}
|
||||
this.reference_layer = null;
|
||||
config.need_render = true;
|
||||
}
|
||||
|
||||
free() {
|
||||
|
||||
@ -411,16 +411,15 @@ class Base_layers_class {
|
||||
* @param {int} id
|
||||
* @param {int} value 0-100
|
||||
*/
|
||||
set_opacity(id, value) {
|
||||
id = parseInt(id);
|
||||
async set_opacity(id, value) {
|
||||
value = parseInt(value);
|
||||
if (value < 0 || value > 100) {
|
||||
//reset
|
||||
value = 100;
|
||||
}
|
||||
var link = this.get_layer(id);
|
||||
|
||||
link.opacity = value;
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_action(id, { opacity: value })
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -428,36 +427,10 @@ class Base_layers_class {
|
||||
*
|
||||
* @param {int} id
|
||||
*/
|
||||
layer_clear(id) {
|
||||
id = parseInt(id);
|
||||
var link = this.get_layer(id);
|
||||
|
||||
if (link.type == 'image') {
|
||||
//clean image
|
||||
link.link = null;
|
||||
}
|
||||
|
||||
for (var i in link) {
|
||||
//remove private attributes
|
||||
if (i[0] == '_')
|
||||
delete link[i];
|
||||
}
|
||||
|
||||
link.x = 0;
|
||||
link.y = 0;
|
||||
link.width = 0;
|
||||
link.height = 0;
|
||||
link.visible = true;
|
||||
link.opacity = 100;
|
||||
link.composition = null;
|
||||
link.rotate = 0;
|
||||
link.data = null;
|
||||
link.params = {};
|
||||
link.status = null;
|
||||
link.render_function = null;
|
||||
link.type = null;
|
||||
|
||||
config.need_render = true;
|
||||
async layer_clear(id) {
|
||||
return app.State.do_action(
|
||||
new app.Actions.Clear_layer_action(id)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -466,24 +439,10 @@ class Base_layers_class {
|
||||
* @param {int} id
|
||||
* @param {int} direction
|
||||
*/
|
||||
move(id, direction) {
|
||||
id = parseInt(id);
|
||||
var link = this.get_layer(id);
|
||||
|
||||
if (direction < 0) {
|
||||
var target = this.find_previous(id);
|
||||
}
|
||||
else {
|
||||
var target = this.find_next(id);
|
||||
}
|
||||
if (target != null) {
|
||||
var current_order = link.order;
|
||||
link.order = target.order;
|
||||
target.order = current_order;
|
||||
}
|
||||
|
||||
this.render();
|
||||
this.Base_gui.GUI_layers.render_layers();
|
||||
async move(id, direction) {
|
||||
return app.State.do_action(
|
||||
new app.Actions.Reorder_layer_action(id, direction)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -579,18 +538,9 @@ class Base_layers_class {
|
||||
* @param {object} params
|
||||
*/
|
||||
add_filter(layer_id, name, params) {
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
var link = this.get_layer(layer_id);
|
||||
var filter = {
|
||||
id: this.Helper.getRandomInt(1, 999999999),
|
||||
name: name,
|
||||
params: params,
|
||||
};
|
||||
link.filters.push(filter);
|
||||
|
||||
config.need_render = true;
|
||||
this.Base_gui.GUI_layers.render_layers();
|
||||
return app.State.do_action(
|
||||
new app.Actions.Add_layer_filter_action(layer_id, name, params)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -600,18 +550,9 @@ class Base_layers_class {
|
||||
* @param {string} filter_id
|
||||
*/
|
||||
delete_filter(layer_id, filter_id) {
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
var link = this.get_layer(layer_id);
|
||||
|
||||
for (var i in link.filters) {
|
||||
if (link.filters[i].id == filter_id) {
|
||||
link.filters.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
config.need_render = true;
|
||||
this.Base_gui.GUI_layers.render_layers();
|
||||
return app.State.do_action(
|
||||
new app.Actions.Delete_layer_filter_action(layer_id, filter_id)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -704,28 +645,9 @@ class Base_layers_class {
|
||||
* @param {int} layer_id (optional)
|
||||
*/
|
||||
update_layer_image(canvas, layer_id) {
|
||||
if (layer_id == null)
|
||||
layer_id = config.layer.id;
|
||||
var link = this.get_layer(layer_id);
|
||||
|
||||
if (link.type != 'image'){
|
||||
alertify.error('Error: layer must be image.');
|
||||
return null;
|
||||
}
|
||||
|
||||
if(this.Helper.is_edge_or_ie() == false){
|
||||
//update image using blob (faster)
|
||||
canvas.toBlob(function (blob) {
|
||||
link.link.src = window.URL.createObjectURL(blob);
|
||||
config.need_render = true;
|
||||
}, 'image/png');
|
||||
}
|
||||
else{
|
||||
//slow way for IE, Edge
|
||||
link.link.src = canvas.toDataURL();
|
||||
}
|
||||
|
||||
config.need_render = true;
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas, layer_id)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -45,39 +45,47 @@ class Base_selection_class {
|
||||
this.selected_object_drag_type = null;
|
||||
this.click_details = {};
|
||||
this.is_touch = false;
|
||||
// True if dragging from inside canvas area
|
||||
this.is_drag = false;
|
||||
|
||||
this.events();
|
||||
}
|
||||
|
||||
events() {
|
||||
var _this = this;
|
||||
|
||||
document.addEventListener('mousedown', function (e) {
|
||||
if(_this.is_touch == true)
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
this.is_drag = false;
|
||||
if(this.is_touch == true)
|
||||
return;
|
||||
_this.selected_object_actions(e);
|
||||
if (!e.target.closest('#main_wrapper'))
|
||||
return;
|
||||
this.is_drag = true;
|
||||
this.selected_object_actions(e);
|
||||
});
|
||||
document.addEventListener('mousemove', function (e) {
|
||||
if(_this.is_touch == true)
|
||||
document.addEventListener('mousemove', (e) => {
|
||||
if(this.is_touch == true)
|
||||
return;
|
||||
_this.selected_object_actions(e);
|
||||
this.selected_object_actions(e);
|
||||
});
|
||||
document.addEventListener('mouseup', function (e) {
|
||||
if(_this.is_touch == true)
|
||||
document.addEventListener('mouseup', (e) => {
|
||||
if(this.is_touch == true)
|
||||
return;
|
||||
_this.selected_object_actions(e);
|
||||
this.selected_object_actions(e);
|
||||
});
|
||||
|
||||
// touch
|
||||
document.addEventListener('touchstart', function (event) {
|
||||
_this.is_touch = true;
|
||||
_this.selected_object_actions(event);
|
||||
document.addEventListener('touchstart', (event) => {
|
||||
this.is_drag = false;
|
||||
this.is_touch = true;
|
||||
if (!e.target.closest('#main_wrapper'))
|
||||
return;
|
||||
this.is_drag = true;
|
||||
this.selected_object_actions(event);
|
||||
});
|
||||
document.addEventListener('touchmove', function (event) {
|
||||
_this.selected_object_actions(event);
|
||||
document.addEventListener('touchmove', (event) => {
|
||||
this.selected_object_actions(event);
|
||||
}, {passive: false});
|
||||
document.addEventListener('touchend', function (event) {
|
||||
_this.selected_object_actions(event);
|
||||
document.addEventListener('touchend', (event) => {
|
||||
this.selected_object_actions(event);
|
||||
});
|
||||
}
|
||||
|
||||
@ -264,6 +272,9 @@ class Base_selection_class {
|
||||
if(event_type == 'touchmove') event_type = 'mousemove';
|
||||
if(event_type == 'touchend') event_type = 'mouseup';
|
||||
|
||||
if (!this.is_drag && ['mousedown', 'mouseup'].includes(event_type))
|
||||
return;
|
||||
|
||||
const mainWrapper = document.getElementById('main_wrapper');
|
||||
const defaultCursor = config.TOOL && config.TOOL.name === 'text' ? 'text' : 'default';
|
||||
if (mainWrapper.style.cursor != defaultCursor) {
|
||||
@ -288,7 +299,7 @@ class Base_selection_class {
|
||||
height: settings.data.height,
|
||||
};
|
||||
}
|
||||
if (event_type == 'mousemove' && this.mouse_lock == 'selected_object_actions') {
|
||||
if (event_type == 'mousemove' && this.mouse_lock == 'selected_object_actions' && this.is_drag) {
|
||||
|
||||
const allowNegativeDimensions = settings.data.render_function
|
||||
&& ['line', 'gradient'].includes(settings.data.render_function[0]);
|
||||
|
||||
@ -61,6 +61,7 @@ class Base_state_class {
|
||||
await action.do();
|
||||
} catch (error) {
|
||||
// Action aborted. This could be expected behavior if detected that the action shouldn't run.
|
||||
console.info(error);
|
||||
return { status: 'aborted', reason: error };
|
||||
}
|
||||
// Remove all redo actions from history
|
||||
@ -106,6 +107,7 @@ class Base_state_class {
|
||||
|
||||
save() {
|
||||
|
||||
/*
|
||||
this.optimize();
|
||||
|
||||
if (this.enabled == false) {
|
||||
@ -155,6 +157,7 @@ class Base_state_class {
|
||||
}
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -341,7 +341,6 @@ class GUI_colors_class {
|
||||
// Initialize hex entry
|
||||
this.inputs.hex
|
||||
.on('input', (event) => {
|
||||
console.log(event);
|
||||
const value = this.inputs.hex.val();
|
||||
const trimmedValue = value.trim();
|
||||
if (value !== trimmedValue) {
|
||||
|
||||
@ -50,13 +50,15 @@ class GUI_layers_class {
|
||||
}
|
||||
else if (target.id == 'layer_up') {
|
||||
//move layer up
|
||||
window.State.save();
|
||||
_this.Base_layers.move(config.layer.id, 1);
|
||||
app.State.do_action(
|
||||
new app.Actions.Reorder_layer_action(config.layer.id, 1)
|
||||
);
|
||||
}
|
||||
else if (target.id == 'layer_down') {
|
||||
//move layer down
|
||||
window.State.save();
|
||||
_this.Base_layers.move(config.layer.id, -1);
|
||||
app.State.do_action(
|
||||
new app.Actions.Reorder_layer_action(config.layer.id, -1)
|
||||
);
|
||||
}
|
||||
else if (target.id == 'visibility') {
|
||||
//change visibility
|
||||
@ -80,8 +82,9 @@ class GUI_layers_class {
|
||||
}
|
||||
else if (target.id == 'delete_filter') {
|
||||
//delete filter
|
||||
window.State.save();
|
||||
_this.Base_layers.delete_filter(target.dataset.pid, target.dataset.id);
|
||||
app.State.do_action(
|
||||
new app.Actions.Delete_layer_filter_action(target.dataset.pid, target.dataset.id)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@ -107,38 +110,40 @@ class GUI_layers_class {
|
||||
|
||||
document.getElementById(target_id).innerHTML = '';
|
||||
var html = '';
|
||||
|
||||
if (config.layer) {
|
||||
for (var i in layers) {
|
||||
var value = layers[i];
|
||||
|
||||
for (var i in layers) {
|
||||
var value = layers[i];
|
||||
if (value.id == config.layer.id)
|
||||
html += '<div class="item active">';
|
||||
else
|
||||
html += '<div class="item">';
|
||||
if (value.visible == true)
|
||||
html += ' <span class="visibility visible" id="visibility" data-id="' + value.id + '" title="hide"></span>';
|
||||
else
|
||||
html += ' <span class="visibility" id="visibility" data-id="' + value.id + '" title="show"></span>';
|
||||
html += ' <span class="delete" id="delete" data-id="' + value.id + '" title="delete"></span>';
|
||||
html += ' <span class="layer_name" id="layer_name" data-id="' + value.id + '">' + value.name + '</span>';
|
||||
html += ' <div class="clear"></div>';
|
||||
html += '</div>';
|
||||
|
||||
if (value.id == config.layer.id)
|
||||
html += '<div class="item active">';
|
||||
else
|
||||
html += '<div class="item">';
|
||||
if (value.visible == true)
|
||||
html += ' <span class="visibility visible" id="visibility" data-id="' + value.id + '" title="hide"></span>';
|
||||
else
|
||||
html += ' <span class="visibility" id="visibility" data-id="' + value.id + '" title="show"></span>';
|
||||
html += ' <span class="delete" id="delete" data-id="' + value.id + '" title="delete"></span>';
|
||||
html += ' <span class="layer_name" id="layer_name" data-id="' + value.id + '">' + value.name + '</span>';
|
||||
html += ' <div class="clear"></div>';
|
||||
html += '</div>';
|
||||
//show filters
|
||||
if (layers[i].filters.length > 0) {
|
||||
html += '<div class="filters">';
|
||||
for (var j in layers[i].filters) {
|
||||
var filter = layers[i].filters[j];
|
||||
var title = this.Helper.ucfirst(filter.name);
|
||||
title = title.replace(/-/g, ' ');
|
||||
|
||||
//show filters
|
||||
if (layers[i].filters.length > 0) {
|
||||
html += '<div class="filters">';
|
||||
for (var j in layers[i].filters) {
|
||||
var filter = layers[i].filters[j];
|
||||
var title = this.Helper.ucfirst(filter.name);
|
||||
title = title.replace(/-/g, ' ');
|
||||
|
||||
html += '<div class="filter">';
|
||||
html += ' <span class="delete" id="delete_filter" data-pid="' + layers[i].id + '" data-id="' + filter.id + '" title="delete"></span>';
|
||||
html += ' <span class="layer_name" id="filter_name" data-pid="' + layers[i].id + '" data-id="' + filter.id + '">' + title + '</span>';
|
||||
html += ' <div class="clear"></div>';
|
||||
html += '<div class="filter">';
|
||||
html += ' <span class="delete" id="delete_filter" data-pid="' + layers[i].id + '" data-id="' + filter.id + '" title="delete"></span>';
|
||||
html += ' <span class="layer_name" id="filter_name" data-pid="' + layers[i].id + '" data-id="' + filter.id + '">' + title + '</span>';
|
||||
html += ' <div class="clear"></div>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../../app.js';
|
||||
import config from './../../../config.js';
|
||||
import Dialog_class from './../../../libs/popup.js';
|
||||
import Base_layers_class from './../../../core/base-layers.js';
|
||||
@ -38,7 +39,9 @@ class Effects_common_class {
|
||||
}
|
||||
|
||||
save(params, type) {
|
||||
this.Base_layers.add_filter(null, type, params);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Add_layer_filter_action(null, type, params)
|
||||
);
|
||||
}
|
||||
|
||||
preview(params, type) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -66,7 +67,9 @@ class Effects_backAndWhite_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -32,7 +33,9 @@ class Effects_blueprint_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -52,7 +53,9 @@ class Effects_boxBlur_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -51,7 +52,9 @@ class Effects_denoise_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -50,7 +51,9 @@ class Effects_dither_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -51,7 +52,9 @@ class Effects_dotScreen_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -29,7 +30,9 @@ class Effects_edge_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -29,7 +30,9 @@ class Effects_emboss_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -48,7 +49,9 @@ class Effects_enrich_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -51,7 +52,9 @@ class Effects_grains_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -28,7 +29,9 @@ class Effects_heatmap_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -29,7 +30,9 @@ class Effects_1977_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import config from '../../../config.js';
|
||||
import app from '../../../app.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
import alertify from 'alertifyjs/build/alertify.min.js';
|
||||
@ -16,8 +16,6 @@ class Effects_aden_class {
|
||||
return;
|
||||
}
|
||||
|
||||
window.State.save();
|
||||
|
||||
//get canvas from layer
|
||||
var canvas = this.Base_layers.convert_layer_to_canvas(null, true);
|
||||
var ctx = canvas.getContext("2d");
|
||||
@ -28,7 +26,9 @@ class Effects_aden_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -29,7 +30,9 @@ class Effects_clarendon_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -28,7 +29,9 @@ class Effects_gingham_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -33,7 +34,9 @@ class Effects_inkwell_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -27,7 +28,9 @@ class Effects_lofi_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -32,7 +33,9 @@ class Effects_toaster_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -28,7 +29,9 @@ class Effects_valencia_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from '../../../app.js';
|
||||
import config from '../../../config.js';
|
||||
import Dialog_class from '../../../libs/popup.js';
|
||||
import Base_layers_class from '../../../core/base-layers.js';
|
||||
@ -28,7 +29,9 @@ class Effects_xpro2_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -50,7 +51,9 @@ class Effects_mosaic_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -32,7 +33,9 @@ class Effects_nightVision_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -51,7 +52,9 @@ class Effects_oil_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -28,7 +29,9 @@ class Effects_pencil_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, width, height) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -50,7 +51,9 @@ class Effects_sharpen_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -29,7 +30,9 @@ class Effects_solarize_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -73,7 +74,9 @@ class Effects_tiltShift_class {
|
||||
this.change(canvas, params);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -51,7 +52,9 @@ class Effects_vibrance_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -52,7 +53,9 @@ class Effects_vignette_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -49,7 +50,9 @@ class Effects_vintage_class {
|
||||
this.change(canvas, params);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -60,7 +61,9 @@ class Effects_zoomBlur_class {
|
||||
ctx.drawImage(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -54,7 +55,9 @@ class Image_autoAdjust_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
get_adjust_data(data) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -61,7 +62,9 @@ class Image_colorCorrections_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
do_corrections(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -53,7 +54,9 @@ class Image_decreaseColors_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
get_decreased_data(data, colors, greyscale) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import alertify from './../../../../node_modules/alertifyjs/build/alertify.min.js';
|
||||
@ -47,7 +48,9 @@ class Image_flip_class {
|
||||
}
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas2);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas2)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Base_gui_class from './../../core/base-gui.js';
|
||||
@ -58,7 +59,7 @@ class Image_resize_class {
|
||||
{name: "mode", title: "Mode:", values: ["Lanczos", "Hermite", "Basic"]},
|
||||
|
||||
{name: "sharpen", title: "Sharpen:", value: false},
|
||||
{name: "layers", title: "Layers:", values: ["Active", "All"], value: "Active"},
|
||||
{name: "layers", title: "Layers:", values: ["All", "Active"], value: "All"},
|
||||
],
|
||||
on_finish: function (params) {
|
||||
_this.do_resize(params);
|
||||
@ -67,50 +68,61 @@ class Image_resize_class {
|
||||
this.POP.show(settings);
|
||||
}
|
||||
|
||||
do_resize(params) {
|
||||
async do_resize(params) {
|
||||
//validate
|
||||
if (isNaN(params.width) && isNaN(params.height) && isNaN(params.width_percent) && isNaN(params.height_percent)){
|
||||
if (isNaN(params.width) && isNaN(params.height) && isNaN(params.width_percent) && isNaN(params.height_percent)) {
|
||||
alertify.error('Missing at least 1 size parameter.');
|
||||
return false;
|
||||
}
|
||||
if (params.width == config.WIDTH && params.height == config.HEIGHT){
|
||||
if (params.layers == 'All' && params.width == config.WIDTH && params.height == config.HEIGHT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window.State.save();
|
||||
|
||||
// Build a list of actions to execute for resize
|
||||
let actions = [];
|
||||
|
||||
if (params.layers == 'All') {
|
||||
//resize all layers
|
||||
var skips = 0;
|
||||
for (var i in config.layers) {
|
||||
var response = this.resize_layer(config.layers[i], params);
|
||||
if(response === false){
|
||||
try {
|
||||
actions = actions.concat(await this.resize_layer(config.layers[i], params));
|
||||
|
||||
} catch (error) {
|
||||
skips++;
|
||||
}
|
||||
}
|
||||
if (skips > 0) {
|
||||
alertify.error(skips + ' layer(s) were skipped.');
|
||||
}
|
||||
actions = actions.concat(this.resize_gui(params));
|
||||
}
|
||||
else {
|
||||
//only active
|
||||
this.resize_layer(config.layer, params);
|
||||
actions = actions.concat(await this.resize_layer(config.layer, params));
|
||||
}
|
||||
return app.State.do_action(
|
||||
new app.Actions.Bundle_action('resize_layers', 'Resize Layers', actions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* it will try to resize layer (image, text, vector), returns false on failure.
|
||||
* Generates actions that will resize layer (image, text, vector), returns a promise that rejects on failure.
|
||||
*
|
||||
* @param {object} layer
|
||||
* @param {object} params
|
||||
* @returns {undefined|Boolean}
|
||||
* @returns {Promise<object>} Returns array of actions to perform
|
||||
*/
|
||||
resize_layer(layer, params) {
|
||||
async resize_layer(layer, params) {
|
||||
var mode = params.mode;
|
||||
var width = parseInt(params.width);
|
||||
var height = parseInt(params.height);
|
||||
var width_100 = parseInt(params.width_percent);
|
||||
var height_100 = parseInt(params.height_percent);
|
||||
var canvas_width;
|
||||
var canvas_height;
|
||||
var sharpen = params.sharpen;
|
||||
var _this = this;
|
||||
|
||||
@ -118,52 +130,71 @@ class Image_resize_class {
|
||||
if (isNaN(width) && isNaN(height)) {
|
||||
if (isNaN(width_100) == false) {
|
||||
width = Math.round(layer.width * width_100 / 100);
|
||||
canvas_width = Math.round(config.WIDTH * width_100 / 100);
|
||||
}
|
||||
if (isNaN(height_100) == false) {
|
||||
height = Math.round(layer.height * height_100 / 100);
|
||||
canvas_height = Math.round(config.HEIGHT * height_100 / 100);
|
||||
}
|
||||
}
|
||||
|
||||
//if only 1 dimension was provided
|
||||
if (isNaN(width) || isNaN(height)) {
|
||||
var ratio = layer.width / layer.height;
|
||||
var canvas_ratio = config.WIDTH / config.HEIGHT;
|
||||
if (isNaN(width))
|
||||
width = Math.round(height * ratio);
|
||||
canvas_width = Math.round(canvas_height * canvas_ratio);
|
||||
if (isNaN(height))
|
||||
height = Math.round(width / ratio);
|
||||
canvas_height = Math.round(canvas_width / canvas_ratio);
|
||||
}
|
||||
|
||||
let new_x = params.layers == 'All' ? Math.round(layer.x * canvas_width / config.WIDTH) : layer.x;
|
||||
let new_y = params.layers == 'All' ? Math.round(layer.y * canvas_height / config.HEIGHT) : layer.y;
|
||||
|
||||
//is text
|
||||
if(layer.type == 'text'){
|
||||
if (layer.type == 'text') {
|
||||
var xratio = width / layer.width;
|
||||
for (let line of layer.data) {
|
||||
let data = JSON.parse(JSON.stringify(layer.data));
|
||||
for (let line of data) {
|
||||
for (let span of line) {
|
||||
span.meta.size = Math.ceil((span.meta.size || textMetaDefaults.size) * xratio);
|
||||
span.meta.stroke_size = parseFloat((0.1 * Math.round((span.meta.stroke_size != null ? span.meta.stroke_size : textMetaDefaults.stroke_size) * xratio / 0.1)).toFixed(1));
|
||||
span.meta.kerning = Math.ceil((span.meta.kerning || textMetaDefaults.kerning) * xratio);
|
||||
}
|
||||
}
|
||||
layer.width = width;
|
||||
layer.height = height;
|
||||
this.resize_gui();
|
||||
config.need_render = true;
|
||||
return true;
|
||||
|
||||
// Return actions
|
||||
return [
|
||||
new app.Actions.Update_layer_action(layer.id, {
|
||||
x: new_x,
|
||||
y: new_y,
|
||||
data,
|
||||
width,
|
||||
height
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
//is vector
|
||||
if(layer.is_vector == true && layer.width != null && layer.height != null){
|
||||
layer.width = width;
|
||||
layer.height = height;
|
||||
this.resize_gui();
|
||||
config.need_render = true;
|
||||
return true;
|
||||
else if (layer.is_vector == true && layer.width != null && layer.height != null) {
|
||||
// Return actions
|
||||
return [
|
||||
new app.Actions.Update_layer_action(layer.id, {
|
||||
x: new_x,
|
||||
y: new_y,
|
||||
width,
|
||||
height
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
//only images supported at this point
|
||||
if (layer.type != 'image') {
|
||||
else if (layer.type != 'image') {
|
||||
//error - no support
|
||||
alertify.error('Layer must be vector or image (convert it to raster).');
|
||||
return false;
|
||||
throw new Error('Layer is not compatible with resize');
|
||||
}
|
||||
|
||||
//get canvas from layer
|
||||
@ -184,19 +215,15 @@ class Image_resize_class {
|
||||
tmp_data.width = width;
|
||||
tmp_data.height = height;
|
||||
|
||||
this.pica.resize(canvas, tmp_data, {
|
||||
await this.pica.resize(canvas, tmp_data, {
|
||||
alpha: true,
|
||||
})
|
||||
.then(function(result) {
|
||||
.then((result) => {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
ctx.drawImage(tmp_data, 0, 0, width, height);
|
||||
|
||||
finish_resize();
|
||||
});
|
||||
return;
|
||||
}
|
||||
else if (mode == "Hermite") {
|
||||
//Hermite resample
|
||||
@ -216,48 +243,59 @@ class Image_resize_class {
|
||||
ctx.drawImage(tmp_data, 0, 0, width, height);
|
||||
}
|
||||
|
||||
finish_resize();
|
||||
|
||||
//private finish action
|
||||
function finish_resize(){
|
||||
if (sharpen == true) {
|
||||
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
var filtered = _this.ImageFilters.Sharpen(imageData, 1); //add effect
|
||||
ctx.putImageData(filtered, 0, 0);
|
||||
}
|
||||
|
||||
//save
|
||||
_this.Base_layers.update_layer_image(canvas, layer.id);
|
||||
layer.width = canvas.width;
|
||||
layer.height = canvas.height;
|
||||
layer.width_original = canvas.width;
|
||||
layer.height_original = canvas.height;
|
||||
config.need_render = true;
|
||||
|
||||
_this.resize_gui();
|
||||
if (sharpen == true) {
|
||||
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
var filtered = _this.ImageFilters.Sharpen(imageData, 1); //add effect
|
||||
ctx.putImageData(filtered, 0, 0);
|
||||
}
|
||||
|
||||
// Return actions
|
||||
return [
|
||||
new app.Actions.Update_layer_image_action(canvas, layer.id),
|
||||
new app.Actions.Update_layer_action(layer.id, {
|
||||
x: new_x,
|
||||
y: new_y,
|
||||
width: canvas.width,
|
||||
height: canvas.height,
|
||||
width_original: canvas.width,
|
||||
height_original: canvas.height
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
resize_gui() {
|
||||
var max_x = 0;
|
||||
var max_y = 0;
|
||||
|
||||
for (var i = 0; i < config.layers.length; i++) {
|
||||
var layer = config.layers[i];
|
||||
|
||||
if(layer.width == null || layer.height == null || layer.x == null || layer.y == null){
|
||||
//layer without dimensions
|
||||
continue;
|
||||
}
|
||||
resize_gui(params) {
|
||||
var width = parseInt(params.width);
|
||||
var height = parseInt(params.height);
|
||||
var width_100 = parseInt(params.width_percent);
|
||||
var height_100 = parseInt(params.height_percent);
|
||||
|
||||
max_x = Math.max(max_x, layer.x + layer.width);
|
||||
max_y = Math.max(max_y, layer.y + layer.height);
|
||||
//if dimension with percent provided
|
||||
if (isNaN(width) && isNaN(height)) {
|
||||
if (isNaN(width_100) == false) {
|
||||
width = Math.round(config.WIDTH * width_100 / 100);
|
||||
}
|
||||
if (isNaN(height_100) == false) {
|
||||
height = Math.round(config.HEIGHT * height_100 / 100);
|
||||
}
|
||||
}
|
||||
|
||||
config.WIDTH = parseInt(max_x);
|
||||
config.HEIGHT = parseInt(max_y);
|
||||
this.Base_gui.prepare_canvas();
|
||||
config.need_render = true;
|
||||
|
||||
//if only 1 dimension was provided
|
||||
if (isNaN(width) || isNaN(height)) {
|
||||
var ratio = config.WIDTH / config.HEIGHT;
|
||||
if (isNaN(width))
|
||||
width = Math.round(height * ratio);
|
||||
if (isNaN(height))
|
||||
height = Math.round(width / ratio);
|
||||
}
|
||||
|
||||
return [
|
||||
new app.Actions.Prepare_canvas_action('undo'),
|
||||
new app.Actions.Update_config_action({
|
||||
WIDTH: parseInt(width),
|
||||
HEIGHT: parseInt(height)
|
||||
}),
|
||||
new app.Actions.Prepare_canvas_action('do')
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_gui_class from './../../core/base-gui.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
@ -38,9 +39,7 @@ class Image_trim_class {
|
||||
}, false);
|
||||
}
|
||||
|
||||
trim(){
|
||||
var _this = this;
|
||||
|
||||
trim() {
|
||||
var removeWhiteColor = false;
|
||||
if(config.TRANSPARENCY == false)
|
||||
removeWhiteColor = true;
|
||||
@ -53,58 +52,64 @@ class Image_trim_class {
|
||||
{}, //gap
|
||||
{name: "remove_white", title: "Trim white color?", value: removeWhiteColor},
|
||||
],
|
||||
on_finish: function (params) {
|
||||
window.State.save();
|
||||
if(params.trim_layer == true)
|
||||
_this.trim_layer(config.layer.id, params.remove_white);
|
||||
if(params.trim_all == true)
|
||||
_this.trim_all(params.remove_white);
|
||||
on_finish: (params) => {
|
||||
let actions = [];
|
||||
if (params.trim_layer == true)
|
||||
actions = actions.concat(this.trim_layer(config.layer.id, params.remove_white));
|
||||
if (params.trim_all == true)
|
||||
actions = actions.concat(this.trim_all(params.remove_white));
|
||||
if (actions.length > 0) {
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('trim_layers', 'Trim Layers', actions)
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
this.Dialog.show(settings);
|
||||
}
|
||||
|
||||
trim_layer(layer_id, removeWhiteColor = false){
|
||||
trim_layer(layer_id, removeWhiteColor = false) {
|
||||
var layer = this.Base_layers.get_layer(layer_id);
|
||||
|
||||
if (config.layer.type != 'image') {
|
||||
if (layer.type != 'image') {
|
||||
alertify.error('Skip - layer must be image.');
|
||||
return false;
|
||||
}
|
||||
|
||||
var trim = this.get_trim_info(layer_id, removeWhiteColor);
|
||||
trim = trim.relative;
|
||||
|
||||
if(layer.type == 'image'){
|
||||
//if image was stretched
|
||||
var width_ratio = (layer.width / layer.width_original);
|
||||
var height_ratio = (layer.height / layer.height_original);
|
||||
|
||||
//if image was stretched
|
||||
var width_ratio = (layer.width / layer.width_original);
|
||||
var height_ratio = (layer.height / layer.height_original);
|
||||
|
||||
//create smaller canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext("2d");
|
||||
canvas.width = trim.width / width_ratio;
|
||||
canvas.height = trim.height / height_ratio;
|
||||
//create smaller canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext("2d");
|
||||
canvas.width = trim.width / width_ratio;
|
||||
canvas.height = trim.height / height_ratio;
|
||||
|
||||
//cut required part
|
||||
ctx.translate(-trim.left / width_ratio, -trim.top / height_ratio);
|
||||
canvas.getContext("2d").drawImage(layer.link, 0, 0);
|
||||
ctx.translate(0, 0);
|
||||
this.Base_layers.update_layer_image(canvas, layer.id);
|
||||
//cut required part
|
||||
ctx.translate(-trim.left / width_ratio, -trim.top / height_ratio);
|
||||
canvas.getContext("2d").drawImage(layer.link, 0, 0);
|
||||
ctx.translate(0, 0);
|
||||
|
||||
//update attributes
|
||||
layer.width = Math.ceil(canvas.width * width_ratio);
|
||||
layer.height = Math.ceil(canvas.height * height_ratio);
|
||||
layer.x += trim.left;
|
||||
layer.y += trim.top;
|
||||
layer.width_original = canvas.width;
|
||||
layer.height_original = canvas.height;
|
||||
}
|
||||
|
||||
config.need_render = true;
|
||||
return [
|
||||
new app.Actions.Update_layer_image_action(canvas, layer.id),
|
||||
new app.Actions.Update_layer_action(layer.id, {
|
||||
x: layer.x + trim.left,
|
||||
y: layer.y + trim.top,
|
||||
width: Math.ceil(canvas.width * width_ratio),
|
||||
height: Math.ceil(canvas.height * height_ratio),
|
||||
width_original: canvas.width,
|
||||
height_original: canvas.height
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
trim_all(removeWhiteColor = false) {
|
||||
let actions = [];
|
||||
|
||||
var all_top = config.HEIGHT;
|
||||
var all_left = config.WIDTH;
|
||||
var all_bottom = config.HEIGHT;
|
||||
@ -118,12 +123,12 @@ class Image_trim_class {
|
||||
}
|
||||
|
||||
//collect info
|
||||
for (var i = 0; i < config.layers.length; i++) {
|
||||
var layer = config.layers[i];
|
||||
for (let i = 0; i < config.layers.length; i++) {
|
||||
let layer = config.layers[i];
|
||||
|
||||
if(layer.width == null || layer.height == null || layer.x == null || layer.y == null){
|
||||
if (layer.width == null || layer.height == null || layer.x == null || layer.y == null) {
|
||||
//layer without dimensions
|
||||
var trim_info = this.get_trim_info(layer.id, removeWhiteColor);
|
||||
const trim_info = this.get_trim_info(layer.id, removeWhiteColor);
|
||||
|
||||
all_top = Math.min(all_top, trim_info.top);
|
||||
all_left = Math.min(all_left, trim_info.left);
|
||||
@ -139,25 +144,29 @@ class Image_trim_class {
|
||||
}
|
||||
|
||||
//move every layer
|
||||
for (var i = 0; i < config.layers.length; i++) {
|
||||
var layer = config.layers[i];
|
||||
for (let i = 0; i < config.layers.length; i++) {
|
||||
let layer = config.layers[i];
|
||||
if (layer.x == null || layer.y == null || layer.type == null)
|
||||
continue;
|
||||
|
||||
layer.x = layer.x - all_left;
|
||||
layer.y = layer.y - all_top;
|
||||
actions.push(
|
||||
new app.Actions.Update_layer_action(layer.id, {
|
||||
x: layer.x - all_left,
|
||||
y: layer.y - all_top
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
//resize
|
||||
config.WIDTH = config.WIDTH - all_left - all_right;
|
||||
config.HEIGHT = config.HEIGHT - all_top - all_bottom;
|
||||
if (config.WIDTH < 1)
|
||||
config.WIDTH = 1;
|
||||
if (config.HEIGHT < 1)
|
||||
config.HEIGHT = 1;
|
||||
|
||||
this.Base_gui.prepare_canvas();
|
||||
config.need_render = true;
|
||||
actions.push(
|
||||
new app.Actions.Prepare_canvas_action('undo'),
|
||||
new app.Actions.Update_config_action({
|
||||
WIDTH: Math.max(1, config.WIDTH - all_left - all_right),
|
||||
HEIGHT: Math.max(1, config.HEIGHT - all_top - all_bottom)
|
||||
}),
|
||||
new app.Actions.Prepare_canvas_action('do')
|
||||
);
|
||||
return actions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
|
||||
@ -8,9 +9,9 @@ class Layer_clear_class {
|
||||
}
|
||||
|
||||
clear() {
|
||||
window.State.save();
|
||||
|
||||
this.Base_layers.layer_clear(config.layer.id);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Clear_layer_action(config.layer.id)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -46,7 +46,6 @@ class Layer_flatten_class {
|
||||
for (var i = config.layers.length - 1; i >= 0; i--) {
|
||||
delete_actions.push(new app.Actions.Delete_layer_action(config.layers[i].id));
|
||||
}
|
||||
console.log(delete_actions);
|
||||
// Run actions
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('flatten_image', 'Flatten Image', [
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
|
||||
@ -8,13 +9,15 @@ class Layer_move_class {
|
||||
}
|
||||
|
||||
up() {
|
||||
window.State.save();
|
||||
this.Base_layers.move(config.layer.id, 1);
|
||||
app.State.do_action(
|
||||
new app.Actions.Reorder_layer_action(config.layer.id, 1)
|
||||
);
|
||||
}
|
||||
|
||||
down() {
|
||||
window.State.save();
|
||||
this.Base_layers.move(config.layer.id, -1);
|
||||
app.State.do_action(
|
||||
new app.Actions.Reorder_layer_action(config.layer.id, -1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -50,7 +51,9 @@ class Tools_colorToAlpha_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, color) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -49,7 +50,9 @@ class Tools_colorZoom_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
change(data, zoom, center) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -63,11 +64,17 @@ class Tools_contentFill_class {
|
||||
this.change(canvas, params);
|
||||
|
||||
//save
|
||||
config.layer.x = 0;
|
||||
config.layer.y = 0;
|
||||
config.layer.width = config.WIDTH;
|
||||
config.layer.height = config.HEIGHT;
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Bundle_action('content_fill', 'Content Fill', [
|
||||
new app.Actions.Update_layer_action(config.layer.id, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: config.WIDTH,
|
||||
height: config.HEIGHT
|
||||
}),
|
||||
new app.Actions.Update_layer_image_data(canvas)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
change(canvas, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -54,7 +55,9 @@ class Tools_replaceColor_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
do_replace(data, params) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import app from './../../app.js';
|
||||
import config from './../../config.js';
|
||||
import Base_layers_class from './../../core/base-layers.js';
|
||||
import Dialog_class from './../../libs/popup.js';
|
||||
@ -48,7 +49,9 @@ class Tools_restoreAlpha_class {
|
||||
ctx.putImageData(data, 0, 0);
|
||||
|
||||
//save
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
return app.State.do_action(
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
);
|
||||
}
|
||||
|
||||
recover_alpha(data, level) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -128,7 +129,11 @@ class Blur_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('blur_tool', 'Blur Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -105,7 +106,11 @@ class BulgePinch_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('bulge_pinch_tool', 'Bulge/Pinch Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -259,7 +260,11 @@ class Clone_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('clone_tool', 'Clone Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -30,28 +31,30 @@ class Crop_class extends Base_tools_class {
|
||||
return _this.selection;
|
||||
},
|
||||
};
|
||||
this.mousedown_selection = null;
|
||||
this.Base_selection = new Base_selection_class(ctx, sel_config, this.name);
|
||||
}
|
||||
|
||||
dragStart(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
this.is_mousedown_canvas = false;
|
||||
if (config.TOOL.name != this.name)
|
||||
return;
|
||||
_this.mousedown(event);
|
||||
if (!event.target.closest('#main_wrapper'))
|
||||
return;
|
||||
this.is_mousedown_canvas = true;
|
||||
this.mousedown(event);
|
||||
}
|
||||
|
||||
dragMove(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
if (config.TOOL.name != this.name)
|
||||
return;
|
||||
_this.mousemove(event);
|
||||
this.mousemove(event);
|
||||
}
|
||||
|
||||
dragEnd(event) {
|
||||
var _this = this;
|
||||
if (config.TOOL.name != _this.name)
|
||||
if (config.TOOL.name != this.name)
|
||||
return;
|
||||
_this.mouseup(event);
|
||||
this.mouseup(event);
|
||||
}
|
||||
|
||||
load() {
|
||||
@ -82,9 +85,11 @@ class Crop_class extends Base_tools_class {
|
||||
|
||||
mousedown(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
if (mouse.valid == false || mouse.click_valid == false)
|
||||
if (this.Base_selection.is_drag == false || mouse.valid == false || mouse.click_valid == false)
|
||||
return;
|
||||
|
||||
this.mousedown_selection = JSON.parse(JSON.stringify(this.selection));
|
||||
|
||||
if (this.Base_selection.mouse_lock !== null) {
|
||||
return;
|
||||
}
|
||||
@ -95,7 +100,7 @@ class Crop_class extends Base_tools_class {
|
||||
|
||||
mousemove(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
if (mouse.is_drag == false) {
|
||||
if (this.Base_selection.is_drag == false || mouse.is_drag == false) {
|
||||
return;
|
||||
}
|
||||
if (e.type == 'mousedown' && (mouse.valid == false || mouse.click_valid == false)) {
|
||||
@ -108,7 +113,7 @@ class Crop_class extends Base_tools_class {
|
||||
var width = mouse.x - mouse.click_x;
|
||||
var height = mouse.y - mouse.click_y;
|
||||
|
||||
if(event.ctrlKey == true || event.metaKey){
|
||||
if(e.ctrlKey == true || e.metaKey){
|
||||
//ctrl is pressed - crop will be calculated based on global width and height ratio
|
||||
var ratio = config.WIDTH / config.HEIGHT;
|
||||
var width_new = Math.round(height * ratio);
|
||||
@ -134,6 +139,9 @@ class Crop_class extends Base_tools_class {
|
||||
mouseup(e) {
|
||||
var mouse = this.get_mouse_info(e);
|
||||
|
||||
if (!this.Base_selection.is_drag) {
|
||||
return;
|
||||
}
|
||||
if (e.type == 'mousedown' && mouse.click_valid == false) {
|
||||
return;
|
||||
}
|
||||
@ -183,7 +191,9 @@ class Crop_class extends Base_tools_class {
|
||||
this.selection.height = config.HEIGHT - this.selection.y;
|
||||
}
|
||||
|
||||
config.need_render = true;
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
render(ctx, layer) {
|
||||
@ -193,7 +203,7 @@ class Crop_class extends Base_tools_class {
|
||||
/**
|
||||
* do actual crop
|
||||
*/
|
||||
on_params_update() {
|
||||
async on_params_update() {
|
||||
var params = this.getParams();
|
||||
var selection = this.selection;
|
||||
params.crop = true;
|
||||
@ -229,69 +239,98 @@ class Crop_class extends Base_tools_class {
|
||||
selection.width = Math.min(selection.width, config.WIDTH);
|
||||
selection.height = Math.min(selection.height, config.HEIGHT);
|
||||
|
||||
let actions = [];
|
||||
|
||||
for (var i in config.layers) {
|
||||
var link = config.layers[i];
|
||||
if (link.type == null)
|
||||
continue;
|
||||
|
||||
let x = link.x;
|
||||
let y = link.y;
|
||||
let width = link.width;
|
||||
let height = link.height;
|
||||
let width_original = link.width_original;
|
||||
let height_original = link.height_original;
|
||||
|
||||
//move
|
||||
link.x -= parseInt(selection.x);
|
||||
link.y -= parseInt(selection.y);
|
||||
x -= parseInt(selection.x);
|
||||
y -= parseInt(selection.y);
|
||||
|
||||
if (link.type == 'image') {
|
||||
//also remove unvisible data
|
||||
var left = 0;
|
||||
if (link.x < 0)
|
||||
left = -link.x;
|
||||
var top = 0;
|
||||
if (link.y < 0)
|
||||
top = -link.y;
|
||||
var right = 0;
|
||||
if (link.x + link.width > selection.width)
|
||||
right = link.x + link.width - selection.width;
|
||||
var bottom = 0;
|
||||
if (link.y + link.height > selection.height)
|
||||
bottom = link.y + link.height - selection.height;
|
||||
var width = link.width - left - right;
|
||||
var height = link.height - top - bottom;
|
||||
let left = 0;
|
||||
if (x < 0)
|
||||
left = -x;
|
||||
let top = 0;
|
||||
if (y < 0)
|
||||
top = -y;
|
||||
let right = 0;
|
||||
if (x + width > selection.width)
|
||||
right = x + width - selection.width;
|
||||
let bottom = 0;
|
||||
if (y + height > selection.height)
|
||||
bottom = y + height - selection.height;
|
||||
let crop_width = width - left - right;
|
||||
let crop_height = height - top - bottom;
|
||||
|
||||
//if image was streched
|
||||
var width_ratio = (link.width / link.width_original);
|
||||
var height_ratio = (link.height / link.height_original);
|
||||
let width_ratio = (width / width_original);
|
||||
let height_ratio = (height / height_original);
|
||||
|
||||
//create smaller canvas
|
||||
var canvas = document.createElement('canvas');
|
||||
var ctx = canvas.getContext("2d");
|
||||
canvas.width = width / width_ratio;
|
||||
canvas.height = height / height_ratio;
|
||||
let canvas = document.createElement('canvas');
|
||||
let ctx = canvas.getContext("2d");
|
||||
canvas.width = crop_width / width_ratio;
|
||||
canvas.height = crop_height / height_ratio;
|
||||
|
||||
//cut required part
|
||||
ctx.translate(-left / width_ratio, -top / height_ratio);
|
||||
canvas.getContext("2d").drawImage(link.link, 0, 0);
|
||||
ctx.translate(0, 0);
|
||||
this.Base_layers.update_layer_image(canvas, link.id);
|
||||
actions.push(
|
||||
new app.Actions.Update_layer_image_action(canvas, link.id)
|
||||
);
|
||||
|
||||
//update attributes
|
||||
link.width = Math.ceil(canvas.width * width_ratio);
|
||||
link.height = Math.ceil(canvas.height * height_ratio);
|
||||
link.x += left;
|
||||
link.y += top;
|
||||
link.width_original = canvas.width;
|
||||
link.height_original = canvas.height;
|
||||
width = Math.ceil(canvas.width * width_ratio);
|
||||
height = Math.ceil(canvas.height * height_ratio);
|
||||
x += left;
|
||||
y += top;
|
||||
width_original = canvas.width;
|
||||
height_original = canvas.height;
|
||||
}
|
||||
|
||||
actions.push(
|
||||
new app.Actions.Update_layer_action(link.id, {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
width_original,
|
||||
height_original
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
config.WIDTH = parseInt(selection.width);
|
||||
config.HEIGHT = parseInt(selection.height);
|
||||
|
||||
this.Base_gui.prepare_canvas();
|
||||
actions.push(
|
||||
new app.Actions.Prepare_canvas_action('undo'),
|
||||
new app.Actions.Update_config_action({
|
||||
WIDTH: parseInt(selection.width),
|
||||
HEIGHT: parseInt(selection.height)
|
||||
}),
|
||||
new app.Actions.Prepare_canvas_action('do'),
|
||||
new app.Actions.Reset_selection_action()
|
||||
);
|
||||
await app.State.do_action(
|
||||
new app.Actions.Bundle_action('crop_tool', 'Crop Tool', actions)
|
||||
);
|
||||
this.selection = {
|
||||
x: null,
|
||||
y: null,
|
||||
width: null,
|
||||
height: null,
|
||||
};
|
||||
this.Base_selection.reset_selection();
|
||||
}
|
||||
|
||||
on_leave() {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -129,7 +130,11 @@ class Desaturate_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('desaturate_tool', 'Desaturate Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -155,7 +156,11 @@ class Erase_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('erase_tool', 'Erase Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -106,7 +106,11 @@ class Fill_class extends Base_tools_class {
|
||||
|
||||
if (config.layer.type != null) {
|
||||
//update
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('fill_tool', 'Fill Tool', [
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
])
|
||||
);
|
||||
}
|
||||
else {
|
||||
//create new
|
||||
@ -119,7 +123,7 @@ class Fill_class extends Base_tools_class {
|
||||
params.width = canvas.width;
|
||||
params.height = canvas.height;
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('fill', 'Fill', [
|
||||
new app.Actions.Bundle_action('fill_tool', 'Fill Tool', [
|
||||
new app.Actions.Insert_layer_action(params)
|
||||
])
|
||||
);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -88,7 +89,11 @@ class Magic_erase_class extends Base_tools_class {
|
||||
this.magic_erase_general(ctx, config.WIDTH, config.HEIGHT,
|
||||
mouse_x, mouse_y, params.power, params.anti_aliasing, params.contiguous);
|
||||
|
||||
this.Base_layers.update_layer_image(canvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('magic_erase_tool', 'Magic Eraser Tool', [
|
||||
new app.Actions.Update_layer_image_action(canvas)
|
||||
])
|
||||
);
|
||||
//prevent crash bug on touch screen - hard to explain and debug
|
||||
await new Promise(r => setTimeout(r, 10));
|
||||
this.working = false;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -249,7 +250,11 @@ class Selection_class extends Base_tools_class {
|
||||
return;
|
||||
|
||||
delete config.layer.link_canvas;
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
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;
|
||||
@ -283,7 +288,12 @@ class Selection_class extends Base_tools_class {
|
||||
//do erase
|
||||
this.tmpCanvasCtx.clearRect(mouse_x, mouse_y, selection.width, selection.height);
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('selection_tool', 'Selection Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
this.selection = {
|
||||
x: null,
|
||||
y: null,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
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';
|
||||
@ -128,7 +129,11 @@ class Sharpen_class extends Base_tools_class {
|
||||
}
|
||||
delete config.layer.link_canvas;
|
||||
|
||||
this.Base_layers.update_layer_image(this.tmpCanvas);
|
||||
app.State.do_action(
|
||||
new app.Actions.Bundle_action('sharpen_tool', 'Sharpen Tool', [
|
||||
new app.Actions.Update_layer_image_action(this.tmpCanvas)
|
||||
])
|
||||
);
|
||||
|
||||
//decrease memory
|
||||
this.tmpCanvas.width = 1;
|
||||
|
||||
@ -367,12 +367,6 @@ class Text_document_class {
|
||||
for (let i = 0; i < insertLine.length; i++) {
|
||||
const span = insertLine[i];
|
||||
const spanLength = span.text.length;
|
||||
if (span === insertedSpan) {
|
||||
console.log(
|
||||
(character > characterCount || character === 0),
|
||||
character <= characterCount + spanLength
|
||||
);
|
||||
}
|
||||
if (!modifyingSpan && (character > characterCount || character === 0) && character <= characterCount + spanLength) {
|
||||
if (insertLine[i + 1] && insertLine[i + 1].text === '') {
|
||||
modifyingSpan = insertLine[i + 1];
|
||||
@ -2391,6 +2385,10 @@ class Text_class extends Base_tools_class {
|
||||
editor.layer = layer;
|
||||
layerEditors.set(layer, editor);
|
||||
}
|
||||
if (layer._needs_update_data) {
|
||||
delete layer._needs_update_data;
|
||||
editor.set_lines(layer.data);
|
||||
}
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user