Merge from master

This commit is contained in:
acer 2020-12-06 19:43:53 -05:00
commit 84b2e1da25
13 changed files with 131 additions and 79 deletions

View File

@ -37,7 +37,7 @@ Edge, Emboss, Enrich, Gamma, Grains, GrayScale, Heatmap, JPG Compression, Mosaic
Tilt Shift, Vignette, Vibrance, Vintage, Blueprint, Night Vision, Pencil, also Instagram Filters: 1977, Aden, Clarendon,
Gingham, Inkwell, Lo-fi, Toaster, Valencia, X-Pro II.
- **Tools**: pencil, brush, magic wand, erase, fill, color picker, letters, crop, blur, sharpen, desaturate, clone,
borders, sprites, key-points, color to alpha, color zoom, replace color, restore alpha, content fill.
borders, sprites, key-points, color zoom, replace color, restore alpha, content fill.
- **Help**: keyboard shortcuts, translations.
## Embed

12
dist/bundle.js vendored

File diff suppressed because one or more lines are too long

2
dist/bundle.js.map vendored
View File

@ -1 +1 @@
{"version":3,"file":"bundle.js","sources":["webpack:///bundle.js"],"mappings":"AAAA;;;;;;;;;;;;;AA8uNA;;;;;;;;;;;AAogBA;;;;;;;;;;;;;;;;;;;AA4uqCA;;;;;;;;;;;;AAyKA;;;;;;;AA4wBA;;;;;;AAm8CA","sourceRoot":""}
{"version":3,"file":"bundle.js","sources":["webpack:///bundle.js"],"mappings":"AAAA;;;;;;;;;;;;;AAwvLA;;;;;;;;;;;AAogBA;;;;;;;;;;;;;;;;;;;AAmr0CA;;;;;;;;;;;;AAyKA;;;;;;;AA8zBA;;;;;;AAm8CA","sourceRoot":""}

View File

@ -1,6 +1,6 @@
{
"name": "miniPaint",
"version": "4.4.0",
"version": "4.4.2",
"author": "Vilius L.",
"description": "Online graphics editing tool lets create, edit images using HTML5 technologies.",
"keywords": [

View File

@ -284,7 +284,7 @@ body .sp-preview{
.sidebar_left .pencil:after{ background-image: url('images/icons/pencil.svg'); }
.sidebar_left .pick_color:after{ background-image: url('images/icons/pick_color.svg'); }
.sidebar_left .erase:after{ background-image: url('images/icons/erase.svg'); }
.sidebar_left .magic_erase:after{ background-image: url('../../images/icons/magic_erase.svg'); }
.sidebar_left .magic_erase:after{ background-image: url('images/icons/magic_erase.svg'); }
.sidebar_left .fill:after{ background-image: url('images/icons/fill.svg'); }
.sidebar_left .line:after{ background-image: url('images/icons/line.svg'); }
.sidebar_left .rectangle:after{ background-image: url('images/icons/rectangle.svg'); }

View File

@ -1,6 +1,6 @@
:root {
/* original - default */
--background: #575e60;
--background: #666d6f;
--text-color: #f4f3f3;
--text-color-muted: #c1c1c1;
--text-color-red: #e38282;

View File

@ -15,6 +15,7 @@ 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_object_property_action } from './set-object-property.js';
export { Set_selection_action } from './set-selection.js';
export { Stop_animation_action } from './stop-animation.js';
export { Toggle_layer_visibility_action } from './toggle-layer-visibility.js';

View File

@ -38,9 +38,9 @@ export class Insert_layer_action extends Base_action {
link: null,
x: 0,
y: 0,
width: 0,
width: null,
width_original: null,
height: 0,
height: null,
height_original: null,
visible: true,
is_vector: false,
@ -75,8 +75,8 @@ export class Insert_layer_action extends Base_action {
layer.is_vector = true;
}
if (config.layers.length == 1 && config.layer.width == 0
&& config.layer.height == 0 && config.layer.data == null) {
if (config.layers.length == 1 && (config.layer.width == 0 || config.layer.width === null)
&& (config.layer.height == 0 || config.layer.height === null) && config.layer.data == null) {
// Remove first empty layer
this.delete_layer_action = new app.Actions.Delete_layer_action(config.layer.id, true);
@ -86,9 +86,9 @@ export class Insert_layer_action extends Base_action {
if (layer.link == null) {
if (typeof layer.data == 'object') {
// Load actual image
if (layer.width == 0)
if (layer.width == 0 || layer.width === null)
layer.width = layer.data.width;
if (layer.height == 0)
if (layer.height == 0 || layer.height === null)
layer.height = layer.data.height;
layer.link = layer.data.cloneNode(true);
layer.link.onload = function () {
@ -104,9 +104,9 @@ export class Insert_layer_action extends Base_action {
layer.link = new Image();
layer.link.onload = () => {
// Update dimensions
if (layer.width == 0)
if (layer.width == 0 || layer.width === null)
layer.width = layer.link.width;
if (layer.height == 0)
if (layer.height == 0 || layer.height === null)
layer.height = layer.link.height;
if (layer.width_original == null)
layer.width_original = layer.width;
@ -133,7 +133,7 @@ export class Insert_layer_action extends Base_action {
}
if (this.settings != undefined && config.layers.length > 0
&& config.layer.width == 0 && config.layer.height == 0
&& (config.layer.width == 0 || config.layer.width === null) && (config.layer.height == 0 || config.layer.height === null)
&& config.layer.data == null && layer.type != 'image' && this.can_automate !== false) {
// Update existing layer, because it's empty
delete layer.name;

View File

@ -0,0 +1,35 @@
import app from './../app.js';
import config from './../config.js';
import { Base_action } from './base.js';
export class Set_object_property_action extends Base_action {
/**
* Sets a generic object property. I recommend against using this as it's generally a hack for edge cases.
*
* @param {string} layer_id
* @param {object} settings
*/
constructor(object, property_name, value) {
super('set_object_property', 'Set Object Property');
this.object = object;
this.property_name = property_name;
this.value = value;
this.old_value = null;
}
async do() {
super.do();
this.old_value = this.object[this.property_name];
this.object[this.property_name] = this.value;
}
async undo() {
super.undo();
this.object[this.property_name] = this.old_value;
this.old_value = null;
}
free() {
this.object = null;
}
}

View File

@ -545,11 +545,6 @@ const menuDefinition = [
{
divider: true
},
{
name: 'Color to Alpha',
ellipsis: true,
target: 'tools/color_to_alpha.color_to_alpha'
},
{
name: 'Color Zoom',
ellipsis: true,

View File

@ -60,6 +60,7 @@ class Base_layers_class {
this.last_zoom = 1;
this.auto_increment = 1;
this.stable_dimensions = [];
this.debug_rendering = false;
}
/**
@ -125,6 +126,10 @@ class Base_layers_class {
if (config.need_render == true) {
if(this.debug_rendering === true){
console.log('Rendering...');
}
if (this.last_zoom != config.ZOOM) {
//change zoom
zoomView.scaleAt(

View File

@ -8,6 +8,8 @@ import config from './../config.js';
var instance = null;
var settings_all = [];
const handle_size = 12;
const DRAG_TYPE_TOP = 1;
const DRAG_TYPE_BOTTOM = 2;
const DRAG_TYPE_LEFT = 4;
@ -145,7 +147,6 @@ class Base_selection_class {
* marks object as selected, and draws corners
*/
draw_selection() {
var _this = this;
var settings = this.find_settings();
var data = settings.data;
@ -164,8 +165,7 @@ class Base_selection_class {
return;
}
var block_size_default = 14;
block_size_default = Math.ceil(block_size_default / config.ZOOM);
var block_size_default = handle_size / config.ZOOM;
if (config.ZOOM != 1) {
x = Math.round(x);
@ -174,89 +174,94 @@ class Base_selection_class {
h = Math.round(h);
}
var block_size = block_size_default;
var half_size = Math.ceil(block_size / 2);
var corner_offset = (block_size / 2.4);
var middle_offset = (block_size / 1.9);
this.ctx.save();
this.ctx.globalAlpha = 1;
let isRotated = false;
if (data.rotate != null && data.rotate != 0) {
//rotate
isRotated = true;
this.ctx.translate(data.x + data.width / 2, data.y + data.height / 2);
this.ctx.rotate(data.rotate * Math.PI / 180);
x = Math.round(-data.width / 2);
y = Math.round(-data.height / 2);
}
var half_fix = 0.5;
//fill
if (settings.enable_background == true) {
this.ctx.fillStyle = "rgba(0, 255, 0, 0.3)";
this.ctx.fillRect(x, y, w, h);
}
const wholeLineWidth = 2 / config.ZOOM;
const halfLineWidth = wholeLineWidth / 2;
//borders
if (settings.enable_borders == true && (x != 0 || y != 0 || w != config.WIDTH || h != config.HEIGHT)) {
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "rgba(0, 128, 0, 0.5)";
this.ctx.strokeRect(x + half_fix, y + half_fix, w, h);
this.ctx.lineWidth = wholeLineWidth;
this.ctx.strokeStyle = 'rgb(255, 255, 255)';
this.ctx.strokeRect(x - halfLineWidth, y - halfLineWidth, w + wholeLineWidth, h + wholeLineWidth);
this.ctx.lineWidth = halfLineWidth;
this.ctx.strokeStyle = 'rgb(0, 0, 0)';
this.ctx.strokeRect(x - wholeLineWidth, y - wholeLineWidth, w + (wholeLineWidth * 2), h + (wholeLineWidth * 2));
}
const hitsLeftEdge = isRotated ? false : x < handle_size;
const hitsTopEdge = isRotated ? false : y < handle_size;
const hitsRightEdge = isRotated ? false : x + w > config.WIDTH - handle_size;
const hitsBottomEdge = isRotated ? false : y + h > config.HEIGHT - handle_size;
//draw corners
if (settings.enable_controls == true && Math.abs(w) > block_size * 2 && Math.abs(h) > block_size * 2) {
corner(x - half_size, y - half_size, 0, 0, DRAG_TYPE_LEFT | DRAG_TYPE_TOP);
corner(x + w + half_size, y - half_size, -1, 0, DRAG_TYPE_RIGHT | DRAG_TYPE_TOP);
corner(x - half_size, y + h + half_size, 0, -1, DRAG_TYPE_LEFT | DRAG_TYPE_BOTTOM);
corner(x + w + half_size, y + h + half_size, -1, -1, DRAG_TYPE_RIGHT | DRAG_TYPE_BOTTOM);
}
if (settings.enable_controls == true) {
//draw centers
if (Math.abs(w) > block_size * 5) {
corner(x + w / 2 - block_size / 2, y - half_size, 0, 0, DRAG_TYPE_TOP);
corner(x + w / 2 - block_size / 2, y + h + half_size, 0, -1, DRAG_TYPE_BOTTOM);
}
if (Math.abs(h) > block_size * 5) {
corner(x - half_size, y + h / 2 - block_size / 2, 0, 0, DRAG_TYPE_LEFT);
corner(x + w + half_size, y + h / 2 - block_size / 2, -1, 0, DRAG_TYPE_RIGHT);
}
}
function corner(x, y, dx, dy, drag_type) {
var block_size = Math.round(block_size_default / 2) * 2;
x = Math.round(x);
y = Math.round(y);
var corner = (x, y, dx, dy, drag_type) => {
// var block_size = Math.round(block_size_default / 2) * 2;
var angle = 0;
if (settings.data.rotate != null && settings.data.rotate > 0) {
if (settings.data.rotate != null && settings.data.rotate != 0) {
angle = settings.data.rotate;
}
//register position
_this.selected_obj_positions[drag_type] = {
this.selected_obj_positions[drag_type] = {
x: x + dx * block_size,
y: y + dy * block_size,
size: block_size,
};
if (settings.enable_controls == false || angle > 0) {
_this.ctx.strokeStyle = "rgba(0, 128, 0, 0.4)";
_this.ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
if (settings.enable_controls == false || angle != 0) {
this.ctx.strokeStyle = "rgba(0, 0, 0, 0.4)";
this.ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
}
else {
_this.ctx.strokeStyle = "#008000";
_this.ctx.fillStyle = "#ffffff";
this.ctx.strokeStyle = "#000000";
this.ctx.fillStyle = "#ffffff";
}
//borders
_this.ctx.lineWidth = 1;
if (config.ZOOM < 1)
_this.ctx.lineWidth = 2;
_this.ctx.beginPath();
_this.ctx.arc(
x + dx * block_size + half_size,
y + dy * block_size + half_size,
half_size, 0, 2 * Math.PI);
_this.ctx.fill();
_this.ctx.stroke();
this.ctx.lineWidth = wholeLineWidth;
this.ctx.beginPath();
this.ctx.arc(x + dx * block_size, y + dy * block_size, block_size / 2, 0, 2 * Math.PI);
this.ctx.fill();
this.ctx.stroke();
};
if (settings.enable_controls == true) {
corner(x - corner_offset - wholeLineWidth, y - corner_offset - wholeLineWidth, hitsLeftEdge ? 0.5 : 0, hitsTopEdge ? 0.5 : 0, DRAG_TYPE_LEFT | DRAG_TYPE_TOP);
corner(x + w + corner_offset + wholeLineWidth, y - corner_offset - wholeLineWidth, hitsRightEdge ? -0.5 : 0, hitsTopEdge ? 0.5 : 0, DRAG_TYPE_RIGHT | DRAG_TYPE_TOP);
corner(x - corner_offset - wholeLineWidth, y + h + corner_offset + wholeLineWidth, hitsLeftEdge ? 0.5 : 0, hitsBottomEdge ? -0.5 : 0, DRAG_TYPE_LEFT | DRAG_TYPE_BOTTOM);
corner(x + w + corner_offset + wholeLineWidth, y + h + corner_offset + wholeLineWidth, hitsRightEdge ? -0.5 : 0, hitsBottomEdge ? -0.5 : 0, DRAG_TYPE_RIGHT | DRAG_TYPE_BOTTOM);
}
if (settings.enable_controls == true) {
//draw centers
if (Math.abs(w) > block_size * 5) {
corner(x + w / 2, y - middle_offset - wholeLineWidth, 0, hitsTopEdge ? 0.5 : 0, DRAG_TYPE_TOP);
corner(x + w / 2, y + h + middle_offset + wholeLineWidth, 0, hitsBottomEdge ? -0.5 : 0, DRAG_TYPE_BOTTOM);
}
if (Math.abs(h) > block_size * 5) {
corner(x - middle_offset - wholeLineWidth, y + h / 2, hitsLeftEdge ? 0.5 : 0, 0, DRAG_TYPE_LEFT);
corner(x + w + middle_offset + wholeLineWidth, y + h / 2, hitsRightEdge ? -0.5 : 0, 0, DRAG_TYPE_RIGHT);
}
}
//restore
@ -317,7 +322,7 @@ class Base_selection_class {
const is_drag_type_bottom = Math.floor(drag_type / DRAG_TYPE_BOTTOM) % 2 === 1;
if (e.buttons == 1 || typeof e.buttons == "undefined") {
// Do transformations
// Do transformations
var dx = Math.round(mouse.x - mouse.click_x);
var dy = Math.round(mouse.y - mouse.click_y);
var width = this.click_details.width + dx;
@ -386,8 +391,8 @@ class Base_selection_class {
for (let current_drag_type in this.selected_obj_positions) {
const position = this.selected_obj_positions[current_drag_type];
if (mouse.x >= position.x && mouse.x <= position.x + position.size
&& mouse.y >= position.y && mouse.y <= position.y + position.size
if (mouse.x >= position.x - position.size / 2 && mouse.x <= position.x + position.size / 2
&& mouse.y >= position.y - position.size / 2 && mouse.y <= position.y + position.size / 2
) {
//match
if (event_type == 'mousedown') {

View File

@ -315,6 +315,8 @@ class File_open_class {
open_template_test(){
var _this = this;
this.Base_layers.debug_rendering = true;
window.fetch("images/test-collection.json").then(function(response) {
return response.json();
@ -391,7 +393,7 @@ class File_open_class {
img.src = url;
}
load_json(data) {
async load_json(data) {
var json;
if(typeof data == 'string')
json = JSON.parse(data);
@ -446,9 +448,15 @@ class File_open_class {
new app.Actions.Prepare_canvas_action('do'),
);
var max_id_order = 0;
for (var i in json.layers) {
var value = json.layers[i];
if(value.id > max_id_order)
max_id_order = value.id;
if(typeof value.order != undefined && value.order > max_id_order)
max_id_order = value.order;
if (value.type == 'image') {
//add image data
value.link = null;
@ -467,7 +475,10 @@ class File_open_class {
new app.Actions.Select_layer_action(json.info.layer_active, true)
);
}
app.State.do_action(
actions.push(
new app.Actions.Set_object_property_action(this.Base_layers, 'auto_increment', max_id_order + 1)
);
await app.State.do_action(
new app.Actions.Bundle_action('open_json_file', 'Open JSON File', actions)
);
}