#87 - Layers.insert can be async (example in /examples/add-edit-imgData.html),

better error messages
This commit is contained in:
Vilius 2018-02-02 22:07:37 +02:00
parent 80869ed818
commit 0326654d8b
12 changed files with 290 additions and 142 deletions

18
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":"dist/bundle.js","sources":["webpack:///dist/bundle.js"],"mappings":"AAAA;AAusCA;;;;;;;;;;;;;AAquKA;;;;;;;;;;AAuhBA;;;;;;;;;;;;;;;;;;AA4mxBA;;;;;;;;;;;AAyKA;;;;;;AA2uBA","sourceRoot":""}
{"version":3,"file":"dist/bundle.js","sources":["webpack:///dist/bundle.js"],"mappings":"AAAA;AAuzCA;;;;;;;;;;;;;AAgkNA;;;;;;;;;;AAgfA;;;;;;;;;;;;;;;;;;AAspgCA;;;;;;;;;;;AAyKA;;;;;;AA2uBA","sourceRoot":""}

View File

@ -0,0 +1,76 @@
<html>
<body style="margin:0;">
<iframe id="myFrame" style="width:100%;height:100vh;border:0;" src="../"></iframe>
<script>
window.addEventListener('load', function (e) {
draw_various();
}, false);
async function draw_various() {
var Layers = document.getElementById('myFrame').contentWindow.Layers;
//add layer
var canvas = document.createElement('canvas');
canvas.width = 50;
canvas.height = 50;
var ctx = canvas.getContext("2d");
cross_X(ctx, 25, 25);
var params = {
type: 'image',
data: canvas.toDataURL("image/png"),
x: 50,
y: 50,
width: canvas.width,
height: canvas.height,
};
await Layers.insert(params);
//add new layer
var canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 400;
var ctx = canvas.getContext("2d");
cross_X(ctx, 200, 200, null, '#00cc00');
var params = {
type: 'image',
data: canvas.toDataURL("image/png"),
width: canvas.width,
height: canvas.height,
};
await Layers.insert(params);
//update last layer
var canvas = Layers.convert_layer_to_canvas(null, true); //no trim
var ctx = canvas.getContext("2d");
cross_X(ctx, 300, 300, null, '#00cc00');
Layers.update_layer_image(canvas);
//also update layer
var link = Layers.get_layer();
link.x = parseInt(canvas.dataset.x);
link.y = parseInt(canvas.dataset.y);
link.width = canvas.width;
link.height = canvas.height;
}
function cross_X(ctx, x, y, size = 20, col = '#ff0000') {
if(size == null)
size = 20;
x = parseFloat(x);
y = parseFloat(y);
size = parseInt(size);
var lw = parseInt(5);
ctx.beginPath();
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.lineWidth = lw;
ctx.strokeStyle = col;
ctx.stroke();
ctx.moveTo(x + size, y - size);
ctx.lineTo(x - size, y + size);
ctx.lineWidth = lw;
ctx.strokeStyle = col;
ctx.stroke();
}
</script>

View File

@ -1,7 +1,7 @@
<html>
<body style="margin:0;">
<iframe id="myFrame" style="width:100%;height:70vh;" src="../"></iframe>
<iframe id="myFrame" style="width:100%;height:70vh;border:0;" src="../"></iframe>
<div style="height:20vh;margin:10px;">
Click on image to edit.
@ -45,11 +45,20 @@ function my_save(){
tempCanvas.width = dim.width;
tempCanvas.height = dim.height;
Layers.convert_layers_to_canvas(tempCtx);
tempCanvas.toBlob(function(blob) {
//image data here
alert('Data length: ' + blob.size);
console.log(blob);
});
if(is_edge_or_ie() == false){
//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);
}
}
function my_update(){
@ -74,4 +83,15 @@ function my_update(){
window.onload = function () {
//open_image(document.getElementById('testImage')); //uncomment me
};
//if IE 11 or Edge
function is_edge_or_ie() {
//ie11
if( !(window.ActiveXObject) && "ActiveXObject" in window )
return true;
//edge
if( navigator.userAgent.indexOf('Edge/') != -1 )
return true;
return false;
}
</script>

36
package-lock.json generated
View File

@ -1321,6 +1321,39 @@
"babel-types": "6.25.0"
}
},
"babel-polyfill": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
"requires": {
"babel-runtime": "6.26.0",
"core-js": "2.5.3",
"regenerator-runtime": "0.10.5"
},
"dependencies": {
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
"requires": {
"core-js": "2.5.3",
"regenerator-runtime": "0.11.1"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
}
}
},
"core-js": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
"integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4="
}
}
},
"babel-preset-env": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
@ -7150,8 +7183,7 @@
"regenerator-runtime": {
"version": "0.10.5",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
"dev": true
"integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
},
"regenerator-transform": {
"version": "0.10.1",

View File

@ -33,6 +33,7 @@
},
"dependencies": {
"alertifyjs": "^1.11.0",
"babel-polyfill": "^6.26.0",
"blueimp-canvas-to-blob": "^3.14.0",
"exif-js": "^2.3.0",
"file-saver": "^1.3.3",

View File

@ -281,129 +281,138 @@ class Base_layers_class {
* @param {array} settings
* @param {boolean} can_automate
*/
insert(settings, can_automate = true) {
async insert(settings, can_automate = true) {
var _this = this;
var need_autoresize = false;
return new Promise(function(resolve, reject) {
var resolvable = false;
var need_autoresize = false;
//create empty layer
var layer = {
id: this.auto_increment,
parent_id: 0,
name: this.Helper.ucfirst(config.TOOL.name) + ' #' + this.auto_increment,
type: null,
link: null,
x: 0,
y: 0,
width: 0,
width_original: null,
height: 0,
height_original: null,
visible: true,
opacity: 100,
order: this.auto_increment,
composition: 'source-over',
rotate: 0,
data: null,
params: {},
status: null,
color: config.COLOR,
filters: [],
render_function: null,
};
//default data
var layer = {
id: _this.auto_increment,
parent_id: 0,
name: _this.Helper.ucfirst(config.TOOL.name) + ' #' + _this.auto_increment,
type: null,
link: null,
x: 0,
y: 0,
width: 0,
width_original: null,
height: 0,
height_original: null,
visible: true,
opacity: 100,
order: _this.auto_increment,
composition: 'source-over',
rotate: 0,
data: null,
params: {},
status: null,
color: config.COLOR,
filters: [],
render_function: null,
};
//add data
for (var i in settings) {
if (typeof layer[i] == "undefined") {
alertify.error('Error: wrong key: ' + i);
continue;
}
layer[i] = settings[i];
}
//if image - prepare
if (layer.type == 'image') {
if (config.layers.length == 1 && config.layer.width == 0
&& config.layer.height == 0 && config.layer.data == null) {
//remove first empty layer?
this.delete(config.layer.id, true);
}
if (layer.link == null) {
if (typeof layer.data == 'object') {
//load actual image
if (layer.width == 0)
layer.width = layer.data.width;
if (layer.height == 0)
layer.height = layer.data.height;
layer.link = layer.data.cloneNode(true);
layer.data = null;
need_autoresize = true;
//build data
for (var i in settings) {
if (typeof layer[i] == "undefined") {
alertify.error('Error: wrong key: ' + i);
continue;
}
else if (typeof layer.data == 'string') {
//try loading as imageData
layer.link = new Image();
layer.link.onload = function () {
//update dimensions
layer[i] = settings[i];
}
//prepare image
if (layer.type == 'image') {
if (config.layers.length == 1 && config.layer.width == 0
&& config.layer.height == 0 && config.layer.data == null) {
//remove first empty layer?
_this.delete(config.layer.id, true);
}
if (layer.link == null) {
if (typeof layer.data == 'object') {
//load actual image
if (layer.width == 0)
layer.width = layer.link.width;
layer.width = layer.data.width;
if (layer.height == 0)
layer.height = layer.link.height;
if (layer.width_original == null)
layer.width_original = layer.width;
if (layer.height_original == null)
layer.height_original = layer.height;
//free data
layer.height = layer.data.height;
layer.link = layer.data.cloneNode(true);
layer.data = null;
_this.autoresize(layer.width, layer.height, layer.id, can_automate);
_this.render();
need_autoresize = true;
}
else if (typeof layer.data == 'string') {
//try loading as imageData
resolvable = true;
layer.link = new Image();
layer.link.onload = function () {
config.need_render = true;
//update dimensions
if (layer.width == 0)
layer.width = layer.link.width;
if (layer.height == 0)
layer.height = layer.link.height;
if (layer.width_original == null)
layer.width_original = layer.width;
if (layer.height_original == null)
layer.height_original = layer.height;
//free data
layer.data = null;
_this.autoresize(layer.width, layer.height, layer.id, can_automate);
_this.render();
layer.link.onload = function () {
config.need_render = true;
};
resolve(true);
};
};
layer.link.src = layer.data;
}
else {
alertify.error('Error: can not load image.');
layer.link.src = layer.data;
}
else {
alertify.error('Error: can not load image.');
}
}
}
}
if (settings != undefined && config.layers.length > 0
&& config.layer.width == 0 && config.layer.height == 0
&& config.layer.data == null && layer.type != 'image' && can_automate !== false) {
//update existing empty
for (var i in layer) {
if (i == 'id')
continue;
if (i == 'name')
continue;
if (i == 'order')
continue;
config.layer[i] = layer[i];
if (settings != undefined && config.layers.length > 0
&& config.layer.width == 0 && config.layer.height == 0
&& config.layer.data == null && layer.type != 'image' && can_automate !== false) {
//update existing layer, because its empty
for (var i in layer) {
if (i == 'id')
continue;
if (i == 'name')
continue;
if (i == 'order')
continue;
config.layer[i] = layer[i];
}
}
}
else {
//new layer
config.layers.push(layer);
config.layer = this.get_layer(this.auto_increment);
this.auto_increment++;
else {
//create new layer
config.layers.push(layer);
config.layer = _this.get_layer(layer.id);
_this.auto_increment++;
if (config.layer == null) {
config.layer = config.layers[0];
if (config.layer == null) {
config.layer = config.layers[0];
}
}
}
if (layer.id >= this.auto_increment)
this.auto_increment = layer.id + 1;
if (layer.id >= _this.auto_increment)
_this.auto_increment = layer.id + 1;
if (need_autoresize == true) {
this.autoresize(config.layer.width, config.layer.height);
}
if (need_autoresize == true) {
_this.autoresize(config.layer.width, config.layer.height);
}
this.render();
this.Base_gui.GUI_layers.render_layers();
_this.render();
_this.Base_gui.GUI_layers.render_layers();
if(resolvable == false){
resolve(true);
}
});
}
/**
@ -453,7 +462,7 @@ class Base_layers_class {
function myCallback() {
_this.Base_gui.GUI_preview.zoom_auto();
}
}
}
}
/**
@ -463,11 +472,15 @@ class Base_layers_class {
* @returns {object}
*/
get_layer(id) {
if(id == undefined){
id = config.layer.id;
}
for (var i in config.layers) {
if (config.layers[i].id == id) {
return config.layers[i];
}
}
alertify.error('Error: can not find layer with id:' + id);
return null;
}
@ -787,12 +800,14 @@ class Base_layers_class {
/**
* exports (active) layer to canvas for saving
*
* @param {int} layer_id
* @param {boolean} actual_area if false, all visible and trimed area will be used
* @param {int} layer_id or current layer by default
* @param {boolean} actual_area used for resized image. Default is false.
* @param {boolean} can_trim default is true
* @returns {canvas}
*/
convert_layer_to_canvas(layer_id, actual_area = false, can_trim) {
convert_layer_to_canvas(layer_id, actual_area = false, can_trim) {
if(actual_area == null)
actual_area = false;
if (layer_id == null)
layer_id = config.layer.id;
var link = this.get_layer(layer_id);
@ -825,12 +840,12 @@ class Base_layers_class {
if (trim_info.left > 0 || trim_info.top > 0 || trim_info.right > 0 || trim_info.bottom > 0) {
offset_x = trim_info.left;
offset_y = trim_info.top;
this.Helper.change_canvas_size(canvas,
canvas.width - trim_info.left - trim_info.right,
canvas.height - trim_info.top - trim_info.bottom,
offset_x,
offset_y);
var w = canvas.width - trim_info.left - trim_info.right;
var h = canvas.height - trim_info.top - trim_info.bottom;
if(w > 1 && h > 1) {
this.Helper.change_canvas_size(canvas, w, h, offset_x, offset_y);
}
}
}
@ -851,8 +866,10 @@ class Base_layers_class {
layer_id = config.layer.id;
var link = this.get_layer(layer_id);
if (link.type != 'image')
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)

View File

@ -236,7 +236,7 @@ class Base_selection_class {
if (e.type == 'mousedown' && config.mouse.valid == false || settings.enable_controlls == false) {
return;
}
if (settings.data.rotate != null && settings.data.rotate > 0) {
if (settings.data != null && settings.data.rotate != null && settings.data.rotate > 0) {
//controls on rotated object disabled
return;
}

View File

@ -68,7 +68,7 @@ class Base_tools_class {
set_mouse_info(event) {
if (this.save_mouse !== true) {
//not maint
//not main
return false;
}
if (event != undefined && event.changedTouches) {

View File

@ -5,6 +5,7 @@
import config from './../../config.js';
import Helper_class from './../../libs/helpers.js';
import alertify from './../../../../node_modules/alertifyjs/build/alertify.min.js';
var Helper = new Helper_class();
@ -138,17 +139,17 @@ class GUI_colors_class {
var value = parseInt(object.value);
if (isNaN(value) || value < 0) {
object.value = 0;
return false;
alertify.error('Error: bad rgb value.');
}
if (value > 255) {
object.value = 255;
return false;
alertify.error('Error: bad rgb value.');
}
config.COLOR = Helper.rgbToHex(
document.getElementById("rgb_r").value,
document.getElementById("rgb_g").value,
document.getElementById("rgb_b").value
);
);
config.ALPHA = document.getElementById("rgb_a").value;
this.render_colors(object.id);
@ -162,7 +163,7 @@ class GUI_colors_class {
}
if (value > 255) {
object.value = 255;
return false;
alertify.error('Error: bad hsl value.');
}
var rgb = Helper.hslToRgb(
document.getElementById("hsl_h").value / 255,

View File

@ -16,7 +16,7 @@ import Base_layers_class from './core/base-layers.js';
import Base_tools_class from './core/base-tools.js';
import Base_state_class from './core/base-state.js';
window.onload = function (e) {
window.addEventListener('load', function (e) {
//initiate app
var Layers = new Base_layers_class();
var Base_tools = new Base_tools_class(true);
@ -33,4 +33,4 @@ window.onload = function (e) {
GUI.render_main_gui();
Layers.init();
};
}, false);

View File

@ -3,6 +3,7 @@ var path = require('path');
module.exports = {
entry: [
'babel-polyfill',
'./src/js/main.js',
],
output: {