mirror of
https://github.com/viliusle/miniPaint.git
synced 2026-02-06 15:31:53 +00:00
Merge from master
This commit is contained in:
commit
84b2e1da25
@ -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
12
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/bundle.js.map
vendored
2
dist/bundle.js.map
vendored
@ -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":""}
|
||||
@ -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": [
|
||||
|
||||
@ -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'); }
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
:root {
|
||||
/* original - default */
|
||||
--background: #575e60;
|
||||
--background: #666d6f;
|
||||
--text-color: #f4f3f3;
|
||||
--text-color-muted: #c1c1c1;
|
||||
--text-color-red: #e38282;
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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;
|
||||
|
||||
35
src/js/actions/set-object-property.js
Normal file
35
src/js/actions/set-object-property.js
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user