mirror of
https://github.com/viliusle/miniPaint.git
synced 2026-02-06 13:51:51 +00:00
update
This commit is contained in:
parent
e4516734c7
commit
70e5ad7862
14
README.md
14
README.md
@ -2,13 +2,17 @@ miniPaint - Online graphics editing tool using HTML5.
|
||||
|
||||
Demo: http://viliusle.github.io/miniPaint/
|
||||
|
||||
Built using HTML5, JavaScript, Canvas, Drag and Drop, Files API, Offline Support.
|
||||
|
||||
Online graphics editing tool use HTML5 technologies like Canvas, Offline support,
|
||||
Drag and Drop.
|
||||
|
||||
Features: open, edit, save images, various drawing tools like Magic Wand tool, Clone tool,
|
||||
erase, fill, colour picker, colour selector, layers, pencil, brush, shapes, trim, flip,
|
||||
rotate, resize, Lanczos resample, transparency, zoom, grid, EXIF data, crop,
|
||||
export/import layers data, paste from clipboard, 25 various filters including blur, Tilt Shift.
|
||||
erase, fill, color picker, colour selector, layers, pencil, brush, shapes, trim, flip,
|
||||
rotate, resize, transparency, zoom, grid, EXIF data, crop, export/import layers data,
|
||||
paste from clipboard, 30 various filters including blur, Tilt Shift, perspective,
|
||||
denoise, vignette, auto colorize, auto adjust colors, decrease color deapth, histogram,
|
||||
gradients, fast Hermite resample.
|
||||
|
||||
Key features: layers, transparency, offline graphics editing.
|
||||
|
||||
@ -16,8 +20,8 @@ It works in all modern browsers that support HTML5.
|
||||
|
||||
Used libraries:
|
||||
JQuery http://jquery.com/
|
||||
Menu http://blog.geotitles.com/2011/09/creating-the-new-top-black-bar-found-in-google-and-all-its-products/
|
||||
Google Menu http://blog.geotitles.com/2011/09/creating-the-new-top-black-bar-found-in-google-and-all-its-products/
|
||||
ImageFilters.js https://github.com/arahaya/ImageFilters.js
|
||||
glfx.js http://evanw.github.io/glfx.js/
|
||||
html5slider.js https://github.com/fryn/html5slider
|
||||
exif.js https://github.com/jseidelin/exif-js
|
||||
harmony.js http://ricardocabello.com/blog/post/689
|
||||
|
||||
BIN
img/Thumbs.db
BIN
img/Thumbs.db
Binary file not shown.
BIN
img/all.png
BIN
img/all.png
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
img/colors.png
BIN
img/colors.png
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
46
index.html
46
index.html
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<title>miniPaint - online image editor</title>
|
||||
<meta name="description" content="miniPaint is free online image editor using HTML5. Edit, adjust your images, add effects online in your browser, without installing anything..." />
|
||||
<meta name="keywords" content="photo, image, picture, free, edit, html5, online, photoshop, gimp, effects, sharpen, blur, magic wand tool, clone tool, rotate, resize, photoshop online, online tools, tilt shift" />
|
||||
<meta name="keywords" content="photo, image, picture, transparent, layers, free, edit, html5, canvas, javascript, online, photoshop, gimp, effects, sharpen, blur, magic wand tool, clone tool, rotate, resize, photoshop online, online tools, tilt shift, auto colorize" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="styles/styles.css" />
|
||||
<link rel="stylesheet" type="text/css" media="print" href="styles/print.css" />
|
||||
@ -18,7 +18,14 @@
|
||||
</div>
|
||||
<div id="canvas_container">
|
||||
<div id="menu_left">
|
||||
<div id="menu_left_container"></div>
|
||||
<div id="menu_left_container">
|
||||
<noscript>
|
||||
Select object tool, Select area tool, Magic Wand Tool,
|
||||
Erase, Fill, Pick Color, Pencil, Draw line, Draw letters,
|
||||
Draw rectangle, Draw circle, Brush, Blur tool, Sharpen tool,
|
||||
Clone tool, Gradient
|
||||
</noscript>
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
<div id="main_colour" onclick="TOOLS.toggle_color_select();"></div>
|
||||
<div style="margin-top:10px;padding:3px 0px 3px 3px;" class="block" id="all_colors"></div>
|
||||
@ -27,7 +34,8 @@
|
||||
<div id="main_colour_rgb">
|
||||
Red: <input id="rgb_r" onKeyUp="TOOLS.set_color_rgb(this, 'r')" type="text" value="255" /><br />
|
||||
Green: <input id="rgb_g" onKeyUp="TOOLS.set_color_rgb(this, 'g')" type="text" value="255" /><br />
|
||||
Blue: <input id="rgb_b" onKeyUp="TOOLS.set_color_rgb(this, 'b')" type="text" value="255" />
|
||||
Blue: <input id="rgb_b" onKeyUp="TOOLS.set_color_rgb(this, 'b')" type="text" value="255" /><br />
|
||||
Alpha: <input id="rgb_a" onKeyUp="TOOLS.set_color_rgb(this, 'a')" type="text" value="255" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="block" id="info"></div>
|
||||
@ -41,7 +49,7 @@
|
||||
<input onclick="DRAW.zoom(+1);" style="width:30px;" class="layer_add" type="button" value="+" />
|
||||
<b>Zoom: </b><span id="zoom_nr">100</span>%
|
||||
<br />
|
||||
<input id="zoom_range" type="range" value="100" min="50" max="1000" step="50" oninput="DRAW.zoom(this.value);" />
|
||||
<input style="width:95%;" id="zoom_range" type="range" value="100" min="50" max="1000" step="50" oninput="DRAW.zoom(this.value);" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="layers_base">
|
||||
@ -78,7 +86,6 @@
|
||||
<a href="#">Edit</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['edit_undo']);" href="#">Undo</a></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_redo']);" href="#">Redo</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_cut']);" href="#">Cut</a></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_copy']);" href="#">Copy</a></li>
|
||||
@ -91,6 +98,7 @@
|
||||
<li>
|
||||
<a href="#">Image</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['image_information']);" href="#">Information...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_size']);" href="#">Size...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_trim']);" href="#">Trim</a>
|
||||
<li><a onclick="MENU.do_menu(['image_crop']);" href="#">Crop Selection</a>
|
||||
@ -101,10 +109,12 @@
|
||||
<li><a onclick="MENU.do_menu(['image_rotate']);" href="#">Custom Rotation...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_vflip']);" href="#">Vertical Flip</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_hflip']);" href="#">Horizontal Flip</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_histogram']);" href="#">Histogram...</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['image_colors']);" href="#">Color corrections...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_auto_adjust']);" href="#">Auto adjust colors</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_decrease_colors']);" href="#">Decrease color depth...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_negative']);" href="#">Negative</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_exif']);" href="#">EXIF info...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_grid']);" href="#">Grid...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -119,19 +129,13 @@
|
||||
<li><a onclick="MENU.do_menu(['layer_move_up']);" href="#">Move Up</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_move_down']);" href="#">Move Down</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_opacity']);" href="#">Opacity...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_colors']);" href="#">Color corrections...</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_rotate_left']);" href="#">Rotate Left</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_rotate_right']);" href="#">Rotate Right</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_rotate']);" href="#">Custom Rotation...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_vflip']);" href="#">Vertical Flip</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_hflip']);" href="#">Horizontal Flip</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_trim']);" href="#">Trim</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_resize']);" href="#">Resize...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_negative']);" href="#">Negative</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_clear']);" href="#">Clear</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_differences']);" href="#">Differences Down</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_sprites']);" href="#">Generate sprites</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_merge_down']);" href="#">Merge Down</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_flatten']);" href="#">Flatten Image</a></li>
|
||||
|
||||
@ -140,14 +144,19 @@
|
||||
<li>
|
||||
<a href="#">Effects</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['effects_bw']);" href="#">Black and White</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_bw']);" href="#">Black and White...</a>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['effects_BoxBlur']);" href="#">Blur-Box...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_GaussianBlur']);" href="#">Blur-Gaussian...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_StackBlur']);" href="#">Blur-Stack...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_zoomblur']);" href="#">Blur-Zoom...</a>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['effects_BrightnessContrast']);" href="#">Brightness Contrast...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_bulge_pinch']);" href="#">Bulge/Pinch...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Channels']);" href="#">Channels...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_ColorTransformFilter']);" href="#">Color Transform...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_colorize']);" href="#">Colorize...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['effects_denoise']);" href="#">Denoise...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Desaturate']);" href="#">Desaturate</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Dither']);" href="#">Dither...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_dot_screen']);" href="#">Dot Screen...</a>
|
||||
@ -160,17 +169,20 @@
|
||||
<li><a onclick="MENU.do_menu(['effects_Mosaic']);" href="#">Mosaic...</a>
|
||||
<li><a onclick="MENU.do_menu(['layer_negative']);" href="#">Negative</a></li>
|
||||
<li><a onclick="MENU.do_menu(['effects_Oil']);" href="#">Oil...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_perspective']);" href="#">Perspective...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Posterize']);" href="#">Posterize...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Sepia']);" href="#">Sepia</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Sharpen']);" href="#">Sharpen...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Solarize']);" href="#">Solarize</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_tilt_shift']);" href="#">Tilt Shift...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_vignette']);" href="#">Vignette...</a>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Help</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['help_shortcuts']);" href="#">Keyboard Shortcuts...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['help_credits']);" href="#">Credits...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['help_about']);" href="#">About...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -183,16 +195,16 @@
|
||||
<script src="libs/menu.js"></script>
|
||||
<script src="libs/imagefilters.js"></script>
|
||||
<script src="libs/glfx.js"></script>
|
||||
<script src="libs/html5slider.js"></script>
|
||||
<script src="libs/exif.js"></script>
|
||||
<script src="libs/exif-binaryajax.js"></script>
|
||||
<script src="libs/harmony.js"></script>
|
||||
|
||||
<script src="js/helpers.js"></script>
|
||||
<script src="js/popup.js"></script>
|
||||
<script src="js/controlls.js"></script>
|
||||
<script src="js/tools.js"></script>
|
||||
<script src="js/draw.js"></script>
|
||||
<script src="js/layers.js"></script>
|
||||
<script src="js/helpers.js"></script>
|
||||
<script src="js/menu_actions.js"></script>
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
181
js/controlls.js
181
js/controlls.js
@ -22,15 +22,19 @@ function CONTROLLS_CLASS(){
|
||||
this.ZOOM_X = 0;
|
||||
this.ZOOM_Y = 0;
|
||||
this.mini_rect_data = { w: 0, h:0 };
|
||||
|
||||
this.isDrag = false;
|
||||
this.sr_size = 8; //selected area resize rects size
|
||||
var autosize = true;
|
||||
var isDrag = false;
|
||||
var mouse_click_x = false;
|
||||
var mouse_click_y = false;
|
||||
var mouse_x_move_last = false;
|
||||
var mouse_y_move_last = false;
|
||||
var resize_all = false;
|
||||
var mouse_click_valid = false;
|
||||
var last_pop_click = [0, 0];
|
||||
var popup_pos_top = 0;
|
||||
var popup_pos_left = 0;
|
||||
var popup_dragable = false;
|
||||
|
||||
//keyboard actions
|
||||
this.on_keyboard_action = function(event){
|
||||
@ -75,6 +79,13 @@ function CONTROLLS_CLASS(){
|
||||
else if(k == 27){
|
||||
if(POP != undefined && POP.active == true)
|
||||
POP.hide();
|
||||
delete TOOLS.last_line_x;
|
||||
delete TOOLS.last_line_y;
|
||||
if(TOOLS.select_data != false){
|
||||
TOOLS.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
TOOLS.select_square_action = '';
|
||||
}
|
||||
}
|
||||
//z - undo
|
||||
else if(k == 90){
|
||||
@ -105,12 +116,9 @@ function CONTROLLS_CLASS(){
|
||||
MENU.rotate_resize_doc(270, WIDTH, HEIGHT);
|
||||
MENU.rotate_layer({angle: 270}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//r - rotate right
|
||||
else if(k == 82){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_resize_doc(90, WIDTH, HEIGHT);
|
||||
MENU.rotate_layer({angle: 90}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//r - resize
|
||||
else if(k == 82)
|
||||
MENU.resize_box();
|
||||
//grid
|
||||
else if(k==71){
|
||||
if(MAIN.grid == false)
|
||||
@ -125,6 +133,7 @@ function CONTROLLS_CLASS(){
|
||||
MAIN.save_state();
|
||||
canvas_active().clearRect(TOOLS.select_data.x, TOOLS.select_data.y, TOOLS.select_data.w, TOOLS.select_data.h);
|
||||
TOOLS.select_data = false;
|
||||
TOOLS.select_square_action = '';
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
}
|
||||
@ -133,7 +142,8 @@ function CONTROLLS_CLASS(){
|
||||
CON.shift_pressed = true;
|
||||
//ctrl
|
||||
else if(k==17){
|
||||
CON.ctrl_pressed = true;
|
||||
if(CON.ctrl_pressed == false)
|
||||
CON.ctrl_pressed = true;
|
||||
if (!window.Clipboard)
|
||||
pasteCatcher.focus();
|
||||
}
|
||||
@ -167,6 +177,13 @@ function CONTROLLS_CLASS(){
|
||||
else if(k==67){
|
||||
if(CON.ctrl_pressed == true && TOOLS.select_data != false)
|
||||
MENU.copy_to_clipboard();
|
||||
else if(CON.ctrl_pressed == false){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(3);
|
||||
var param2 = parseInt(30);
|
||||
DRAW.colorize(canvas_active(), WIDTH, HEIGHT, param1, param2, true);
|
||||
DRAW.zoom();
|
||||
}
|
||||
}
|
||||
//v
|
||||
else if(k==86){
|
||||
@ -174,6 +191,21 @@ function CONTROLLS_CLASS(){
|
||||
if(CON.ctrl_pressed == true)
|
||||
MENU.paste();
|
||||
}
|
||||
//f - fix images
|
||||
else if(k==70){
|
||||
MAIN.save_state();
|
||||
DRAW.auto_adjust(canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//h - histogram
|
||||
else if(k==72){
|
||||
TOOLS.histogram();
|
||||
}
|
||||
//-
|
||||
else if(k==109)
|
||||
DRAW.zoom(-1);
|
||||
//+
|
||||
else if(k==107)
|
||||
DRAW.zoom(+1);
|
||||
|
||||
DRAW.zoom();
|
||||
return true;
|
||||
@ -191,40 +223,48 @@ function CONTROLLS_CLASS(){
|
||||
else if(k==18)
|
||||
CON.alt_pressed = false;
|
||||
}
|
||||
// mouse_x, mouse_y, event.pageX, event.pageY
|
||||
this.get_mouse_position = function(event){
|
||||
var valid = true;
|
||||
if(event.offsetX) {
|
||||
mouse_x = event.offsetX;
|
||||
mouse_y = event.offsetY;
|
||||
mouse_rel_x = event.offsetX;
|
||||
mouse_rel_y = event.offsetY;
|
||||
}
|
||||
else if(event.layerX) {
|
||||
mouse_x = event.layerX;
|
||||
mouse_y = event.layerY;
|
||||
mouse_rel_x = event.layerX;
|
||||
mouse_rel_y = event.layerY;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
if(event.target.id != "canvas_preview"){
|
||||
if((mouse_x < 200 || mouse_y < 200) && event.target.id != "canvas_front"){
|
||||
mouse_x = mouse_x - 109;
|
||||
mouse_y = mouse_y - 34;
|
||||
valid = false;
|
||||
}
|
||||
else if((mouse_x > WIDTH+1 || mouse_y > HEIGHT+1) && event.target.id != "canvas_front"){
|
||||
mouse_x = mouse_x - 109;
|
||||
mouse_y = mouse_y - 34;
|
||||
valid = false;
|
||||
}
|
||||
mouse_x = event.pageX;
|
||||
mouse_y = event.pageY;
|
||||
var abs_x = event.pageX;
|
||||
var abs_y = event.pageY;
|
||||
|
||||
if(event.target.id == "canvas_front"){
|
||||
//in canvas area - relative pos
|
||||
mouse_x = mouse_rel_x;
|
||||
mouse_y = mouse_rel_y;
|
||||
if(ZOOM != 100 ){
|
||||
mouse_x = Math.floor(mouse_x / ZOOM * 100);
|
||||
mouse_y = Math.floor(mouse_y / ZOOM * 100);
|
||||
mouse_y = Math.floor(mouse_y / ZOOM * 100);
|
||||
}
|
||||
}
|
||||
else
|
||||
else{
|
||||
//outside canvas - absolute pos - canvas offset
|
||||
mouse_x = mouse_x - 109;
|
||||
mouse_y = mouse_y - 34;
|
||||
valid = false;
|
||||
|
||||
}
|
||||
if(event.target.id == "canvas_preview"){
|
||||
//in preview area - relative pos
|
||||
mouse_x = mouse_rel_x;
|
||||
mouse_y = mouse_rel_y;
|
||||
}
|
||||
|
||||
//save - other place will use it too
|
||||
CON.mouse = {
|
||||
x: mouse_x,
|
||||
x: mouse_x,
|
||||
y: mouse_y,
|
||||
click_x: mouse_click_x,
|
||||
click_y: mouse_click_y,
|
||||
@ -232,14 +272,16 @@ function CONTROLLS_CLASS(){
|
||||
last_y: mouse_y_move_last,
|
||||
valid: valid,
|
||||
click_valid: mouse_click_valid,
|
||||
abs_x: abs_x,
|
||||
abs_y: abs_y,
|
||||
};
|
||||
}
|
||||
//mouse right click
|
||||
this.mouse_right_click = function(event){
|
||||
if(POP != undefined && POP.active==true) return true;
|
||||
mouse_click_x = mouse_x;
|
||||
mouse_click_y = mouse_y;
|
||||
CON.get_mouse_position(event);
|
||||
mouse_click_x = CON.mouse.x;
|
||||
mouse_click_y = CON.mouse.y;
|
||||
|
||||
for (i in TOOLS){
|
||||
if(i == ACTION){
|
||||
@ -250,16 +292,29 @@ function CONTROLLS_CLASS(){
|
||||
}
|
||||
//mouse click
|
||||
this.mouse_click = function(event){
|
||||
if(POP != undefined && POP.active==true) return true;
|
||||
CON.isDrag = true;
|
||||
if(POP != undefined && POP.active==true){
|
||||
CON.get_mouse_position(event);
|
||||
last_pop_click[0] = CON.mouse.abs_x;
|
||||
last_pop_click[1] = CON.mouse.abs_y;
|
||||
popup = document.getElementById('popup');
|
||||
popup_pos_top = parseInt(popup.style.top);
|
||||
popup_pos_left = parseInt(popup.style.left);
|
||||
if(event.target.id == "popup_drag")
|
||||
popup_dragable = true;
|
||||
else
|
||||
popup_dragable = false;
|
||||
return true;
|
||||
}
|
||||
if(event.which == 3) return true;
|
||||
mouse_click_x = mouse_x;
|
||||
mouse_click_y = mouse_y;
|
||||
CON.get_mouse_position(event);
|
||||
mouse_click_x = CON.mouse.x;
|
||||
mouse_click_y = CON.mouse.y;
|
||||
if(CON.mouse.valid == false)
|
||||
mouse_click_valid = false;
|
||||
else
|
||||
mouse_click_valid = true;
|
||||
isDrag = true;
|
||||
|
||||
|
||||
//check tools functions
|
||||
for (i in TOOLS){
|
||||
@ -282,9 +337,18 @@ function CONTROLLS_CLASS(){
|
||||
}
|
||||
//mouse move
|
||||
this.mouse_move = function(event){
|
||||
if(POP != undefined && POP.active==true) return true;
|
||||
if(POP != undefined && POP.active==true){
|
||||
//drag popup
|
||||
if(CON.isDrag==true && popup_dragable == true){
|
||||
CON.get_mouse_position(event);
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = (popup_pos_top + CON.mouse.abs_y - last_pop_click[1])+'px';
|
||||
popup.style.left = (popup_pos_left + CON.mouse.abs_x - last_pop_click[0])+'px';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
CON.get_mouse_position(event);
|
||||
if(event.target.id == "canvas_preview" && isDrag==true)
|
||||
if(event.target.id == "canvas_preview" && CON.isDrag==true)
|
||||
CON.calc_preview_by_mouse(CON.mouse.x, CON.mouse.y);
|
||||
LAYER.update_info_block();
|
||||
|
||||
@ -294,21 +358,23 @@ function CONTROLLS_CLASS(){
|
||||
else if(event.target.id == "resize-h") document.body.style.cursor = "n-resize";
|
||||
else if(event.target.id == "resize-wh") document.body.style.cursor = "nw-resize";
|
||||
else document.body.style.cursor = "auto";
|
||||
if(resize_all != false && isDrag==true){
|
||||
if(resize_all != false && CON.isDrag==true){
|
||||
document.body.style.cursor = "auto";
|
||||
if(resize_all == "w"){
|
||||
new_w = mouse_x;
|
||||
new_w = CON.mouse.x;
|
||||
new_h = HEIGHT;
|
||||
}
|
||||
else if(resize_all == "h"){
|
||||
new_w = WIDTH;
|
||||
new_h = mouse_y;
|
||||
new_h = CON.mouse.y;
|
||||
}
|
||||
else if(resize_all == "wh"){
|
||||
new_w = mouse_x;
|
||||
new_h = mouse_y;
|
||||
new_w = CON.mouse.x;
|
||||
new_h = CON.mouse.y;
|
||||
}
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_front.lineWidth = 1;
|
||||
canvas_front.fillStyle = "#ff0000";
|
||||
HELPER.dashedRect(canvas_front, 0, 0, new_w-1, new_h-1);
|
||||
event.preventDefault();
|
||||
HELPER.remove_selection();
|
||||
@ -316,16 +382,15 @@ function CONTROLLS_CLASS(){
|
||||
}
|
||||
}
|
||||
//check tools functions
|
||||
if(isDrag === false){
|
||||
for (i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('move', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
for (i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('move', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isDrag === false) return false; //only drag now
|
||||
|
||||
|
||||
if(CON.isDrag === false) return false; //only drag now
|
||||
|
||||
//check tools functions
|
||||
for (i in TOOLS){
|
||||
@ -337,15 +402,17 @@ function CONTROLLS_CLASS(){
|
||||
|
||||
if(ACTION != 'select_square')
|
||||
TOOLS.select_square_action = '';
|
||||
|
||||
|
||||
|
||||
mouse_x_move_last = CON.mouse.x;
|
||||
mouse_y_move_last = CON.mouse.y;
|
||||
}
|
||||
//release mouse click
|
||||
this.mouse_release = function(event){
|
||||
CON.isDrag = false;
|
||||
if(POP != undefined && POP.active==true) return true;
|
||||
var mouse = CON.get_mouse_position(event);
|
||||
isDrag = false;
|
||||
mouse_x_move_last = false
|
||||
mouse_y_move_last = false;
|
||||
if(TOOLS.select_square_action == '' && CON.mouse.valid == true)
|
||||
@ -362,16 +429,16 @@ function CONTROLLS_CLASS(){
|
||||
}
|
||||
|
||||
//main window resize
|
||||
if(resize_all != false && ZOOM == 100){
|
||||
if(resize_all != false && ZOOM == 100 && CON.mouse.x > 0 && CON.mouse.y > 0){
|
||||
CON.autosize = false;
|
||||
document.body.style.cursor = "auto";
|
||||
if(resize_all == "w")
|
||||
WIDTH = parseInt(mouse_x);
|
||||
WIDTH = CON.mouse.x;
|
||||
else if(resize_all == "h")
|
||||
HEIGHT = parseInt(mouse_y);
|
||||
HEIGHT = CON.mouse.y;
|
||||
else if(resize_all == "wh"){
|
||||
WIDTH = parseInt(mouse_x);
|
||||
HEIGHT = parseInt(mouse_y);
|
||||
WIDTH = mouse_x;
|
||||
HEIGHT = CON.mouse.y;
|
||||
}
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
@ -387,8 +454,10 @@ function CONTROLLS_CLASS(){
|
||||
progress.style.display='block';
|
||||
progress.value = progress.innerHTML = 0;
|
||||
MAIN.save_state();
|
||||
var n_valid = 0;
|
||||
for (var i = 0, f; f = e.dataTransfer.files[i]; i++){
|
||||
if(!f.type.match('image.*') && f.type != 'text/xml') continue;
|
||||
n_valid++;
|
||||
|
||||
var FR = new FileReader();
|
||||
FR.file = e.dataTransfer.files[i];
|
||||
@ -425,6 +494,8 @@ function CONTROLLS_CLASS(){
|
||||
else
|
||||
FR.readAsDataURL(f);
|
||||
}
|
||||
if(n_valid == 0)
|
||||
progress.style.display='none';
|
||||
document.getElementById("drop_zone").style.display='none';
|
||||
}
|
||||
this.mouse_wheel_handler = function(e){ //return true;
|
||||
|
||||
663
js/draw.js
663
js/draw.js
@ -6,7 +6,7 @@ function DRAW_CLASS(){
|
||||
this.draw_grid = function(canvas, gap_x, gap_y){
|
||||
if(MAIN.grid == false){
|
||||
canvas.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
DRAW.draw_background(canvas);
|
||||
DRAW.draw_background(canvas, WIDTH, HEIGHT);
|
||||
return false;
|
||||
}
|
||||
gap_x = parseInt(gap_x);
|
||||
@ -36,10 +36,10 @@ function DRAW_CLASS(){
|
||||
canvas.stroke();
|
||||
}
|
||||
}
|
||||
this.draw_background = function(canvas, gap, force){
|
||||
this.draw_background = function(canvas, W, H, gap, force){
|
||||
if(MAIN.TRANSPARENCY == false && force == undefined){
|
||||
canvas.beginPath();
|
||||
canvas.rect(0, 0, WIDTH, HEIGHT);
|
||||
canvas.rect(0, 0, W, H);
|
||||
canvas.fillStyle = "#ffffff";
|
||||
canvas.fill();
|
||||
return false;
|
||||
@ -47,12 +47,12 @@ function DRAW_CLASS(){
|
||||
if(gap == undefined)
|
||||
gap = 10;
|
||||
var fill = true;
|
||||
for(var i=0; i<WIDTH; i=i+gap){
|
||||
for(var i=0; i<W; i=i+gap){
|
||||
if(i%(gap*2) == 0)
|
||||
fill=true;
|
||||
else
|
||||
fill=false;
|
||||
for(var j=0; j<HEIGHT; j=j+gap){
|
||||
for(var j=0; j<H; j=j+gap){
|
||||
if(fill==true){
|
||||
canvas.fillStyle = '#eeeeee';
|
||||
canvas.fillRect(i, j, gap, gap);
|
||||
@ -103,7 +103,6 @@ function DRAW_CLASS(){
|
||||
imgData[k+1] = color_to.g; //g
|
||||
imgData[k+2] = color_to.b; //b
|
||||
imgData[k+3] = color_to.a; //a
|
||||
|
||||
stack.push(nextPointX);
|
||||
stack.push(nextPointY);
|
||||
}
|
||||
@ -134,6 +133,7 @@ function DRAW_CLASS(){
|
||||
color_from.b == color_to.b &&
|
||||
color_from.a == color_to.a)
|
||||
return false;
|
||||
if(ALPHA < 255 && color_from.a == ALPHA) return false;
|
||||
var stack = [];
|
||||
stack.push(x);
|
||||
stack.push(y);
|
||||
@ -152,10 +152,14 @@ function DRAW_CLASS(){
|
||||
Math.abs(imgData[k+2] - color_from.b) <= sensitivity &&
|
||||
Math.abs(imgData[k+3] - color_from.a) <= sensitivity){
|
||||
//fill pixel
|
||||
imgData[k+0] = color_to.r; //r
|
||||
imgData[k+1] = color_to.g; //g
|
||||
imgData[k+2] = color_to.b; //b
|
||||
imgData[k+3] = color_to.a; //a
|
||||
if(ALPHA == 255){
|
||||
imgData[k+0] = color_to.r; //r
|
||||
imgData[k+1] = color_to.g; //g
|
||||
imgData[k+2] = color_to.b; //b
|
||||
imgData[k+3] = color_to.a; //a
|
||||
}
|
||||
else
|
||||
imgData[k+3] = ALPHA; //a
|
||||
|
||||
stack.push(nextPointX);
|
||||
stack.push(nextPointY);
|
||||
@ -164,7 +168,65 @@ function DRAW_CLASS(){
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
}
|
||||
this.trim = function(layer, no_resize){
|
||||
this.trim_info = function(canvas, trim_white, include_white){
|
||||
var top = 0;
|
||||
var left = 0;
|
||||
var bottom = 0;
|
||||
var right = 0;
|
||||
var img = canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height);
|
||||
var imgData = img.data;
|
||||
//check top
|
||||
main1:
|
||||
for(var y = 0; y < img.height; y++){
|
||||
for(var x = 0; x < img.width; x++){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main1;
|
||||
}
|
||||
top++;
|
||||
}
|
||||
//check left
|
||||
main2:
|
||||
for(var x = 0; x < img.width; x++){
|
||||
for(var y = 0; y < img.height; y++){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main2;
|
||||
}
|
||||
left++;
|
||||
}
|
||||
//check bottom
|
||||
main3:
|
||||
for(var y = img.height-1; y >= 0; y--){
|
||||
for(var x = img.width-1; x >= 0; x--){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main3;
|
||||
}
|
||||
bottom++;
|
||||
}
|
||||
//check right
|
||||
main4:
|
||||
for(var x = img.width-1; x >= 0; x--){
|
||||
for(var y = img.height-1; y >= 0; y--){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main4;
|
||||
}
|
||||
right++;
|
||||
}
|
||||
return {
|
||||
top: top,
|
||||
left: left,
|
||||
bottom: bottom,
|
||||
right: right,
|
||||
};
|
||||
};
|
||||
this.trim = function(layer, no_resize, include_white){
|
||||
var all_top = HEIGHT;
|
||||
var all_left = WIDTH;
|
||||
var all_bottom = HEIGHT;
|
||||
@ -183,18 +245,20 @@ function DRAW_CLASS(){
|
||||
for(var y = 0; y < img.height; y++){
|
||||
for(var x = 0; x < img.width; x++){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3]>0 && (imgData[k]<255 || imgData[k+1]<255 || imgData[k+2]<255) )
|
||||
break main1;
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main1;
|
||||
}
|
||||
top++;
|
||||
}
|
||||
//check left
|
||||
main2:
|
||||
for(var x = 0; x < img.width; x++){
|
||||
for(var x = 0; x < img.width; x++){
|
||||
for(var y = 0; y < img.height; y++){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3]>0 && (imgData[k]<255 || imgData[k+1]<255 || imgData[k+2]<255) )
|
||||
break main2;
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main2;
|
||||
}
|
||||
left++;
|
||||
}
|
||||
@ -203,8 +267,9 @@ function DRAW_CLASS(){
|
||||
for(var y = img.height-1; y >= 0; y--){
|
||||
for(var x = img.width-1; x >= 0; x--){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3]>0 && (imgData[k]<255 || imgData[k+1]<255 || imgData[k+2]<255) )
|
||||
break main3;
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main3;
|
||||
}
|
||||
bottom++;
|
||||
}
|
||||
@ -213,8 +278,9 @@ function DRAW_CLASS(){
|
||||
for(var x = img.width-1; x >= 0; x--){
|
||||
for(var y = img.height-1; y >= 0; y--){
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
if(imgData[k+3]>0 && (imgData[k]<255 || imgData[k+1]<255 || imgData[k+2]<255) )
|
||||
break main4;
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
if(include_white !== true && imgData[k] == 255 && imgData[k+1] == 255 && imgData[k+2] == 255) continue; //white
|
||||
break main4;
|
||||
}
|
||||
right++;
|
||||
}
|
||||
@ -261,18 +327,358 @@ function DRAW_CLASS(){
|
||||
}
|
||||
LAYER.update_info_block();
|
||||
}
|
||||
this.effect_bw = function(context, W, H){
|
||||
var threshold = 200;
|
||||
this.effect_bw = function(context, W, H, level){
|
||||
var black = level + 25; //default 150;
|
||||
var white = level - 25; //defaul 100;
|
||||
if(black < 0 || level == 0) black = 0;
|
||||
if(white > 255 || level == 255) white = 255;
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
for(var i = 0; i < imgData.length; i += 4) {
|
||||
var c = imgData[i] > threshold ? 255 : 0;
|
||||
imgData[i] = c;
|
||||
imgData[i+1] = c;
|
||||
imgData[i+2] = c;
|
||||
var imgData = img.data;
|
||||
for(var j = 0; j < H; j++){
|
||||
for(var i = 0; i < W; i++){
|
||||
var x = (i + j*W) * 4;
|
||||
if(imgData[x+3] == 0) continue; //transparent
|
||||
var c = 0;
|
||||
var mid = round(imgData[x] + imgData[x+1] + imgData[x+2])/3;
|
||||
if(mid >= black)
|
||||
c = 255;
|
||||
else if(mid <= white)
|
||||
c = 0;
|
||||
else{
|
||||
//we not sure here ... randomize to get better overall quality
|
||||
c = HELPER.getRandomInt(white, black);
|
||||
if(mid < c)
|
||||
c = 0;
|
||||
else
|
||||
c = 255;
|
||||
}
|
||||
imgData[x] = c;
|
||||
imgData[x+1] = c;
|
||||
imgData[x+2] = c;
|
||||
}
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
}
|
||||
this.decrease_colors = function(context, W, H, colors, dithering, greyscale){
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
|
||||
//collect top colors
|
||||
var colors_top = [];
|
||||
for(var i = 0; i < imgData.length; i += 40){ //check pixel and skip 10.
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
var key = imgData[i]+"."+imgData[i+1]+"."+imgData[i+2];
|
||||
|
||||
if(colors_top[key] == undefined)
|
||||
colors_top[key] = [1, imgData[i], imgData[i+1], imgData[i+2]];
|
||||
else
|
||||
colors_top[key][0]++;
|
||||
}
|
||||
|
||||
//sort
|
||||
colors_top.sort(function(a,b) { return parseFloat(b[0]) - parseFloat(a[0]); } );
|
||||
var colors_top_sort = [];
|
||||
for (var i in colors_top)
|
||||
colors_top_sort.push(colors_top[i]);
|
||||
colors_top_sort.sort(function(a, b) {return b[0] - a[0]});
|
||||
colors_top = colors_top_sort; //alert(colors_top.length);
|
||||
|
||||
if(colors_top.length > 256){
|
||||
var last = colors_top[0];
|
||||
for(var i=1; i<colors_top.length; i++){
|
||||
var diffR = colors_top[i][1] - last[1];
|
||||
var diffG = colors_top[i][2] - last[2];
|
||||
var diffB = colors_top[i][3] - last[3];
|
||||
diff = Math.sqrt(diffR*diffR + diffG*diffG + diffB*diffB);
|
||||
|
||||
if(diff > 100)
|
||||
last = colors_top[i]; //save last good
|
||||
else{
|
||||
//to close, remove it
|
||||
colors_top.splice(i, 1); i--;
|
||||
}
|
||||
}
|
||||
if(colors_top.length < 100){
|
||||
//oops, we deleted too much ...
|
||||
colors_top = colors_top_sort;
|
||||
colors_top_sort.splice(256);
|
||||
}
|
||||
colors_top_sort.splice(512);
|
||||
}
|
||||
colors_top_sort = [];
|
||||
|
||||
var palette = [];
|
||||
var min = 0;
|
||||
var index;
|
||||
var top_color_n;
|
||||
for(var i in colors_top){
|
||||
if(colors_top[i][0] > min){
|
||||
min = colors_top[0];
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
//add main color
|
||||
palette.push([colors_top[index][1], colors_top[index][2], colors_top[index][3]]);
|
||||
top_color_n = colors_top[index][0];
|
||||
|
||||
//increase pallete - use only different colors
|
||||
for(var c=1; c<colors; c++){
|
||||
var diff_all=0;
|
||||
var max_all = 0;
|
||||
var index_all;
|
||||
//reset
|
||||
for(var i in colors_top)
|
||||
colors_top[i][4] = [];
|
||||
for(var p in palette){
|
||||
var diff;
|
||||
var max = 0;
|
||||
var index;
|
||||
var diff_tmp = [];
|
||||
for(var i in colors_top){
|
||||
var diffR = colors_top[i][1] - palette[p][0];
|
||||
var diffG = colors_top[i][2] - palette[p][1];
|
||||
var diffB = colors_top[i][3] - palette[p][2];
|
||||
diff = Math.sqrt(diffR*diffR + diffG*diffG + diffB*diffB); //max 441
|
||||
//density fix
|
||||
//diff *= colors_top[i][0];// * 441 / top_color_n;
|
||||
colors_top[i][4].push(diff);
|
||||
}
|
||||
}
|
||||
//find biggest minimum
|
||||
var index=0;
|
||||
var max = 0;
|
||||
for(var i in colors_top){
|
||||
var min = 999999;
|
||||
for(var k in colors_top[i][4]){
|
||||
if(colors_top[i][4][k] < min)
|
||||
min = colors_top[i][4][k];
|
||||
}
|
||||
if(min > max){
|
||||
index = i;
|
||||
max = min;
|
||||
}
|
||||
}
|
||||
palette.push([colors_top[index][1], colors_top[index][2], colors_top[index][3]]);
|
||||
}
|
||||
|
||||
//change
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
var mid = round(imgData[i] + imgData[i+1] + imgData[i+2])/3;
|
||||
if(dithering == true){
|
||||
//find first close color
|
||||
var index1 = 0;
|
||||
var min1 = 256*3;
|
||||
var diff1;
|
||||
for(var j=0; j<palette.length; j++){
|
||||
var diff = 0;
|
||||
diff += Math.abs(palette[j][0] - imgData[i]);
|
||||
diff += Math.abs(palette[j][1] - imgData[i+1]);
|
||||
diff += Math.abs(palette[j][2] - imgData[i+2]);
|
||||
if(diff < min1){
|
||||
min1 = diff;
|
||||
index1 = j;
|
||||
diff1 = diff;
|
||||
}
|
||||
}
|
||||
//find second close color
|
||||
var index2 = 0;
|
||||
var min2 = 256*3;
|
||||
var diff2;
|
||||
for(var j=0; j<palette.length; j++){
|
||||
if(j == index1) continue; //we already have this
|
||||
var diff = 0;
|
||||
diff += Math.abs(palette[j][0] - imgData[i]);
|
||||
diff += Math.abs(palette[j][1] - imgData[i+1]);
|
||||
diff += Math.abs(palette[j][2] - imgData[i+2]);
|
||||
if(diff < min2){
|
||||
min2 = diff;
|
||||
index2 = j;
|
||||
diff2 = diff;
|
||||
}
|
||||
}
|
||||
var c;
|
||||
if(diff1 == 0 || diff1/diff2 < 0.3)
|
||||
c = palette[index1]; //exact color match
|
||||
else{
|
||||
//we not sure here ... randomize to get better overall quality
|
||||
var rand = HELPER.getRandomInt(-diff1, diff2);
|
||||
if(rand < 0)
|
||||
c = palette[index2];
|
||||
else
|
||||
c = palette[index1];
|
||||
}
|
||||
imgData[i] = c[0];
|
||||
imgData[i+1] = c[1];
|
||||
imgData[i+2] = c[2];
|
||||
}
|
||||
else{
|
||||
var index = 0;
|
||||
var min = 256*3;
|
||||
for(var j=0; j<palette.length; j++){
|
||||
var diff = 0;
|
||||
diff += Math.abs(palette[j][0] - imgData[i]);
|
||||
diff += Math.abs(palette[j][1] - imgData[i+1]);
|
||||
diff += Math.abs(palette[j][2] - imgData[i+2]);
|
||||
if(diff < min){
|
||||
min = diff;
|
||||
index = j;
|
||||
}
|
||||
}
|
||||
imgData[i] = palette[index][0];
|
||||
imgData[i+1] = palette[index][1];
|
||||
imgData[i+2] = palette[index][2];
|
||||
}
|
||||
if(greyscale == true){
|
||||
var mid = round(0.2126 * imgData[i] + 0.7152 * imgData[i+1] + 0.0722 * imgData[i+2]);
|
||||
imgData[i] = mid;
|
||||
imgData[i+1] = mid;
|
||||
imgData[i+2] = mid;
|
||||
}
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
}
|
||||
//converts greyscale images to coloured
|
||||
this.colorize = function(context, W, H, rand_power, max_gap, dither, manual_colors){
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
|
||||
if(manual_colors == undefined || manual_colors === true){
|
||||
var colors = [];
|
||||
for(var x=0; x < 3; x++){
|
||||
colors[x] = [];
|
||||
var pre = HELPER.getRandomInt(-1 * rand_power, rand_power);
|
||||
for(var i = 0; i <= 255; i++){
|
||||
colors[x][i] = HELPER.getRandomInt(pre - rand_power, pre + rand_power);
|
||||
|
||||
if(colors[x][i] < -1*max_gap) colors[x][i] += 10;
|
||||
else if(colors[x][i] > max_gap) colors[x][i] -= 10;
|
||||
|
||||
pre = colors[x][i];
|
||||
}
|
||||
}
|
||||
if(manual_colors === true)
|
||||
return colors;
|
||||
}
|
||||
else
|
||||
var colors = manual_colors;
|
||||
|
||||
//colorize
|
||||
var imgData = img.data;
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if(dither == true){
|
||||
var diff = Math.abs(colors[0][imgData[x]]) + Math.abs(colors[0][imgData[x]]) + Math.abs(colors[0][imgData[x]]);
|
||||
diff = diff / 3;
|
||||
}
|
||||
for(var c = 0; c < 3; c++){
|
||||
var x = i + c;
|
||||
if(dither == false)
|
||||
imgData[x] += colors[c][imgData[x]];
|
||||
else{
|
||||
if(diff < rand_power*6)
|
||||
imgData[x] += colors[c][imgData[x]];
|
||||
else{
|
||||
//big difference here - randomize
|
||||
var rand = HELPER.getRandomInt(Math.min(0, colors[c][imgData[x]]), Math.max(0, colors[c][imgData[x]]));
|
||||
imgData[x] += rand;
|
||||
}
|
||||
}
|
||||
if(imgData[x] > 255) imgData[x] = 255;
|
||||
if(imgData[x] < 0) imgData[x] = 0;
|
||||
}
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
return false;
|
||||
}
|
||||
//fixing white and black color balance
|
||||
this.auto_adjust = function(context, W, H){
|
||||
//settings
|
||||
var white = 240; //white color min
|
||||
var black = 30; //black color max
|
||||
var target_white = 1; //how much % white colors should take
|
||||
var target_black = 0.5; //how much % black colors should take
|
||||
var modify = 1.1; //color modify strength
|
||||
|
||||
document.body.style.cursor = "wait";
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
var n = 0; //pixels count without transparent
|
||||
|
||||
//make sure we have white
|
||||
var n_valid = 0;
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if((imgData[i] + imgData[i+1] + imgData[i+2]) / 3 > white) n_valid++;
|
||||
n++;
|
||||
}
|
||||
target = target_white;
|
||||
var n_fix_white = 0;
|
||||
var done = false;
|
||||
for(var j=0; j < 30; j++){
|
||||
if(n_valid * 100 / n >= target) done = true;
|
||||
if(done == true) break;
|
||||
n_fix_white++;
|
||||
|
||||
//adjust
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
for(var c = 0; c < 3; c++){
|
||||
var x = i + c;
|
||||
if(imgData[x] < 10) continue;
|
||||
//increase white
|
||||
imgData[x] *= modify;
|
||||
imgData[x] = round(imgData[x]);
|
||||
if(imgData[x] > 255) imgData[x] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
//recheck
|
||||
n_valid = 0;
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if((imgData[i] + imgData[i+1] + imgData[i+2]) / 3 > white) n_valid++;
|
||||
}
|
||||
}
|
||||
|
||||
//make sure we have black
|
||||
n_valid = 0;
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if((imgData[i] + imgData[i+1] + imgData[i+2]) / 3 < black) n_valid++;
|
||||
}
|
||||
target = target_black;
|
||||
var n_fix_black = 0;
|
||||
var done = false;
|
||||
for(var j=0; j < 30; j++){
|
||||
if(n_valid * 100 / n >= target) done = true;
|
||||
if(done == true) break;
|
||||
n_fix_black++;
|
||||
|
||||
//adjust
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
for(var c = 0; c < 3; c++){
|
||||
var x = i + c;
|
||||
if(imgData[x] > 240) continue;
|
||||
//increase black
|
||||
imgData[x] -= (255-imgData[x]) * modify - (255-imgData[x]);
|
||||
imgData[x] = round(imgData[x]);
|
||||
}
|
||||
}
|
||||
|
||||
//recheck
|
||||
n_valid = 0;
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if((imgData[i] + imgData[i+1] + imgData[i+2]) / 3 < black) n_valid++;
|
||||
}
|
||||
}
|
||||
|
||||
//save
|
||||
context.putImageData(img, 0, 0);
|
||||
document.body.style.cursor = "auto";
|
||||
log('Iterations: brighten='+n_fix_white+", darken="+n_fix_black);
|
||||
}
|
||||
this.zoom = function(recalc, scroll){
|
||||
if(recalc != undefined){
|
||||
//zoom-in or zoom-out
|
||||
@ -327,7 +733,7 @@ function DRAW_CLASS(){
|
||||
canvas_preview.rect(0, 0, DRAW.PREVIEW_SIZE.w, DRAW.PREVIEW_SIZE.h);
|
||||
canvas_preview.fillStyle = "#ffffff";
|
||||
canvas_preview.fill();
|
||||
DRAW.draw_background(canvas_preview, 5);
|
||||
DRAW.draw_background(canvas_preview, DRAW.PREVIEW_SIZE.w, DRAW.PREVIEW_SIZE.h, 5);
|
||||
|
||||
//redraw preview area
|
||||
canvas_preview.save();
|
||||
@ -369,111 +775,98 @@ function DRAW_CLASS(){
|
||||
context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
|
||||
context.stroke();
|
||||
}
|
||||
//http://stackoverflow.com/questions/2303690/resizing-an-image-in-an-html5-canvas, credits to "syockit"
|
||||
var object_l = {};
|
||||
this.thumbnailer = function(elem, sx, lobes){
|
||||
var img = elem.getContext("2d").getImageData(0, 0, elem.width, elem.height);
|
||||
object_l.canvas = elem;
|
||||
object_l.ctx = elem.getContext("2d");
|
||||
object_l.ctx.putImageData(img, 0, 0);
|
||||
object_l.img = img;
|
||||
object_l.src = object_l.ctx.getImageData(0, 0, img.width, img.height);
|
||||
object_l.dest = {
|
||||
width: sx,
|
||||
height: Math.round(img.height * sx / img.width),
|
||||
};
|
||||
object_l.dest.data = new Array(object_l.dest.width * object_l.dest.height * 3);
|
||||
object_l.lanczos = DRAW.lanczosCreate(lobes);
|
||||
object_l.ratio = img.width / sx;
|
||||
object_l.rcp_ratio = 2 / object_l.ratio;
|
||||
object_l.range2 = Math.ceil(object_l.ratio * lobes / 2);
|
||||
object_l.cacheLanc = {};
|
||||
object_l.center = {};
|
||||
object_l.icenter = {};
|
||||
object_l.date = Date.now();
|
||||
//setTimeout(this.process1, 0, this, 0); //setTimeout is slow, has big pauses between
|
||||
DRAW.process1(object_l, 0);
|
||||
}
|
||||
//calculates lanczos weight
|
||||
this.lanczosCreate = function(lobes){
|
||||
return function(x){
|
||||
if (x > lobes)
|
||||
return 0;
|
||||
x *= Math.PI;
|
||||
if (Math.abs(x) < 1e-16)
|
||||
return 1;
|
||||
var xx = x / lobes;
|
||||
return Math.sin(x) * Math.sin(xx) / x / xx;
|
||||
}
|
||||
}
|
||||
this.process1 = function(self, u){
|
||||
//continue
|
||||
self.center.x = (u + 0.5) * self.ratio;
|
||||
self.icenter.x = Math.floor(self.center.x);
|
||||
for (var v = 0; v < self.dest.height; v++) {
|
||||
self.center.y = (v + 0.5) * self.ratio;
|
||||
self.icenter.y = Math.floor(self.center.y);
|
||||
var a, r, g, b, x;
|
||||
a = r = g = b = x = 0;
|
||||
for (var i = self.icenter.x - self.range2; i <= self.icenter.x + self.range2; i++) {
|
||||
if (i < 0 || i >= self.src.width)
|
||||
continue;
|
||||
var f_x = Math.floor(1000 * Math.abs(i - self.center.x));
|
||||
if (!self.cacheLanc[f_x])
|
||||
self.cacheLanc[f_x] = {};
|
||||
for (var j = self.icenter.y - self.range2; j <= self.icenter.y + self.range2; j++) {
|
||||
if (j < 0 || j >= self.src.height)
|
||||
continue;
|
||||
var f_y = Math.floor(1000 * Math.abs(j - self.center.y));
|
||||
if (self.cacheLanc[f_x][f_y] == undefined)
|
||||
self.cacheLanc[f_x][f_y] = self.lanczos(Math.sqrt(Math.pow(f_x * self.rcp_ratio, 2) + Math.pow(f_y * self.rcp_ratio, 2)) / 1000);
|
||||
weight = self.cacheLanc[f_x][f_y];
|
||||
if (weight > 0) {
|
||||
var idx = (j * self.src.width + i) * 4;
|
||||
a += weight;
|
||||
r += weight * self.src.data[idx];
|
||||
g += weight * self.src.data[idx + 1];
|
||||
b += weight * self.src.data[idx + 2];
|
||||
x += weight * self.src.data[idx + 3]; //transparency
|
||||
}
|
||||
}
|
||||
}
|
||||
var idx = (v * self.dest.width + u) * 4;
|
||||
self.dest.data[idx] = r / a;
|
||||
self.dest.data[idx + 1] = g / a;
|
||||
self.dest.data[idx + 2] = b / a;
|
||||
self.dest.data[idx + 3] = x / a ; //transparency
|
||||
}
|
||||
if (++u < self.dest.width)
|
||||
DRAW.process1(self, u);
|
||||
else
|
||||
DRAW.process2(self, u);
|
||||
};
|
||||
this.process2 = function(self){
|
||||
self.ctx.putImageData(self.img, 0, 0);
|
||||
self.src = self.ctx.getImageData(0, 0, self.dest.width, self.dest.height);
|
||||
var idx, idx2;
|
||||
for (var i = 0; i < self.dest.width; i++) {
|
||||
for (var j = 0; j < self.dest.height; j++) {
|
||||
idx = (j * self.dest.width + i) * 4;
|
||||
idx2 = (j * self.dest.width + i) * 4;
|
||||
self.src.data[idx2] = self.dest.data[idx];
|
||||
self.src.data[idx2 + 1] = self.dest.data[idx + 1];
|
||||
self.src.data[idx2 + 2] = self.dest.data[idx + 2];
|
||||
self.src.data[idx2 + 3] = self.dest.data[idx + 3]; //transparency
|
||||
}
|
||||
}
|
||||
//var time = Date.now() - self.date;alert(time/1000+"s");
|
||||
self.ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
self.ctx.putImageData(self.src, 0, 0);
|
||||
self = {}; //release memory
|
||||
//hermite resample - classic "rings.gif" 1000x1000 resize to 200x200 record - 0.040
|
||||
this.resample_hermite = function(canvas, W, H, W2, H2){
|
||||
var time1 = Date.now();
|
||||
var img = canvas.getContext("2d").getImageData(0, 0, W, H);
|
||||
var img2 = canvas.getContext("2d").getImageData(0, 0, W2, H2);
|
||||
var data = img.data;
|
||||
var data2 = img2.data;
|
||||
var ratio_w = W / W2;
|
||||
var ratio_h = H / H2;
|
||||
var ratio_w_half = Math.ceil(ratio_w/2);
|
||||
var ratio_h_half = Math.ceil(ratio_h/2);
|
||||
|
||||
//do some extra things
|
||||
LAYER.resize_canvas(LAYERS[LAYER.layer_active].name, true);
|
||||
if(MENU.last_menu == 'image_resize')
|
||||
DRAW.trim();
|
||||
DRAW.zoom();
|
||||
if(POP.active == true)
|
||||
POP.hide();
|
||||
}
|
||||
for(var j = 0; j < H2; j++){
|
||||
for(var i = 0; i < W2; i++){
|
||||
var x2 = (i + j*W2) * 4;
|
||||
var weight = 0;
|
||||
var weights = 0;
|
||||
var gx_r = gx_g = gx_b = gx_a = 0;
|
||||
var center_y = (j + 0.5) * ratio_h;
|
||||
for(var yy = Math.floor(j * ratio_h); yy < (j + 1) * ratio_h; yy++){
|
||||
var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
|
||||
var center_x = (i + 0.5) * ratio_w;
|
||||
var w0 = dy*dy //pre-calc part of w
|
||||
for(var xx = Math.floor(i * ratio_w); xx < (i + 1) * ratio_w; xx++){
|
||||
var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
|
||||
var w = Math.sqrt(w0 + dx*dx);
|
||||
if(w >= -1 && w <= 1){
|
||||
//hermite filter
|
||||
weight = 2 * w*w*w - 3*w*w + 1;
|
||||
if(weight > 0){
|
||||
dx = 4*(xx + yy*W);
|
||||
gx_r += weight * data[dx];
|
||||
gx_g += weight * data[dx + 1];
|
||||
gx_b += weight * data[dx + 2];
|
||||
gx_a += weight * data[dx + 3];
|
||||
weights += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data2[x2] = gx_r / weights;
|
||||
data2[x2 + 1] = gx_g / weights;
|
||||
data2[x2 + 2] = gx_b / weights;
|
||||
data2[x2 + 3] = gx_a / weights;
|
||||
}
|
||||
}
|
||||
console.log("hermite = "+(Math.round(Date.now() - time1)/1000)+" s");
|
||||
canvas.getContext("2d").clearRect(0, 0, Math.max(W, W2), Math.max(H, H2));
|
||||
canvas.getContext("2d").putImageData(img2, 0, 0);
|
||||
};
|
||||
this.resample_hermite_threads = function(canvas, W, H, W2, H2){
|
||||
var time1 = Date.now();
|
||||
var img = canvas.getContext("2d").getImageData(0, 0, W, H);
|
||||
var img2 = canvas.getContext("2d").getImageData(0, 0, W2, H2);
|
||||
var data2 = img2.data;
|
||||
var cores = 8;
|
||||
var cpu_in_use = 0;
|
||||
var progress = document.getElementById('uploadprogress');
|
||||
progress.style.display='block';
|
||||
progress.value = progress.innerHTML = 0;
|
||||
canvas.getContext("2d").clearRect(0, 0, W, H);
|
||||
|
||||
for(var c = 0; c < cores; c++){
|
||||
cpu_in_use++;
|
||||
var my_worker = new Worker("libs/worker-hermite.js");
|
||||
my_worker.onmessage = function(event){ //log(event.data);return false;
|
||||
cpu_in_use--;
|
||||
var complete = ((cores - cpu_in_use) / cores * 100 | 0);
|
||||
progress.value = progress.innerHTML = complete;
|
||||
var offset = event.data.offset; //log( event.data.data.length);
|
||||
|
||||
for(var i = 0; i < event.data.data.length; i += 4){
|
||||
var x = offset + i; //log([ x, event.data.data[i], event.data.data[i+1],event.data.data[i+2],event.data.data[i+3], ]); return false;
|
||||
data2[x] = event.data.data[i];
|
||||
data2[x + 1] = event.data.data[i+1];
|
||||
data2[x + 2] = event.data.data[i+2];
|
||||
data2[x + 3] = event.data.data[i+3];
|
||||
}
|
||||
|
||||
//finish
|
||||
if(cpu_in_use <= 0){
|
||||
console.log("hermite "+cores+" cores = "+(Math.round(Date.now() - time1)/1000)+" s");
|
||||
canvas.getContext("2d").clearRect(0, 0, W, H);
|
||||
canvas.getContext("2d").putImageData(img2, 0, 0);
|
||||
|
||||
progress.style.display='none';
|
||||
if(MENU.last_menu != 'layer_resize')
|
||||
DRAW.trim();
|
||||
DRAW.zoom();
|
||||
}
|
||||
};
|
||||
my_worker.postMessage([img, W, H, W2, H2, c, cores]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
108
js/helpers.js
108
js/helpers.js
@ -118,8 +118,11 @@ function HELPER_CLASS(){
|
||||
y1 = y1 + 0.5;
|
||||
x2 = x2 + 0.5;
|
||||
y2 = y2 + 0.5;
|
||||
canvas.strokeStyle = color;
|
||||
if (dashLen == undefined) dashLen = 4;
|
||||
if(color != undefined)
|
||||
canvas.strokeStyle = color;
|
||||
else
|
||||
canvas.strokeStyle = "#000000";
|
||||
if(dashLen == undefined) dashLen = 4;
|
||||
canvas.beginPath();
|
||||
canvas.moveTo(x1, y1);
|
||||
var dX = x2 - x1;
|
||||
@ -255,11 +258,110 @@ function HELPER_CLASS(){
|
||||
link.href = 'data:,' + fileContents;
|
||||
link.click();
|
||||
}
|
||||
//credits: richard maloney 2006
|
||||
this.darkenColor = function(color, v){
|
||||
if (color.length >6) { color= color.substring(1,color.length)}
|
||||
var rgb = parseInt(color, 16);
|
||||
var r = Math.abs(((rgb >> 16) & 0xFF)+v); if (r>255) r=r-(r-255);
|
||||
var g = Math.abs(((rgb >> 8) & 0xFF)+v); if (g>255) g=g-(g-255);
|
||||
var b = Math.abs((rgb & 0xFF)+v); if (b>255) b=b-(b-255);
|
||||
r = Number(r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r).toString(16);
|
||||
if (r.length == 1) r = '0' + r;
|
||||
g = Number(g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g).toString(16);
|
||||
if (g.length == 1) g = '0' + g;
|
||||
b = Number(b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b).toString(16);
|
||||
if (b.length == 1) b = '0' + b;
|
||||
return "#" + r + g + b;
|
||||
};
|
||||
//IntegraXor Web SCADA - JavaScript Number Formatter, author: KPL, KHL
|
||||
this.format = function(b,a){
|
||||
if(!b||isNaN(+a))return a;
|
||||
var a=b.charAt(0)=="-"?-a:+a,j=a<0?a=-a:0,e=b.match(/[^\d\-\+#]/g),h=e&&e[e.length-1]||".",e=e&&e[1]&&e[0]||",",b=b.split(h),a=a.toFixed(b[1]&&b[1].length),a=+a+"",d=b[1]&&b[1].lastIndexOf("0"),c=a.split(".");
|
||||
if(!c[1]||c[1]&&c[1].length<=d)
|
||||
a=(+a).toFixed(d+1);
|
||||
d=b[0].split(e);
|
||||
b[0]=d.join("");
|
||||
var f=b[0]&&b[0].indexOf("0");
|
||||
if(f>-1) for(;c[0].length<b[0].length-f;)c[0]="0"+c[0];
|
||||
else +c[0]==0&&(c[0]="");
|
||||
a=a.split(".");a[0]=c[0];
|
||||
if(c=d[1]&&d[d.length-1].length)
|
||||
{for(var d=a[0],f="",k=d.length%c,g=0,i=d.length;g<i;g++)f+=d.charAt(g),!((g-k+1)%c)&&g<i-c&&(f+=e);a[0]=f;}
|
||||
a[1]=b[1]&&a[1]?h+a[1]:"";
|
||||
return(j?"-":"")+a[0]+a[1];
|
||||
};
|
||||
}
|
||||
//http://www.script-tutorials.com/html5-canvas-custom-brush1/
|
||||
var BezierCurveBrush = {
|
||||
// inner variables
|
||||
iPrevX : 0,
|
||||
iPrevY : 0,
|
||||
points : null,
|
||||
|
||||
// initialization function
|
||||
init: function () { },
|
||||
|
||||
startCurve: function (x, y) {
|
||||
this.iPrevX = x;
|
||||
this.iPrevY = y;
|
||||
this.points = new Array();
|
||||
},
|
||||
|
||||
getPoint: function (iLength, a) {
|
||||
var index = a.length - iLength, i;
|
||||
for (i=index; i< a.length; i++) {
|
||||
if (a[i]) {
|
||||
return a[i];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
draw: function (ctx, color_rgb, x, y) {
|
||||
if (Math.abs(this.iPrevX - x) > 5 || Math.abs(this.iPrevY - y) > 5) {
|
||||
this.points.push([x, y]);
|
||||
|
||||
// draw main path stroke
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.iPrevX, this.iPrevY);
|
||||
ctx.lineTo(x, y);
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = 'rgba(' + color_rgb.r + ', ' + color_rgb.g + ', ' + color_rgb.b + ', 0.9)';
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
// draw extra strokes
|
||||
ctx.strokeStyle = 'rgba(' + color_rgb.r + ', ' + color_rgb.g + ', ' + color_rgb.b + ', 0.2)';
|
||||
ctx.beginPath();
|
||||
var iStartPoint = this.getPoint(25, this.points);
|
||||
var iFirstPoint = this.getPoint(1, this.points);
|
||||
var iSecondPoint = this.getPoint(5, this.points);
|
||||
ctx.moveTo(iStartPoint[0],iStartPoint[1]);
|
||||
ctx.bezierCurveTo(iFirstPoint[0], iFirstPoint[1], iSecondPoint[0], iSecondPoint[1], x, y);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
this.iPrevX = x;
|
||||
this.iPrevY = y;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//quick access short functions
|
||||
function log(object){
|
||||
console.log(object);
|
||||
if(typeof object != 'object')
|
||||
console.log(object);
|
||||
else{
|
||||
var str = '[';
|
||||
for(var i in object){
|
||||
if(typeof object[i] == 'number')
|
||||
str += Math.round(object[i]*1000)/1000+", ";
|
||||
else
|
||||
str += object[i]+", ";
|
||||
}
|
||||
str += ']';
|
||||
log(str);
|
||||
}
|
||||
}
|
||||
function round(number){
|
||||
return Math.round(number);
|
||||
|
||||
52
js/layers.js
52
js/layers.js
@ -26,6 +26,27 @@ function LAYER_CLASS(){
|
||||
//image
|
||||
var new_name = name;
|
||||
|
||||
//check size
|
||||
var size_increased = false;
|
||||
if(img.width > WIDTH || img.height > HEIGHT){
|
||||
if(img.width > WIDTH)
|
||||
WIDTH = img.width;
|
||||
if(img.height > HEIGHT)
|
||||
HEIGHT = img.height;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
size_increased = true;
|
||||
}
|
||||
if(LAYERS.length == 1 && CON.autosize == true && size_increased == false){
|
||||
var trim_info = DRAW.trim_info(document.getElementById("Background"));
|
||||
if(trim_info.left == WIDTH){
|
||||
WIDTH = img.width;
|
||||
HEIGHT = img.height;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size(false);
|
||||
}
|
||||
}
|
||||
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS[i].name == new_name)
|
||||
new_name = 'Layer #'+(LAYERS.length+1);
|
||||
@ -37,23 +58,13 @@ function LAYER_CLASS(){
|
||||
opacity: 1,
|
||||
});
|
||||
LAYER.layer_active = LAYERS.length-1;
|
||||
LAYER.layer_renew();
|
||||
|
||||
//check size
|
||||
if(img.width > WIDTH || img.height > HEIGHT){
|
||||
if(img.width > WIDTH)
|
||||
WIDTH = img.width;
|
||||
if(img.height > HEIGHT)
|
||||
HEIGHT = img.height;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
CON.calc_preview_auto();
|
||||
}
|
||||
|
||||
document.getElementById(new_name).getContext("2d").globalAlpha = 1;
|
||||
document.getElementById(new_name).getContext('2d').drawImage(img, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
if(LAYERS.length <= 2 && CON.autosize == true)
|
||||
DRAW.trim();
|
||||
/*if(LAYERS.length <= 2 && CON.autosize == true && size_increased == false){
|
||||
DRAW.trim(undefined, undefined, true);
|
||||
}*/
|
||||
DRAW.zoom();
|
||||
}
|
||||
}
|
||||
@ -68,7 +79,6 @@ function LAYER_CLASS(){
|
||||
document.getElementById('canvas_more').appendChild(new_canvas);
|
||||
document.getElementById(canvas_id).width = WIDTH;
|
||||
document.getElementById(canvas_id).height = HEIGHT;
|
||||
document.getElementById(canvas_id).getContext("2d").fillStyle = "rgba(255, 255, 255, 0.5)";
|
||||
document.getElementById(canvas_id).getContext("2d").mozImageSmoothingEnabled = false;
|
||||
document.getElementById(canvas_id).getContext("2d").webkitImageSmoothingEnabled = false;
|
||||
//document.getElementById(canvas_id).getContext("2d").scale(ZOOM/100, ZOOM/100);
|
||||
@ -209,15 +219,19 @@ function LAYER_CLASS(){
|
||||
|
||||
document.getElementById('info').innerHTML = html;
|
||||
}
|
||||
this.set_canvas_size = function(){
|
||||
this.set_canvas_size = function(repaint){
|
||||
var W = round(WIDTH);
|
||||
var H = round(W / RATIO);
|
||||
|
||||
this.resize_canvas("canvas_back");
|
||||
DRAW.draw_background(canvas_back);
|
||||
DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
this.resize_canvas("canvas_front", false);
|
||||
for(i in LAYERS)
|
||||
this.resize_canvas(LAYERS[i].name, true);
|
||||
for(i in LAYERS){
|
||||
if(repaint === false)
|
||||
this.resize_canvas(LAYERS[i].name, false);
|
||||
else
|
||||
this.resize_canvas(LAYERS[i].name, true);
|
||||
}
|
||||
|
||||
document.getElementById('resize-w').style.marginLeft = (106+W)+"px";
|
||||
document.getElementById('resize-w').style.marginTop = (1+H/2)+"px";
|
||||
|
||||
42
js/main.js
42
js/main.js
@ -1,23 +1,25 @@
|
||||
/*
|
||||
TODO:
|
||||
git
|
||||
Hermite
|
||||
http://stackoverflow.com/questions/2303690/resizing-an-image-in-an-html5-canvas
|
||||
http://bvdwolf.home.xs4all.nl/main/foto/down_sample/down_sample.htm
|
||||
Differences
|
||||
*/
|
||||
|
||||
var MAIN = new MAIN_CLASS();
|
||||
var POP = new popup(WIDTH, HEIGHT);
|
||||
document.onload = MAIN.init(true);
|
||||
|
||||
function MAIN_CLASS(){
|
||||
this.grid = false;
|
||||
this.TRANSPARENCY = true;
|
||||
|
||||
var LAYERS_ARCHIVE = [{}, {}, {}];
|
||||
var LAYERS_ARCHIVE_REDO = {};
|
||||
var LAYERS_ARCHIVE = [{}, {}, {}];
|
||||
var undo_level = 0;
|
||||
|
||||
this.init = function(first_load){
|
||||
if(first_load===true)
|
||||
if(first_load===true){
|
||||
TOOLS.draw_helpers();
|
||||
POP.height_mini = Math.round(POP.width_mini * HEIGHT / WIDTH);
|
||||
}
|
||||
CON.autosize = true;
|
||||
TOOLS.EXIF = false;
|
||||
TOOLS.select_data = false;
|
||||
@ -27,13 +29,18 @@ function MAIN_CLASS(){
|
||||
canvas_main.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
LAYER.layer_add("Background");
|
||||
LAYER.set_canvas_size();
|
||||
DRAW.draw_background(canvas_back);
|
||||
DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
document.getElementById("main_colour").style.backgroundColor = COLOUR;
|
||||
document.getElementById("canvas_preview").width = DRAW.PREVIEW_SIZE.w;
|
||||
document.getElementById("canvas_preview").height = DRAW.PREVIEW_SIZE.h;
|
||||
var color_rgb = HELPER.hex2rgb(COLOUR);
|
||||
document.getElementById("rgb_r").value = color_rgb.r;
|
||||
document.getElementById("rgb_g").value = color_rgb.g;
|
||||
document.getElementById("rgb_b").value = color_rgb.b;
|
||||
document.getElementById("rgb_a").value = ALPHA;
|
||||
DRAW.redraw_preview();
|
||||
}
|
||||
this.save_state = function(){ //log('save...');
|
||||
this.save_state = function(){
|
||||
undo_level = 0;
|
||||
j = 0;
|
||||
|
||||
@ -49,12 +56,12 @@ function MAIN_CLASS(){
|
||||
for(var i in LAYERS)
|
||||
LAYERS_ARCHIVE[j].data[LAYERS[i].name] = document.getElementById(LAYERS[i].name).getContext("2d").getImageData(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
//supports 3 levels undo system
|
||||
this.undo = function(){ //log('loading...');
|
||||
//supports 3 levels undo system - more levels requires more memory - max 1 gb?
|
||||
this.undo = function(){
|
||||
if(LAYERS_ARCHIVE.length == 0) return false;
|
||||
j = undo_level;
|
||||
undo_level++;
|
||||
if(LAYERS_ARCHIVE[j] == undefined) return false;
|
||||
if(LAYERS_ARCHIVE[j] == undefined || LAYERS_ARCHIVE[j].width == undefined) return false;
|
||||
if(WIDTH != LAYERS_ARCHIVE[j].width || HEIGHT != LAYERS_ARCHIVE[j].height){
|
||||
WIDTH = LAYERS_ARCHIVE[j].width;
|
||||
HEIGHT = LAYERS_ARCHIVE[j].height;
|
||||
@ -63,12 +70,6 @@ function MAIN_CLASS(){
|
||||
return true; //size changed, cant undo
|
||||
}
|
||||
|
||||
//save current state
|
||||
LAYERS_ARCHIVE_REDO = {};
|
||||
LAYERS_ARCHIVE_REDO.data = {};
|
||||
for(var i in LAYERS)
|
||||
LAYERS_ARCHIVE_REDO.data[LAYERS[i].name] = document.getElementById(LAYERS[i].name).getContext("2d").getImageData(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
//undo
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS_ARCHIVE[j].data[LAYERS[i].name] != undefined)
|
||||
@ -76,13 +77,6 @@ function MAIN_CLASS(){
|
||||
}
|
||||
DRAW.zoom();
|
||||
}
|
||||
this.redo = function(){
|
||||
if(LAYERS_ARCHIVE_REDO.data == undefined) return false;
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS_ARCHIVE_REDO.data[LAYERS[i].name] != undefined)
|
||||
document.getElementById(LAYERS[i].name).getContext("2d").putImageData(LAYERS_ARCHIVE_REDO.data[LAYERS[i].name], 0, 0);
|
||||
}
|
||||
}
|
||||
this.load_xml = function(data){
|
||||
var xml = $.parseXML(data);
|
||||
w = $(xml).find("width").text();
|
||||
|
||||
@ -2,7 +2,6 @@ var MENU = new MENU_CLASS();
|
||||
|
||||
function MENU_CLASS(){
|
||||
this.last_menu = '';
|
||||
|
||||
var PASTE_DATA = false;
|
||||
|
||||
this.do_menu = function(name){
|
||||
@ -12,8 +11,29 @@ function MENU_CLASS(){
|
||||
|
||||
//new
|
||||
if(name == 'file_new'){
|
||||
ZOOM = 100;
|
||||
MAIN.init();
|
||||
//ZOOM = 100;
|
||||
//MAIN.init();
|
||||
|
||||
POP.add({name: "width", title: "Width:", value: WIDTH, });
|
||||
POP.add({name: "height", title: "Height:", value: HEIGHT, });
|
||||
POP.add({name: "transparency", title: "Transparent:", values: ['Yes', 'No'],});
|
||||
POP.show('New file...', function(response){
|
||||
var width = parseInt(response.width);
|
||||
var height = parseInt(response.height);
|
||||
var transparency = response.transparency;
|
||||
|
||||
if(response.transparency == 'Yes')
|
||||
MAIN.TRANSPARENCY = true;
|
||||
else
|
||||
MAIN.TRANSPARENCY = false;
|
||||
//DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
|
||||
ZOOM = 100;
|
||||
WIDTH = width;
|
||||
HEIGHT = height;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
MAIN.init();
|
||||
});
|
||||
}
|
||||
//open
|
||||
else if(name == 'file_open'){
|
||||
@ -37,10 +57,6 @@ function MENU_CLASS(){
|
||||
else if(name == 'edit_undo'){
|
||||
MAIN.undo();
|
||||
}
|
||||
//redo
|
||||
else if(name == 'edit_redo'){
|
||||
MAIN.redo();
|
||||
}
|
||||
//cut
|
||||
else if(name == 'edit_cut'){
|
||||
MAIN.save_state();
|
||||
@ -81,11 +97,23 @@ function MENU_CLASS(){
|
||||
|
||||
//===== Image ==========================================================
|
||||
|
||||
//information
|
||||
else if(name == 'image_information'){
|
||||
var colors = TOOLS.unique_colors_count(canvas_active(true));
|
||||
colors = HELPER.format("#,##0.####", colors);
|
||||
|
||||
POP.add({title: "Width:", value: WIDTH, });
|
||||
POP.add({title: "Height:", value: HEIGHT, });
|
||||
POP.add({title: "Unique colors:", value: colors, });
|
||||
//exif
|
||||
for(var i in TOOLS.EXIF)
|
||||
POP.add({title: i+":", value: TOOLS.EXIF[i], });
|
||||
POP.show('Information', '');
|
||||
}
|
||||
//size
|
||||
else if(name == 'image_size'){
|
||||
POP.add({name: "width", title: "Enter width:", value: WIDTH, });
|
||||
POP.add({name: "height", title: "Enter height:", value: HEIGHT, });
|
||||
POP.add({name: "transparency", title: "Transparent:", values: ['Yes', 'No'],});
|
||||
POP.add({name: "width", title: "Width:", value: WIDTH, });
|
||||
POP.add({name: "height", title: "Height:", value: HEIGHT, });
|
||||
POP.show('Attributes', this.resize_custom);
|
||||
}
|
||||
//trim
|
||||
@ -117,29 +145,17 @@ function MENU_CLASS(){
|
||||
}
|
||||
}
|
||||
//resize
|
||||
else if(name == 'image_resize'){
|
||||
POP.add({name: "width", title: "Enter new width:", value: WIDTH,});
|
||||
POP.add({name: "height",title: "Enter new height:", value: HEIGHT});
|
||||
POP.add({name: "mode", title: "Mode:", values: ["Resample - Lanczos", "Resize"],});
|
||||
POP.show('Resize', this.resize_layer);
|
||||
}
|
||||
else if(name == 'image_resize')
|
||||
MENU.resize_box();
|
||||
//rotate left
|
||||
else if(name == 'image_rotate_left'){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_resize_doc(270, WIDTH, HEIGHT);
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
MENU.rotate_layer({angle: 270}, layer, WIDTH, HEIGHT);
|
||||
}
|
||||
MENU.rotate_layer({angle: 270}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//rotate right
|
||||
else if(name == 'image_rotate_right'){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_resize_doc(90, WIDTH, HEIGHT);
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
MENU.rotate_layer({angle: 90}, layer, WIDTH, HEIGHT);
|
||||
}
|
||||
MENU.rotate_layer({angle: 90}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//rotate
|
||||
else if(name == 'image_rotate'){
|
||||
@ -147,10 +163,7 @@ function MENU_CLASS(){
|
||||
POP.show('Rotate', function(response){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_resize_doc(response.angle, WIDTH, HEIGHT);
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
MENU.rotate_layer(response, layer, WIDTH, HEIGHT);
|
||||
}
|
||||
MENU.rotate_layer(response, canvas_active(), WIDTH, HEIGHT);
|
||||
},
|
||||
function(response, canvas_preview, w, h){
|
||||
MENU.rotate_layer(response, canvas_preview, w, h);
|
||||
@ -159,40 +172,36 @@ function MENU_CLASS(){
|
||||
//vertical flip
|
||||
else if(name == 'image_vflip'){
|
||||
MAIN.save_state();
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(document.getElementById(LAYERS[i].name), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
layer.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
layer.save();
|
||||
layer.scale(-1, 1);
|
||||
layer.drawImage(tempCanvas, -WIDTH, 0);
|
||||
layer.restore();
|
||||
}
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(canvas_active(true), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().save();
|
||||
canvas_active().scale(-1, 1);
|
||||
canvas_active().drawImage(tempCanvas, -WIDTH, 0);
|
||||
canvas_active().restore();
|
||||
}
|
||||
//horizontal flip
|
||||
else if(name == 'image_hflip'){
|
||||
MAIN.save_state();
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(document.getElementById(LAYERS[i].name), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
layer.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
layer.save();
|
||||
layer.scale(1, -1);
|
||||
layer.drawImage(tempCanvas, 0, -HEIGHT);
|
||||
layer.restore();
|
||||
}
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(canvas_active(true), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().save();
|
||||
canvas_active().scale(1, -1);
|
||||
canvas_active().drawImage(tempCanvas, 0, -HEIGHT);
|
||||
canvas_active().restore();
|
||||
}
|
||||
//histogram
|
||||
else if(name == 'image_histogram'){
|
||||
TOOLS.histogram();
|
||||
}
|
||||
//color corrections
|
||||
else if(name == 'image_colors'){
|
||||
@ -207,27 +216,24 @@ function MENU_CLASS(){
|
||||
|
||||
POP.show('Brightness Contrast', function(user_response){
|
||||
MAIN.save_state();
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param_red = parseInt(user_response.param_red);
|
||||
var param_green = parseInt(user_response.param_green);
|
||||
var param_blue = parseInt(user_response.param_blue);
|
||||
var param_h = parseInt(user_response.param_h);
|
||||
var param_s = parseInt(user_response.param_s);
|
||||
var param_l = parseInt(user_response.param_l);
|
||||
|
||||
var imageData = layer.getImageData(0, 0, WIDTH, HEIGHT);
|
||||
//Brightness/Contrast
|
||||
var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, param1, param2);
|
||||
//RGB corrections
|
||||
var filtered = ImageFilters.ColorTransformFilter(filtered, 1, 1, 1, 1, param_red, param_green, param_blue, 1);
|
||||
//hue/saturation/luminance
|
||||
var filtered = ImageFilters.HSLAdjustment(filtered, param_h, param_s, param_l);
|
||||
layer.putImageData(filtered, 0, 0);
|
||||
DRAW.zoom();
|
||||
}
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param_red = parseInt(user_response.param_red);
|
||||
var param_green = parseInt(user_response.param_green);
|
||||
var param_blue = parseInt(user_response.param_blue);
|
||||
var param_h = parseInt(user_response.param_h);
|
||||
var param_s = parseInt(user_response.param_s);
|
||||
var param_l = parseInt(user_response.param_l);
|
||||
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
//Brightness/Contrast
|
||||
var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, param1, param2);
|
||||
//RGB corrections
|
||||
var filtered = ImageFilters.ColorTransformFilter(filtered, 1, 1, 1, 1, param_red, param_green, param_blue, 1);
|
||||
//hue/saturation/luminance
|
||||
var filtered = ImageFilters.HSLAdjustment(filtered, param_h, param_s, param_l);
|
||||
canvas_active().putImageData(filtered, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
@ -249,28 +255,44 @@ function MENU_CLASS(){
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
//auto adjust colors
|
||||
else if(name == 'image_auto_adjust'){
|
||||
MAIN.save_state();
|
||||
DRAW.auto_adjust(canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//enchance colors
|
||||
else if(name == 'image_decrease_colors'){
|
||||
POP.add({name: "param1", title: "Colors:", value: "10", range: [2, 100], });
|
||||
POP.add({name: "param2", title: "Dithering:", values: ["Yes", "No"], });
|
||||
POP.add({name: "param3", title: "Greyscale:", values: ["Yes", "No"], value: "No", });
|
||||
POP.show('Decrease colors', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
if(user_response.param2 == 'Yes') param2 = true; else param2 = false;
|
||||
if(user_response.param3 == 'Yes') param3 = true; else param3 = false;
|
||||
|
||||
DRAW.decrease_colors(canvas_active(), WIDTH, HEIGHT, param1, param2, param3);
|
||||
DRAW.zoom();
|
||||
});
|
||||
}
|
||||
//negative
|
||||
else if(name == 'image_negative'){
|
||||
MAIN.save_state();
|
||||
for(var i in LAYERS){
|
||||
var layer = document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
|
||||
if(TOOLS.select_data == false)
|
||||
var imageData = layer.getImageData(0, 0, WIDTH, HEIGHT);
|
||||
else
|
||||
var imageData = layer.getImageData(TOOLS.select_data.x, TOOLS.select_data.y, TOOLS.select_data.w, TOOLS.select_data.h);
|
||||
var pixels = imageData.data;
|
||||
for (var i = 0; i < pixels.length; i += 4){
|
||||
pixels[i] = 255 - pixels[i]; // red
|
||||
pixels[i+1] = 255 - pixels[i+1]; // green
|
||||
pixels[i+2] = 255 - pixels[i+2]; // blue
|
||||
}
|
||||
//save
|
||||
if(TOOLS.select_data == false)
|
||||
layer.putImageData(imageData, 0, 0);
|
||||
else
|
||||
layer.putImageData(imageData, TOOLS.select_data.x, TOOLS.select_data.y);
|
||||
if(TOOLS.select_data == false)
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
else
|
||||
var imageData = canvas_active().getImageData(TOOLS.select_data.x, TOOLS.select_data.y, TOOLS.select_data.w, TOOLS.select_data.h);
|
||||
var pixels = imageData.data;
|
||||
for (var i = 0; i < pixels.length; i += 4){
|
||||
pixels[i] = 255 - pixels[i]; // red
|
||||
pixels[i+1] = 255 - pixels[i+1]; // green
|
||||
pixels[i+2] = 255 - pixels[i+2]; // blue
|
||||
}
|
||||
//save
|
||||
if(TOOLS.select_data == false)
|
||||
canvas_active().putImageData(imageData, 0, 0);
|
||||
else
|
||||
canvas_active().putImageData(imageData, TOOLS.select_data.x, TOOLS.select_data.y)
|
||||
}
|
||||
//grid
|
||||
else if(name == 'image_grid'){
|
||||
@ -288,7 +310,7 @@ function MENU_CLASS(){
|
||||
else{
|
||||
MAIN.grid = false;
|
||||
canvas_back.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
DRAW.draw_background(canvas_back);
|
||||
DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,151 +361,52 @@ function MENU_CLASS(){
|
||||
else if(name == 'layer_opacity'){
|
||||
LAYER.set_alpha();
|
||||
}
|
||||
//color corrections
|
||||
else if(name == 'layer_colors'){
|
||||
POP.add({name: "param1", title: "Brightness:", value: "0", range: [-100, 100], });
|
||||
POP.add({name: "param2", title: "Contrast:", value: "0", range: [-100, 100], });
|
||||
POP.add({name: "param_red", title: "Red offset:", value: "0", range: [-255, 255], });
|
||||
POP.add({name: "param_green", title: "Green offset:", value: "0", range: [-255, 255], });
|
||||
POP.add({name: "param_blue", title: "Blue offset:", value: "0", range: [-255, 255], });
|
||||
POP.add({name: "param_h", title: "Hue:", value: "0", range: [-180, 180], });
|
||||
POP.add({name: "param_s", title: "Saturation:", value: "0", range: [-100, 100], });
|
||||
POP.add({name: "param_l", title: "Luminance:", value: "0", range: [-100, 100], });
|
||||
|
||||
POP.show('Brightness Contrast', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param_red = parseInt(user_response.param_red);
|
||||
var param_green = parseInt(user_response.param_green);
|
||||
var param_blue = parseInt(user_response.param_blue);
|
||||
var param_h = parseInt(user_response.param_h);
|
||||
var param_s = parseInt(user_response.param_s);
|
||||
var param_l = parseInt(user_response.param_l);
|
||||
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
//Brightness/Contrast
|
||||
var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, param1, param2);
|
||||
//RGB corrections
|
||||
var filtered = ImageFilters.ColorTransformFilter(filtered, 1, 1, 1, 1, param_red, param_green, param_blue, 1);
|
||||
//hue/saturation/luminance
|
||||
var filtered = ImageFilters.HSLAdjustment(filtered, param_h, param_s, param_l);
|
||||
canvas_active().putImageData(filtered, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param_red = parseInt(user_response.param_red);
|
||||
var param_green = parseInt(user_response.param_green);
|
||||
var param_blue = parseInt(user_response.param_blue);
|
||||
var param_h = parseInt(user_response.param_h);
|
||||
var param_s = parseInt(user_response.param_s);
|
||||
var param_l = parseInt(user_response.param_l);
|
||||
|
||||
var imageData = canvas_preview.getImageData(0, 0, w, h);
|
||||
//Brightness/Contrast
|
||||
var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, param1, param2); //add effect
|
||||
//RGB corrections
|
||||
var filtered = ImageFilters.ColorTransformFilter(filtered, 1, 1, 1, 1, param_red, param_green, param_blue, 1);
|
||||
//hue/saturation/luminance
|
||||
var filtered = ImageFilters.HSLAdjustment(filtered, param_h, param_s, param_l);
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
//rotate left
|
||||
else if(name == 'layer_rotate_left'){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_layer({angle: 270}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//rotate right
|
||||
else if(name == 'layer_rotate_right'){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_layer({angle: 90}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//rotate
|
||||
else if(name == 'layer_rotate'){
|
||||
POP.add({name: "angle", title: "Enter angle (0-360):", value: 90, range: [0, 360], });
|
||||
POP.show('Rotate', function(response){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_layer(response, canvas_active(), WIDTH, HEIGHT);
|
||||
},
|
||||
function(response, canvas_preview, w, h){
|
||||
MENU.rotate_layer(response, canvas_preview, w, h);
|
||||
});
|
||||
}
|
||||
//vertical flip
|
||||
else if(name == 'layer_vflip'){
|
||||
MAIN.save_state();
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(canvas_active(true), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().save();
|
||||
canvas_active().scale(-1, 1);
|
||||
canvas_active().drawImage(tempCanvas, -WIDTH, 0);
|
||||
canvas_active().restore();
|
||||
}
|
||||
//horizontal flip
|
||||
else if(name == 'layer_hflip'){
|
||||
MAIN.save_state();
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
tempCtx.drawImage(canvas_active(true), 0, 0, WIDTH, HEIGHT);
|
||||
//flip
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().save();
|
||||
canvas_active().scale(1, -1);
|
||||
canvas_active().drawImage(tempCanvas, 0, -HEIGHT);
|
||||
canvas_active().restore();
|
||||
}
|
||||
//trim
|
||||
else if(name == 'layer_trim'){
|
||||
MAIN.save_state();
|
||||
DRAW.trim(LAYERS[LAYER.layer_active].name, true);
|
||||
}
|
||||
//resize
|
||||
else if(name == 'layer_resize'){
|
||||
POP.add({name: "width", title: "Enter new width:", value: WIDTH,});
|
||||
POP.add({name: "height",title: "Enter new height:", value: HEIGHT});
|
||||
POP.add({name: "mode", title: "Mode:", values: ["Resample - Lanczos", "Resize"],});
|
||||
POP.show('Resize', this.resize_layer);
|
||||
}
|
||||
//negative
|
||||
else if(name == 'layer_negative'){
|
||||
MAIN.save_state();
|
||||
if(TOOLS.select_data == false)
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
else
|
||||
var imageData = canvas_active().getImageData(TOOLS.select_data.x, TOOLS.select_data.y, TOOLS.select_data.w, TOOLS.select_data.h);
|
||||
var pixels = imageData.data;
|
||||
for (var i = 0; i < pixels.length; i += 4){
|
||||
pixels[i] = 255 - pixels[i]; // red
|
||||
pixels[i+1] = 255 - pixels[i+1]; // green
|
||||
pixels[i+2] = 255 - pixels[i+2]; // blue
|
||||
}
|
||||
//save
|
||||
if(TOOLS.select_data == false)
|
||||
canvas_active().putImageData(imageData, 0, 0);
|
||||
else
|
||||
canvas_active().putImageData(imageData, TOOLS.select_data.x, TOOLS.select_data.y)
|
||||
}
|
||||
else if(name == 'layer_resize')
|
||||
MENU.resize_box();
|
||||
//clear
|
||||
else if(name == 'layer_clear'){
|
||||
MAIN.save_state();
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
//sprites
|
||||
else if(name == 'layer_sprites'){
|
||||
POP.add({name: "param1", title: "Offset:", value: "50", values: ["0", "10", "50", "100"] });
|
||||
POP.show('Sprites', function(response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(response.param1);
|
||||
TOOLS.generate_sprites(param1);
|
||||
});
|
||||
}
|
||||
//show differences
|
||||
else if(name == 'layer_differences'){
|
||||
if(parseInt(LAYER.layer_active) + 1 >= LAYERS.length){
|
||||
POP.add({title: "Error:", value: 'This can not be last layer', });
|
||||
POP.show('Error', '');
|
||||
return false;
|
||||
}
|
||||
|
||||
POP.add({name: "param1", title: "Sensitivity:", value: "0", range: [0, 255] });
|
||||
POP.show('Differences', function(response){
|
||||
var param1 = parseInt(response.param1);
|
||||
TOOLS.calc_differences(param1);
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
TOOLS.calc_differences(param1, canvas_preview, w, h);
|
||||
});
|
||||
}
|
||||
//merge
|
||||
else if(name == 'layer_merge_down'){
|
||||
MAIN.save_state();
|
||||
vlayer_active = parseInt(layer_active);
|
||||
if(LAYER.layer_active + 1 > LAYERS.length){
|
||||
POP.add({title: "Error:", value: 'This is last layer', });
|
||||
vlayer_active = parseInt(LAYER.layer_active);
|
||||
if(parseInt(LAYER.layer_active) + 1 >= LAYERS.length){
|
||||
POP.add({title: "Error:", value: 'This can not be last layer', });
|
||||
POP.show('Error', '');
|
||||
return false;
|
||||
}
|
||||
@ -502,18 +425,6 @@ function MENU_CLASS(){
|
||||
LAYER.layer_remove(LAYER.layer_active+1);
|
||||
LAYER.layer_renew();
|
||||
}
|
||||
//exif
|
||||
else if(name == 'image_exif'){
|
||||
if(TOOLS.EXIF === false){
|
||||
POP.add({title: "Error:", value: 'EXIF info not found.', });
|
||||
POP.show('EXIF info', '');
|
||||
}
|
||||
else{
|
||||
for(var i in TOOLS.EXIF)
|
||||
POP.add({title: i+":", value: TOOLS.EXIF[i], });
|
||||
POP.show('EXIF info', '');
|
||||
}
|
||||
}
|
||||
//flatten all
|
||||
else if(name == 'layer_flatten'){
|
||||
MAIN.save_state();
|
||||
@ -521,7 +432,7 @@ function MENU_CLASS(){
|
||||
tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = WIDTH;
|
||||
tmp_data.height = HEIGHT;
|
||||
for(var i=LAYERS.length - 1; i > 0; i--){
|
||||
for(var i=1; i < LAYERS.length; i++){
|
||||
//copy
|
||||
LAYER.layer_active = i;
|
||||
tmp_data.getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
@ -530,7 +441,8 @@ function MENU_CLASS(){
|
||||
//paste
|
||||
LAYER.layer_active = 0;
|
||||
canvas_active().drawImage(tmp_data, 0, 0);
|
||||
|
||||
}
|
||||
for(var i=LAYERS.length - 1; i > 0; i--){
|
||||
//delete layer
|
||||
LAYER.layer_active = i;
|
||||
LAYER.layer_remove(LAYER.layer_active);
|
||||
@ -541,8 +453,19 @@ function MENU_CLASS(){
|
||||
//===== Effects ========================================================
|
||||
|
||||
else if(name == 'effects_bw'){
|
||||
MAIN.save_state();
|
||||
DRAW.effect_bw(canvas_active(), WIDTH, HEIGHT);
|
||||
POP.add({name: "param1", title: "Level:", value: "125", range: [0, 255], });
|
||||
POP.show('Black and White', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
|
||||
DRAW.effect_bw(canvas_active(), WIDTH, HEIGHT, param1);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
|
||||
DRAW.effect_bw(canvas_preview, w, h, param1);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_BoxBlur'){
|
||||
POP.add({name: "param1", title: "H Radius:", value: "3", range: [1, 20], });
|
||||
@ -604,6 +527,46 @@ function MENU_CLASS(){
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_zoomblur'){
|
||||
POP.add({name: "param1", title: "Strength:", value: "0.3", range: [0, 1], step: 0.01, });
|
||||
POP.add({name: "param2", title: "Center x:", value: round(WIDTH/2), range: [0, WIDTH], });
|
||||
POP.add({name: "param3", title: "Center y:", value: round(HEIGHT/2), range: [0, HEIGHT], });
|
||||
POP.show('Blur-Zoom', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_active(true));
|
||||
filter.draw(texture).zoomBlur(param2, param3, param1).update(); //effect
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().drawImage(filter, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
|
||||
//recalc param by size
|
||||
param2 = param2 / WIDTH * w;
|
||||
param3 = param3 / HEIGHT * h;
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_preview.getImageData(0, 0, w, h));
|
||||
filter.draw(texture).zoomBlur(param2, param3, param1).update(); //effect
|
||||
canvas_preview.drawImage(filter, 0, 0);
|
||||
|
||||
//draw circle
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.strokeStyle = "#ff0000";
|
||||
canvas_preview.lineWidth = 1;
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.arc(param2, param3, 5, 0,Math.PI*2,true);
|
||||
canvas_preview.stroke();
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_BrightnessContrast'){
|
||||
POP.add({name: "param1", title: "Brightness:", value: "0", range: [-100, 100], });
|
||||
POP.add({name: "param2", title: "Contrast:", value: "0", range: [-100, 100], });
|
||||
@ -657,17 +620,13 @@ function MENU_CLASS(){
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_Channels'){
|
||||
POP.add({name: "param1", title: "Red:", value: "1", range: [0, 1], });
|
||||
POP.add({name: "param2", title: "Green:", value: "0", range: [0, 1], });
|
||||
POP.add({name: "param3", title: "Blue:", value: "0", range: [0, 1], });
|
||||
POP.add({name: "param1", title: "Channel:", values: ["Red", "Green", "Blue"],});
|
||||
POP.show('Channels', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
var channel = 1;
|
||||
if(param2 == 1) channel = 2;
|
||||
if(param3 == 1) channel = 3;
|
||||
var param1 = user_response.param1;
|
||||
if(param1 == "Red") channel = 1;
|
||||
else if(param1 == "Green") channel = 2;
|
||||
else if(param1 == "Blue") channel = 3;
|
||||
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var filtered = ImageFilters.Channels(imageData, channel); //add effect
|
||||
@ -675,22 +634,16 @@ function MENU_CLASS(){
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
var channel = 1;
|
||||
if(param2 == 1) channel = 2;
|
||||
if(param3 == 1) channel = 3;
|
||||
var param1 = user_response.param1;
|
||||
if(param1 == "Red") channel = 1;
|
||||
else if(param1 == "Green") channel = 2;
|
||||
else if(param1 == "Blue") channel = 3;
|
||||
var imageData = canvas_preview.getImageData(0, 0, w, h);
|
||||
var filtered = ImageFilters.Channels(imageData, channel); //add effect
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_ColorTransformFilter'){
|
||||
/*POP.add({name: "param1", title: "Red multiplier:", value: "1", range: [0, 5], });
|
||||
POP.add({name: "param2", title: "Green multiplier:", value: "1", range: [0, 5], });
|
||||
POP.add({name: "param3", title: "Blue multiplier:", value: "1", range: [0, 5], });
|
||||
POP.add({name: "param4", title: "Alpha multiplier:", value: "1", range: [0, 5], });*/
|
||||
POP.add({name: "param5", title: "Red offset:", value: "0", range: [-255, 255], });
|
||||
POP.add({name: "param6", title: "Green offset:", value: "0", range: [-255, 255], });
|
||||
POP.add({name: "param7", title: "Blue offset:", value: "0", range: [-255, 255], });
|
||||
@ -717,6 +670,57 @@ function MENU_CLASS(){
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_colorize'){
|
||||
var colorize_data;
|
||||
|
||||
POP.add({name: "param1", title: "Power:", value: "3", range: [1, 10], });
|
||||
POP.add({name: "param2", title: "Limit:", value: "30", range: [10, 200], });
|
||||
POP.add({name: "param3", title: "Dithering:", values: ["Yes", "No"], });
|
||||
POP.add({title: "Shortcut:", value: "C", });
|
||||
POP.preview_in_main = true;
|
||||
POP.show('Auto colorize', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
if(user_response.param3 == 'Yes') param3 = true; else param3 = false;
|
||||
|
||||
DRAW.colorize(canvas_active(), WIDTH, HEIGHT, param1, param2, param3, colorize_data);
|
||||
DRAW.zoom();
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
},
|
||||
function(user_response){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
if(user_response.param3 == 'Yes') param3 = true; else param3 = false;
|
||||
|
||||
colorize_data = DRAW.colorize(canvas_preview, WIDTH, HEIGHT, param1, param2, param3, true);
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_front.drawImage(canvas_active(true), 0, 0);
|
||||
DRAW.colorize(canvas_front, WIDTH, HEIGHT, param1, param2, param3, colorize_data);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_denoise'){
|
||||
POP.add({name: "param1", title: "Exponent:", value: "20", range: [0, 50], });
|
||||
POP.show('Denoise', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_active(true));
|
||||
filter.draw(texture).denoise(param1).update(); //effect
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().drawImage(filter, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_preview.getImageData(0, 0, w, h));
|
||||
filter.draw(texture).denoise(param1).update(); //effect
|
||||
canvas_preview.drawImage(filter, 0, 0);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_Desaturate'){
|
||||
MAIN.save_state();
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
@ -872,6 +876,68 @@ function MENU_CLASS(){
|
||||
canvas_preview.putImageData(filtered, 0, 0);
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_perspective'){
|
||||
POP.add({name: "param1", title: "X1:", value: WIDTH/4, range: [0, WIDTH], });
|
||||
POP.add({name: "param2", title: "Y1:", value: "0", range: [0, HEIGHT], });
|
||||
POP.add({name: "param3", title: "X2:", value: WIDTH*3/4, range: [0, WIDTH], });
|
||||
POP.add({name: "param4", title: "Y2:", value: "0", range: [0, HEIGHT], });
|
||||
POP.add({name: "param5", title: "X3:", value: WIDTH, range: [0, WIDTH], });
|
||||
POP.add({name: "param6", title: "Y3:", value: HEIGHT, range: [0, HEIGHT], });
|
||||
POP.add({name: "param7", title: "X4:", value: "0", range: [0, WIDTH], });
|
||||
POP.add({name: "param8", title: "Y4:", value: HEIGHT, range: [0, HEIGHT], });
|
||||
POP.show('Blur-Zoom', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
var param4 = parseInt(user_response.param4);
|
||||
var param5 = parseInt(user_response.param5);
|
||||
var param6 = parseInt(user_response.param6);
|
||||
var param7 = parseInt(user_response.param7);
|
||||
var param8 = parseInt(user_response.param8);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_active(true));
|
||||
filter.draw(texture).perspective([0,0,WIDTH,0,WIDTH,HEIGHT,0,HEIGHT], [param1,param2,param3,param4,param5,param6,param7,param8]).update(); //effect
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().drawImage(filter, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseInt(user_response.param1);
|
||||
var param2 = parseInt(user_response.param2);
|
||||
var param3 = parseInt(user_response.param3);
|
||||
var param4 = parseInt(user_response.param4);
|
||||
var param5 = parseInt(user_response.param5);
|
||||
var param6 = parseInt(user_response.param6);
|
||||
var param7 = parseInt(user_response.param7);
|
||||
var param8 = parseInt(user_response.param8);
|
||||
|
||||
param1 = param1 / WIDTH * w;
|
||||
param2 = param2 / HEIGHT * h;
|
||||
param3 = param3 / WIDTH * w;
|
||||
param4 = param4 / HEIGHT * h;
|
||||
param5 = param5 / WIDTH * w;
|
||||
param6 = param6 / HEIGHT * h;
|
||||
param7 = param7 / WIDTH * w;
|
||||
param8 = param8 / HEIGHT * h;
|
||||
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_preview.getImageData(0, 0, w, h));
|
||||
canvas_preview.clearRect(0, 0, w, h);
|
||||
filter.draw(texture).perspective([0,0,w,0,w,h,0,h], [param1,param2,param3,param4,param5,param6,param7,param8]).update(); //effect
|
||||
canvas_preview.drawImage(filter, 0, 0);
|
||||
|
||||
//draw circle
|
||||
/*canvas_preview.beginPath();
|
||||
canvas_preview.strokeStyle = "#ff0000";
|
||||
canvas_preview.lineWidth = 1;
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.arc(param2, param3, 5, 0,Math.PI*2,true);
|
||||
canvas_preview.stroke();*/
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_Posterize'){
|
||||
POP.add({name: "param1", title: "Levels:", value: "8", range: [2, 32], });
|
||||
POP.show('Posterize', function(user_response){
|
||||
@ -993,29 +1059,64 @@ function MENU_CLASS(){
|
||||
canvas_preview.stroke();
|
||||
});
|
||||
}
|
||||
else if(name == 'effects_vignette'){
|
||||
POP.add({name: "param1", title: "Size:", value: "0.5", range: [0, 1], step: 0.01, });
|
||||
POP.add({name: "param2", title: "Amount:", value: "0.5", range: [0, 1], step: 0.01, });
|
||||
POP.show('Vignette', function(user_response){
|
||||
MAIN.save_state();
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
var param2 = parseFloat(user_response.param2);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_active(true));
|
||||
filter.draw(texture).vignette(param1, param2).update(); //effect
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().drawImage(filter, 0, 0);
|
||||
DRAW.zoom();
|
||||
},
|
||||
function(user_response, canvas_preview, w, h){
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
var param2 = parseFloat(user_response.param2);
|
||||
|
||||
var filter = fx.canvas();
|
||||
var texture = filter.texture(canvas_preview.getImageData(0, 0, w, h));
|
||||
filter.draw(texture).vignette(param1, param2).update(); //effect
|
||||
canvas_preview.drawImage(filter, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
//===== Help ===========================================================
|
||||
|
||||
//shortcuts
|
||||
else if(name == 'help_shortcuts'){
|
||||
POP.add({title: "Del:", value: 'Delete selection', });
|
||||
POP.add({title: "G:", value: 'Grid on/off', });
|
||||
POP.add({title: "L:", value: 'Rotate left', });
|
||||
POP.add({title: "O:", value: 'Open file(s)', });
|
||||
POP.add({title: "R:", value: 'Rotate right', });
|
||||
POP.add({title: "S:", value: 'Save', });
|
||||
POP.add({title: "T:", value: 'Trim', });
|
||||
POP.add({title: "CTRL + Z:", value: 'Undo', });
|
||||
POP.add({title: "CTRL + A:", value: 'Select all', });
|
||||
POP.add({title: "CTRL + X:", value: 'Cut', });
|
||||
POP.add({title: "CTRL + C:", value: 'Copy', });
|
||||
POP.add({title: "CTRL + V:", value: 'Paste', });
|
||||
POP.add({title: "Arrow keys:", value: 'Move active layer by 10px', });
|
||||
POP.add({title: "CTRL + Arrow keys:", value: 'Move active layer by 50px', });
|
||||
POP.add({title: "SHIFT + Arrow keys:",value: 'Move active layer by 1px', });
|
||||
POP.add({title: "Drag & Drop:", value: 'Imports images/xml data', });
|
||||
POP.add({title: "C", value: 'Colorize', });
|
||||
POP.add({title: "Del", value: 'Delete selection', });
|
||||
POP.add({title: "F", value: 'Aut oadjust colors', });
|
||||
POP.add({title: "G", value: 'Grid on/off', });
|
||||
POP.add({title: "L", value: 'Rotate left', });
|
||||
POP.add({title: "O", value: 'Open file(s)', });
|
||||
POP.add({title: "R", value: 'Resize', });
|
||||
POP.add({title: "S", value: 'Save', });
|
||||
POP.add({title: "T", value: 'Trim', });
|
||||
POP.add({title: "-", value: 'Zoom out', });
|
||||
POP.add({title: "+", value: 'Zoom in', });
|
||||
POP.add({title: "CTRL + Z", value: 'Undo', });
|
||||
POP.add({title: "CTRL + A", value: 'Select all', });
|
||||
POP.add({title: "CTRL + X", value: 'Cut', });
|
||||
POP.add({title: "CTRL + C", value: 'Copy', });
|
||||
POP.add({title: "CTRL + V", value: 'Paste', });
|
||||
POP.add({title: "Arrow keys", value: 'Move active layer by 10px', });
|
||||
POP.add({title: "CTRL + Arrow keys", value: 'Move active layer by 50px', });
|
||||
POP.add({title: "SHIFT + Arrow keys",value: 'Move active layer by 1px', });
|
||||
POP.add({title: "Drag & Drop", value: 'Imports images/xml data', });
|
||||
POP.show('Keyboard Shortcuts', '');
|
||||
}
|
||||
//credits
|
||||
else if(name == 'help_credits'){
|
||||
for(var i in CREDITS)
|
||||
POP.add({title: CREDITS[i].title, html: '<a href="'+CREDITS[i].link+'">'+CREDITS[i].name+'</a>', });
|
||||
POP.show('Credits', '');
|
||||
}
|
||||
//about
|
||||
else if(name == 'help_about'){
|
||||
POP.add({title: "Name:", value: "miniPaint "+VERSION, });
|
||||
@ -1039,13 +1140,6 @@ function MENU_CLASS(){
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
}
|
||||
else{
|
||||
if(user_response.transparency == 'Yes')
|
||||
MAIN.TRANSPARENCY = true;
|
||||
else
|
||||
MAIN.TRANSPARENCY = false;
|
||||
DRAW.draw_background(canvas_back);
|
||||
}
|
||||
}
|
||||
//prepare rotation - increase doc dimensions if needed
|
||||
this.rotate_resize_doc = function(angle, w, h){
|
||||
@ -1125,42 +1219,69 @@ function MENU_CLASS(){
|
||||
canvas_active().drawImage(PASTE_DATA, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
}
|
||||
this.resize_box = function(){
|
||||
POP.add({name: "width", title: "Enter new width:", value: WIDTH,});
|
||||
POP.add({name: "height",title: "Enter new height:", value: HEIGHT});
|
||||
POP.add({name: "mode", title: "Mode:", value: "Resample - Hermite", values: ["Resize", "Resample - Hermite"],});
|
||||
POP.add({name: "ratio",title: "Preserve ratio:", values: ["Yes", "No"]});
|
||||
POP.add({name: "preblur",title: "Pre-Blur:", values: ["Yes", "No"], value: "No", });
|
||||
POP.add({name: "sharpen",title: "Apply sharpen:", values: ["Yes", "No"], value: "No", });
|
||||
POP.show('Resize', MENU.resize_layer);
|
||||
}
|
||||
this.resize_layer = function(user_response){
|
||||
MAIN.save_state();
|
||||
var width = parseInt(user_response.width);
|
||||
var height = parseInt(user_response.height);
|
||||
var ratio_mode = user_response.ratio;
|
||||
var preblur = user_response.preblur;
|
||||
var sharpen = user_response.sharpen;
|
||||
if(isNaN(width) || width<1) return false;
|
||||
if(isNaN(height) || height<1) return false;
|
||||
|
||||
if(user_response.mode == "Resample - Lanczos"){
|
||||
var trim_details = DRAW.trim(LAYERS[LAYER.layer_active].name); //trim
|
||||
//if increasing size - use simple way - its good enough
|
||||
if(width > WIDTH || height > HEIGHT)
|
||||
user_response.mode = "Resize";
|
||||
|
||||
var new_w = WIDTH - trim_details.left - trim_details.right;
|
||||
var new_h = HEIGHT - trim_details.top - trim_details.bottom;
|
||||
var ratio_new = new_w/new_h;
|
||||
if(width / height > RATIO)
|
||||
width = round(height * ratio_new);
|
||||
//anti-artifacting?
|
||||
if(preblur == 'Yes'){
|
||||
var ratio_w = WIDTH / width;
|
||||
var ratio_h = HEIGHT / height;
|
||||
if(ratio_mode == 'Yes')
|
||||
var ratio_avg = Math.max(ratio_w, ratio_h);
|
||||
else
|
||||
height = round(width / ratio_new);
|
||||
if(width >= new_w){
|
||||
LAYER.resize_canvas(LAYERS[LAYER.layer_active].name, true);
|
||||
DRAW.zoom();
|
||||
return false;
|
||||
var ratio_avg = Math.min(ratio_w, ratio_h);
|
||||
var power = ratio_avg * 0.3;
|
||||
if(power > 0.6){
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var filtered = ImageFilters.GaussianBlur(imageData, power); //add effect
|
||||
canvas_active().putImageData(filtered, 0, 0);
|
||||
}
|
||||
|
||||
POP.hide();
|
||||
POP.add({title: "Status:", value: 'Resizing...', });
|
||||
POP.show('Status', '');
|
||||
|
||||
//resample using lanczos-2
|
||||
DRAW.thumbnailer(canvas_active(true), width, 3);
|
||||
}
|
||||
else{
|
||||
//Hermite - good and fast
|
||||
if(user_response.mode == "Resample - Hermite"){
|
||||
if(ratio_mode == 'Yes'){
|
||||
if(width / height > RATIO)
|
||||
width = Math.round(height * RATIO);
|
||||
else
|
||||
height = Math.round(width / RATIO);
|
||||
}
|
||||
if(width == WIDTH && height == HEIGHT) return false;
|
||||
if(width > WIDTH || height > HEIGHT) return false;
|
||||
|
||||
DRAW.resample_hermite(canvas_active(true), WIDTH, HEIGHT, width, height);
|
||||
if(MENU.last_menu != 'layer_resize')
|
||||
DRAW.trim();
|
||||
DRAW.zoom();
|
||||
}
|
||||
//simple resize
|
||||
else if(user_response.mode == "Resize"){
|
||||
//simple resize - FAST
|
||||
if(width / height > RATIO)
|
||||
width = height * RATIO;
|
||||
else
|
||||
height = width / RATIO;
|
||||
if(ratio_mode == 'Yes'){
|
||||
if(width / height > RATIO)
|
||||
width = round(height * RATIO);
|
||||
else
|
||||
height = round(width / RATIO);
|
||||
}
|
||||
|
||||
tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = WIDTH;
|
||||
@ -1178,10 +1299,16 @@ function MENU_CLASS(){
|
||||
LAYER.set_canvas_size();
|
||||
canvas_active().drawImage(tmp_data, 0, 0, width, height);
|
||||
}
|
||||
if(MENU.last_menu == 'image_resize')
|
||||
if(MENU.last_menu != 'layer_resize')
|
||||
DRAW.trim();
|
||||
DRAW.zoom();
|
||||
}
|
||||
//sharpen?
|
||||
if(sharpen == 'Yes'){
|
||||
var imageData = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var filtered = ImageFilters.Sharpen(imageData, 1); //add effect
|
||||
canvas_active().putImageData(filtered, 0, 0);
|
||||
}
|
||||
}
|
||||
this.save = function(user_response){
|
||||
fname = user_response.name;
|
||||
|
||||
198
js/popup.js
198
js/popup.js
@ -7,31 +7,36 @@ POP.add({title: 'title:', function: 'custom_function'});
|
||||
|
||||
POP.show('title', main_handler, 'preview_handler', 'onload_handler');
|
||||
*/
|
||||
var POP = new popup();
|
||||
|
||||
function popup(WIDTH, HEIGHT){
|
||||
function popup(){
|
||||
this.active = false;
|
||||
this.handler = '';
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
|
||||
var WIDTH = WIDTH;
|
||||
var HEIGHT = HEIGHT;
|
||||
this.width_mini = 195;
|
||||
this.height_mini = 195;
|
||||
this.preview_in_main = false;
|
||||
var parameters = [];
|
||||
var width_mini = 195;
|
||||
var height_mini = Math.round(width_mini * HEIGHT / WIDTH);
|
||||
var layer_active_small = document.createElement("canvas");
|
||||
var layer_active_small_ctx = layer_active_small.getContext("2d");
|
||||
|
||||
this.constructor = new function(){
|
||||
var dim = HELPER.get_dimensions();
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = 150+'px';
|
||||
popup.style.left = Math.round(dim[0]/2)+'px';
|
||||
}
|
||||
//add parameter
|
||||
this.add = function(object){
|
||||
if(this.active == true){
|
||||
parameters = [];
|
||||
this.active = false;
|
||||
}
|
||||
parameters.push(object);
|
||||
}
|
||||
//show popup window
|
||||
this.show = function(title, handler, preview_handler, onload_handler){
|
||||
if(this.active == true){
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
this.active = true;
|
||||
this.handler = handler;
|
||||
if(preview_handler != undefined)
|
||||
@ -41,7 +46,12 @@ function popup(WIDTH, HEIGHT){
|
||||
var html = '';
|
||||
var can_be_canceled = false;
|
||||
|
||||
html += '<h2>'+title+'</h2>';
|
||||
var dim = HELPER.get_dimensions();
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = 150+'px';
|
||||
popup.style.left = Math.round(dim[0]/2)+'px';
|
||||
|
||||
html += '<h2 id="popup_drag">'+title+'</h2>';
|
||||
html += '<table style="width:99%;">';
|
||||
for(var i in parameters){
|
||||
var parameter = parameters[i];
|
||||
@ -49,10 +59,53 @@ function popup(WIDTH, HEIGHT){
|
||||
html += '<td style="font-weight:bold;padding-right:3px;width:130px;">'+parameter.title+'</td>';
|
||||
if(parameter.name != undefined){
|
||||
can_be_canceled = true;
|
||||
if(parameter.value != undefined){
|
||||
var colspan = 1;
|
||||
if(parameter.range != undefined)
|
||||
colspan = 2;
|
||||
if(parameter.values != undefined){
|
||||
var onchange = '';
|
||||
if(parameter.onchange != undefined)
|
||||
onchange = ' onchange="'+parameter.onchange+';" ';
|
||||
if(parameter.values.length > 10 || parameter.type == 'select'){
|
||||
//drop down
|
||||
if(onchange == '' && preview_handler != undefined)
|
||||
onchange = ' onchange="POP.view();" ';
|
||||
html += '<td colspan="2"><select '+onchange+' style="font-size:12px;" id="pop_data_'+parameter.name+'">';
|
||||
var k = 0;
|
||||
for(var j in parameter.values){
|
||||
var sel = '';
|
||||
if(parameter.value == parameter.values[j])
|
||||
sel = 'selected="selected"';
|
||||
if(parameter.value == undefined && k == 0)
|
||||
sel = 'selected="selected"';
|
||||
html += '<option '+sel+' name="'+parameter.values[j]+'">'+parameter.values[j]+'</option>';
|
||||
k++;
|
||||
}
|
||||
html += '</select></td>';
|
||||
}
|
||||
else{
|
||||
//radio
|
||||
html += '<td colspan="2">';
|
||||
if(parameter.values.length > 2)
|
||||
html += '<div class="group">';
|
||||
var k = 0;
|
||||
for(var j in parameter.values){
|
||||
var ch = '';
|
||||
if(parameter.value == parameter.values[j])
|
||||
ch = 'checked="checked"';
|
||||
if(parameter.value == undefined && k == 0)
|
||||
ch = 'checked="checked"';
|
||||
if(onchange == '' && preview_handler != undefined)
|
||||
onchange = ' onchange="POP.view();" ';
|
||||
html += '<input type="radio" '+onchange+' '+ch+' name="'+parameter.name+'" id="pop_data_'+parameter.name+"_poptmp"+j+'" value="'+parameter.values[j]+'">';
|
||||
html += '<label style="margin-right:20px;" for="pop_data_'+parameter.name+"_poptmp"+j+'">'+parameter.values[j]+'</label>';
|
||||
if(parameter.values.length > 2)
|
||||
html += '<br />';
|
||||
k++;
|
||||
}
|
||||
if(parameter.values.length > 2)
|
||||
html += '</div>';
|
||||
html += '</td>';
|
||||
}
|
||||
}
|
||||
else if(parameter.value != undefined){
|
||||
var step = 1;
|
||||
if(parameter.step != undefined)
|
||||
step = parameter.step;
|
||||
@ -60,43 +113,46 @@ function popup(WIDTH, HEIGHT){
|
||||
var preview_code = '';
|
||||
if(this.preview !== false)
|
||||
preview_code = 'POP.view();';
|
||||
html += '<td colspan="'+colspan+'"><input style="width:100%;" type="range" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" min="'+parameter.range[0]+'" max="'+parameter.range[1]+'" step="'+step+'" " oninput="document.getElementById(\'pv'+i+'\').innerHTML=Math.round(this.value*100)/100;'+preview_code+'" /></td>';
|
||||
html += '<td><input type="range" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" min="'+parameter.range[0]+'" max="'+parameter.range[1]+'" step="'+step+'" " oninput="document.getElementById(\'pv'+i+'\').innerHTML=Math.round(this.value*100)/100;'+preview_code+'" /></td>';
|
||||
html += '<td style="padding-left:10px;width:50px;" id="pv'+i+'">'+parameter.value+'</td>';
|
||||
}
|
||||
else
|
||||
html += '<td colspan="'+colspan+'"><input style="width:100%;" type="text" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" onkeyup="POP.validate(this);" /></td>';
|
||||
//if(parameter.range != undefined)
|
||||
//html += '<td style="padding-left:10px;">'+parameter.range[0]+' - '+parameter.range[1]+'</td>';
|
||||
}
|
||||
else if(parameter.values != undefined){
|
||||
html += '<td colspan="2"><select style="font-size:12px;" id="pop_data_'+parameter.name+'">';
|
||||
for(var j in parameter.values)
|
||||
html += '<option name="'+parameter.values[j]+'">'+parameter.values[j]+'</option>';
|
||||
html += '</select></td>';
|
||||
else{
|
||||
if(parameter.type == 'textarea')
|
||||
html += '<td><textarea style="width:100%;height:80px;" id="pop_data_'+parameter.name+'">'+parameter.value+'</textarea></td>';
|
||||
else
|
||||
html += '<td colspan="2"><input style="width:100%;" type="text" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" onkeyup="POP.validate(this);" /></td>';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(parameter.function != undefined){
|
||||
//custom function
|
||||
if(typeof parameter.function == 'string')
|
||||
var result = window[parameter.function]();
|
||||
else
|
||||
var result = parameter.function();
|
||||
html += '<td colspan="3">'+result+'</td>';
|
||||
}
|
||||
else if(parameter.html != undefined){
|
||||
//html
|
||||
html += '<td colspan="2">'+parameter.html+'</td>';
|
||||
}
|
||||
else{
|
||||
//locked fields
|
||||
str = ""+parameter.value;
|
||||
var id_tmp = parameter.title.toLowerCase().replace(/[^\w]+/g,'').replace(/ +/g,'-');
|
||||
id_tmp = id_tmp.substring(0, 10);
|
||||
if(str.length < 40)
|
||||
html += '<td colspan="2"><input style="width:100%;color:#393939;padding-left:5px;" disabled="disabled" type="text" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" /></td>';
|
||||
html += '<td colspan="2"><input style="width:97%;color:#393939;padding-left:5px;" disabled="disabled" type="text" id="pop_data_'+id_tmp+'" value="'+parameter.value+'" /></td>';
|
||||
else
|
||||
html += '<td style="font-size:11px;" colspan="2"><textarea disabled="disabled">'+parameter.value+'</textarea></td>';
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
if(this.preview !== false){
|
||||
if(this.preview !== false && this.preview_in_main == false){
|
||||
html += '<div style="margin-top:15px;">';
|
||||
html += '<canvas style="position:relative;float:left;margin-right:5px;border:1px solid #393939;" width="'+width_mini+'" height="'+height_mini+'" id="pop_pre"></canvas>';
|
||||
html += '<canvas style="position:relative;border:1px solid #393939;background-color:#ffffff;" width="'+width_mini+'" height="'+height_mini+'" id="pop_post"></canvas>';
|
||||
html += '<canvas style="position:relative;float:left;margin-right:5px;border:1px solid #393939;" width="'+POP.width_mini+'" height="'+POP.height_mini+'" id="pop_pre"></canvas>';
|
||||
html += '<canvas style="position:relative;border:1px solid #393939;background-color:#ffffff;" width="'+POP.width_mini+'" height="'+POP.height_mini+'" id="pop_post"></canvas>';
|
||||
html += '</div>';
|
||||
}
|
||||
html += '<div style="text-align:center;margin-top:20px;margin-bottom:15px;">';
|
||||
@ -109,7 +165,7 @@ function popup(WIDTH, HEIGHT){
|
||||
|
||||
document.getElementById("popup").innerHTML = html;
|
||||
document.getElementById("popup").style.display="block";
|
||||
if(parameters.length > 20)
|
||||
if(parameters.length > 15)
|
||||
document.getElementById("popup").style.overflowY="scroll";
|
||||
else
|
||||
document.getElementById("popup").style.overflowY='hidden';
|
||||
@ -123,27 +179,28 @@ function popup(WIDTH, HEIGHT){
|
||||
}
|
||||
|
||||
//load preview?
|
||||
if(this.preview !== false){
|
||||
if(this.preview !== false && this.preview_in_main == false){
|
||||
//original
|
||||
var pop_pre = document.getElementById("pop_pre").getContext("2d");
|
||||
pop_pre.rect(0, 0, WIDTH, HEIGHT);
|
||||
pop_pre.rect(0, 0, POP.width_mini, POP.height_mini);
|
||||
pop_pre.fillStyle = "#ffffff";
|
||||
pop_pre.fill();
|
||||
DRAW.draw_background(pop_pre, 5, true);
|
||||
pop_pre.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, width_mini, height_mini);
|
||||
DRAW.draw_background(pop_pre, POP.width_mini, POP.height_mini, 5);
|
||||
pop_pre.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, POP.width_mini, POP.height_mini);
|
||||
|
||||
//copy
|
||||
pop_post = document.getElementById("pop_post").getContext("2d");
|
||||
pop_post.rect(0, 0, width_mini, height_mini);
|
||||
pop_post.rect(0, 0, POP.width_mini, POP.height_mini);
|
||||
pop_post.fillStyle = "#ffffff";
|
||||
pop_post.fill();
|
||||
DRAW.draw_background(pop_post, 5, true);
|
||||
pop_post.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, width_mini, height_mini);
|
||||
DRAW.draw_background(pop_post, POP.width_mini, POP.height_mini, 5);
|
||||
pop_post.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, POP.width_mini, POP.height_mini);
|
||||
|
||||
//prepare temp canvas
|
||||
layer_active_small.width = width_mini;
|
||||
layer_active_small.height = height_mini;
|
||||
layer_active_small_ctx.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, width_mini, height_mini);
|
||||
layer_active_small.width = POP.width_mini;
|
||||
layer_active_small.height = POP.height_mini;
|
||||
layer_active_small_ctx.drawImage(document.getElementById(LAYERS[LAYER.layer_active].name), 0, 0, POP.width_mini, POP.height_mini);
|
||||
POP.view();
|
||||
}
|
||||
}
|
||||
//hide popup
|
||||
@ -154,22 +211,33 @@ function popup(WIDTH, HEIGHT){
|
||||
this.active = false;
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
this.preview_in_main = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
//renders preview. If input=range supported, is called on every param update - must be fast...
|
||||
this.view = function(){
|
||||
if(this.preview !== false){
|
||||
//reset mini view
|
||||
pop_post.clearRect(0, 0, width_mini, height_mini);
|
||||
pop_post.drawImage(layer_active_small, 0, 0);
|
||||
|
||||
if(this.preview_in_main == false){
|
||||
//reset mini view
|
||||
pop_post.clearRect(0, 0, POP.width_mini, POP.height_mini);
|
||||
pop_post.drawImage(layer_active_small, 0, 0);
|
||||
}
|
||||
|
||||
//prepare
|
||||
var response = {};
|
||||
inputs = document.getElementsByTagName('input');
|
||||
for (i = 0; i<inputs.length; i++) {
|
||||
for (i = 0; i<inputs.length; i++){
|
||||
if(inputs[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = inputs[i].id.substr(9);
|
||||
if(HELPER.strpos(key, "_poptmp") != false)
|
||||
key = key.substring(0, HELPER.strpos(key, "_poptmp"));
|
||||
var value = inputs[i].value;
|
||||
response[key] = value;
|
||||
if(inputs[i].type == 'radio'){
|
||||
if(inputs[i].checked==true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
@ -180,8 +248,20 @@ function popup(WIDTH, HEIGHT){
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
//update mini view
|
||||
this.preview(response, pop_post, width_mini, height_mini);
|
||||
textareas = document.getElementsByTagName('textarea');
|
||||
for (i = 0; i<textareas.length; i++){
|
||||
if(textareas[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = textareas[i].id.substr(9);
|
||||
var value = textareas[i].value;
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
//call handler
|
||||
if(this.preview_in_main == false)
|
||||
this.preview(response, pop_post, POP.width_mini, POP.height_mini);
|
||||
else
|
||||
this.preview(response);
|
||||
}
|
||||
}
|
||||
//OK pressed - prepare data and call handlers
|
||||
@ -190,11 +270,19 @@ function popup(WIDTH, HEIGHT){
|
||||
document.getElementById("popup").style.display="none";
|
||||
var response={};
|
||||
inputs = document.getElementsByTagName('input');
|
||||
for (i = 0; i<inputs.length; i++) {
|
||||
for (i = 0; i<inputs.length; i++){
|
||||
if(inputs[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = inputs[i].id.substr(9);
|
||||
if(HELPER.strpos(key, "_poptmp") != false)
|
||||
key = key.substring(0, HELPER.strpos(key, "_poptmp"));
|
||||
var value = inputs[i].value;
|
||||
response[key] = value;
|
||||
if(inputs[i].type == 'radio'){
|
||||
if(inputs[i].checked==true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
@ -205,6 +293,14 @@ function popup(WIDTH, HEIGHT){
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
textareas = document.getElementsByTagName('textarea');
|
||||
for (i = 0; i<textareas.length; i++){
|
||||
if(textareas[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = textareas[i].id.substr(9);
|
||||
var value = textareas[i].value;
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
parameters = [];
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
|
||||
@ -6,16 +6,18 @@ var canvas_front = document.getElementById("canvas_front").getContext("2d"); //
|
||||
var canvas_preview = document.getElementById("canvas_preview").getContext("2d"); //mini preview
|
||||
|
||||
//settings
|
||||
var AUTHOR = 'Vilius';
|
||||
var AUTHOR = 'ViliusL';
|
||||
var EMAIL = 'www.viliusl@gmail.com';
|
||||
var VERSION = '1.7';
|
||||
var VERSION = '1.8';
|
||||
var WIDTH = 800; //canvas midth
|
||||
var HEIGHT = 500; //canvas height
|
||||
var RATIO = WIDTH/HEIGHT; //width & height ratio
|
||||
var LAYERS = []; //layers data
|
||||
var ACTION = 'select_tool'; ///default action
|
||||
var COLOUR = '#000000'; //current color
|
||||
var COLOUR_LAST = '#ffffff'; //last used color
|
||||
var ZOOM = 100; //zoom level 10 - infinity
|
||||
var ALPHA = 255;
|
||||
|
||||
var SAVE_TYPES = [
|
||||
"PNG - Portable Network Graphics", //default
|
||||
@ -29,16 +31,25 @@ var ACTION_DATA = [
|
||||
{name: 'select_tool', title: 'Select object tool', icon: ['all.png', 0+7, 2], attributes: {} },
|
||||
{name: 'select_square', title: 'Select area tool', icon: ['all.png', -50+4, 5], attributes: {} },
|
||||
{name: 'magic_wand', title: 'Magic Wand Tool', icon: ['all.png', -150+1, -50+2], attributes: {sensitivity: 40} },
|
||||
{name: 'erase', title: 'Erase', icon: ['all.png', -100+3, 4], attributes: {size: 20, circle: true} },
|
||||
{name: 'erase', title: 'Erase', icon: ['all.png', -100+3, 4], attributes: {size: 20, circle: true, strict: true,} },
|
||||
{name: 'fill', title: 'Fill', icon: ['all.png', -150+3, 3], attributes: {sensitivity: 0} },
|
||||
{name: 'pick_color', title: 'Pick Color', icon: ['all.png', -200+3, 3], attributes: {} },
|
||||
{name: 'pencil', title: 'Pencil', icon: ['all.png', -250+3, 3], attributes: {} },
|
||||
{name: 'line', title: 'Draw line', icon: ['all.png', -300+3, 3], attributes: {size: 1, arrow: false} },
|
||||
{name: 'letters', title: 'Draw letters', icon: ['all.png', -350+3, 4], attributes: {size: 12} },
|
||||
{name: 'line', title: 'Draw line', icon: ['all.png', -300+3, 3], attributes: {size: 1, multiline: false, arrow: false} },
|
||||
{name: 'letters', title: 'Draw letters', icon: ['all.png', -350+3, 4], attributes: {} },
|
||||
{name: 'draw_square', title: 'Draw rectangle', icon: ['all.png', -400+3, 5], attributes: {fill: false, square: false, round: 0} },
|
||||
{name: 'draw_circle', title: 'Draw circle', icon: ['all.png', -450+3, 5], attributes: {fill: false, circle: false} },
|
||||
{name: 'brush', title: 'Brush', icon: ['all.png', -500+6, 3], attributes: {size: 5} },
|
||||
{name: 'brush', title: 'Brush', icon: ['all.png', -500+6, 3], attributes: {type: 'Simple', type_values: ['Simple', 'BezierCurve', 'Broken', 'Chrome', 'Fur', 'Grouped', 'Shaded', 'Sketchy'], size: 5, } },
|
||||
{name: 'blur_tool', title: 'Blur tool', icon: ['all.png', -250+5, -50+2], attributes: {size: 30, strength: 1} },
|
||||
{name: 'sharpen_tool', title: 'Sharpen tool', icon: ['all.png', -300+5, -50+2], attributes: {size: 30, strength: 1} },
|
||||
{name: 'clone_tool', title: 'Clone tool', icon: ['all.png', -350+4, -50+3], attributes: {size: 30} },
|
||||
{name: 'gradient_tool', title: 'Gradient', icon: ['all.png', -400+3, -50+4], attributes: {radial: false, power: 50} },
|
||||
];
|
||||
|
||||
var CREDITS = [
|
||||
{title: 'Brush styles', name: 'Harmony', link: 'http://ricardocabello.com/blog/post/689', },
|
||||
{title: 'Effects library', name: 'glfx.js', link: 'http://evanw.github.io/glfx.js/', },
|
||||
{title: 'EXIF', name: 'exif.js', link: 'https://github.com/jseidelin/exif-js', },
|
||||
{title: 'Menu', name: 'Google menu', link: 'http://blog.geotitles.com/2011/09/creating-the-new-top-black-bar-found-in-google-and-all-its-products/', },
|
||||
{title: 'Image filters', name: 'ImageFilters.js',link: 'https://github.com/arahaya/ImageFilters.js', },
|
||||
];
|
||||
|
||||
831
js/tools.js
831
js/tools.js
File diff suppressed because it is too large
Load Diff
@ -1,294 +0,0 @@
|
||||
/*
|
||||
html5slider - a JS implementation of <input type=range> for Firefox 16 and up
|
||||
https://github.com/fryn/html5slider
|
||||
|
||||
Copyright (c) 2010-2013 Frank Yan, <http://frankyan.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
// test for native support
|
||||
var test = document.createElement('input');
|
||||
try {
|
||||
test.type = 'range';
|
||||
if (test.type == 'range')
|
||||
return;
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// test for required property support
|
||||
test.style.background = 'linear-gradient(red, red)';
|
||||
if (!test.style.backgroundImage || !('MozAppearance' in test.style))
|
||||
return;
|
||||
|
||||
var scale;
|
||||
var isMac = navigator.platform == 'MacIntel';
|
||||
var thumb = {
|
||||
radius: isMac ? 9 : 6,
|
||||
width: isMac ? 22 : 12,
|
||||
height: isMac ? 16 : 20
|
||||
};
|
||||
var track = 'linear-gradient(transparent ' + (isMac ?
|
||||
'6px, #999 6px, #999 7px, #ccc 8px, #bbb 9px, #bbb 10px, transparent 10px' :
|
||||
'9px, #999 9px, #bbb 10px, #fff 11px, transparent 11px') +
|
||||
', transparent)';
|
||||
var styles = {
|
||||
'min-width': thumb.width + 'px',
|
||||
'min-height': thumb.height + 'px',
|
||||
'max-height': thumb.height + 'px',
|
||||
padding: '0 0 ' + (isMac ? '2px' : '1px'),
|
||||
border: 0,
|
||||
'border-radius': 0,
|
||||
cursor: 'default',
|
||||
'text-indent': '-999999px' // -moz-user-select: none; breaks mouse capture
|
||||
};
|
||||
var options = {
|
||||
attributes: true,
|
||||
attributeFilter: ['min', 'max', 'step', 'value']
|
||||
};
|
||||
var onInput = document.createEvent('HTMLEvents');
|
||||
onInput.initEvent('input', true, false);
|
||||
var onChange = document.createEvent('HTMLEvents');
|
||||
onChange.initEvent('change', true, false);
|
||||
|
||||
if (document.readyState == 'loading')
|
||||
document.addEventListener('DOMContentLoaded', initialize, true);
|
||||
else
|
||||
initialize();
|
||||
addEventListener('pageshow', recreate, true);
|
||||
|
||||
function initialize() {
|
||||
// create initial sliders
|
||||
recreate();
|
||||
// create sliders on-the-fly
|
||||
new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.addedNodes)
|
||||
Array.forEach(mutation.addedNodes, function(node) {
|
||||
if (!(node instanceof Element))
|
||||
;
|
||||
else if (node.childElementCount)
|
||||
Array.forEach(node.querySelectorAll('input[type=range]'), check);
|
||||
else if (node.mozMatchesSelector('input[type=range]'))
|
||||
check(node);
|
||||
});
|
||||
});
|
||||
}).observe(document, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
function recreate() {
|
||||
Array.forEach(document.querySelectorAll('input[type=range]'), check);
|
||||
}
|
||||
|
||||
function check(input) {
|
||||
if (input.type != 'range')
|
||||
transform(input);
|
||||
}
|
||||
|
||||
function transform(slider) {
|
||||
|
||||
var isValueSet, areAttrsSet, isUI, isClick, prevValue, rawValue, prevX;
|
||||
var min, max, step, range, value = slider.value;
|
||||
|
||||
// lazily create shared slider affordance
|
||||
if (!scale) {
|
||||
scale = document.body.appendChild(document.createElement('hr'));
|
||||
style(scale, {
|
||||
'-moz-appearance': isMac ? 'scale-horizontal' : 'scalethumb-horizontal',
|
||||
display: 'block',
|
||||
visibility: 'visible',
|
||||
opacity: 1,
|
||||
position: 'fixed',
|
||||
top: '-999999px'
|
||||
});
|
||||
document.mozSetImageElement('__sliderthumb__', scale);
|
||||
}
|
||||
|
||||
// reimplement value and type properties
|
||||
var getValue = function() { return '' + value; };
|
||||
var setValue = function setValue(val) {
|
||||
value = '' + val;
|
||||
isValueSet = true;
|
||||
draw();
|
||||
delete slider.value;
|
||||
slider.value = value;
|
||||
slider.__defineGetter__('value', getValue);
|
||||
slider.__defineSetter__('value', setValue);
|
||||
};
|
||||
slider.__defineGetter__('value', getValue);
|
||||
slider.__defineSetter__('value', setValue);
|
||||
Object.defineProperty(slider, 'type', {
|
||||
get: function() { return 'range'; }
|
||||
});
|
||||
|
||||
// sync properties with attributes
|
||||
['min', 'max', 'step'].forEach(function(name) {
|
||||
if (slider.hasAttribute(name))
|
||||
areAttrsSet = true;
|
||||
Object.defineProperty(slider, name, {
|
||||
get: function() {
|
||||
return this.hasAttribute(name) ? this.getAttribute(name) : '';
|
||||
},
|
||||
set: function(val) {
|
||||
val === null ?
|
||||
this.removeAttribute(name) :
|
||||
this.setAttribute(name, val);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// initialize slider
|
||||
slider.readOnly = true;
|
||||
style(slider, styles);
|
||||
update();
|
||||
|
||||
new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName != 'value') {
|
||||
update();
|
||||
areAttrsSet = true;
|
||||
}
|
||||
// note that value attribute only sets initial value
|
||||
else if (!isValueSet) {
|
||||
value = slider.getAttribute('value');
|
||||
draw();
|
||||
}
|
||||
});
|
||||
}).observe(slider, options);
|
||||
|
||||
slider.addEventListener('mousedown', onDragStart, true);
|
||||
slider.addEventListener('keydown', onKeyDown, true);
|
||||
slider.addEventListener('focus', onFocus, true);
|
||||
slider.addEventListener('blur', onBlur, true);
|
||||
|
||||
function onDragStart(e) {
|
||||
isClick = true;
|
||||
setTimeout(function() { isClick = false; }, 0);
|
||||
if (e.button || !range)
|
||||
return;
|
||||
var width = parseFloat(getComputedStyle(this).width);
|
||||
var multiplier = (width - thumb.width) / range;
|
||||
if (!multiplier)
|
||||
return;
|
||||
// distance between click and center of thumb
|
||||
var dev = e.clientX - this.getBoundingClientRect().left - thumb.width / 2 -
|
||||
(value - min) * multiplier;
|
||||
// if click was not on thumb, move thumb to click location
|
||||
if (Math.abs(dev) > thumb.radius) {
|
||||
isUI = true;
|
||||
this.value -= -dev / multiplier;
|
||||
}
|
||||
rawValue = value;
|
||||
prevX = e.clientX;
|
||||
this.addEventListener('mousemove', onDrag, true);
|
||||
this.addEventListener('mouseup', onDragEnd, true);
|
||||
}
|
||||
|
||||
function onDrag(e) {
|
||||
var width = parseFloat(getComputedStyle(this).width);
|
||||
var multiplier = (width - thumb.width) / range;
|
||||
if (!multiplier)
|
||||
return;
|
||||
rawValue += (e.clientX - prevX) / multiplier;
|
||||
prevX = e.clientX;
|
||||
isUI = true;
|
||||
this.value = rawValue;
|
||||
}
|
||||
|
||||
function onDragEnd() {
|
||||
this.removeEventListener('mousemove', onDrag, true);
|
||||
this.removeEventListener('mouseup', onDragEnd, true);
|
||||
slider.dispatchEvent(onInput);
|
||||
slider.dispatchEvent(onChange);
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
if (e.keyCode > 36 && e.keyCode < 41) { // 37-40: left, up, right, down
|
||||
onFocus.call(this);
|
||||
isUI = true;
|
||||
this.value = value + (e.keyCode == 38 || e.keyCode == 39 ? step : -step);
|
||||
}
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
if (!isClick)
|
||||
this.style.boxShadow = !isMac ? '0 0 0 2px #fb0' :
|
||||
'inset 0 0 20px rgba(0,127,255,.1), 0 0 1px rgba(0,127,255,.4)';
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
this.style.boxShadow = '';
|
||||
}
|
||||
|
||||
// determines whether value is valid number in attribute form
|
||||
function isAttrNum(value) {
|
||||
return !isNaN(value) && +value == parseFloat(value);
|
||||
}
|
||||
|
||||
// validates min, max, and step attributes and redraws
|
||||
function update() {
|
||||
min = isAttrNum(slider.min) ? +slider.min : 0;
|
||||
max = isAttrNum(slider.max) ? +slider.max : 100;
|
||||
if (max < min)
|
||||
max = min > 100 ? min : 100;
|
||||
step = isAttrNum(slider.step) && slider.step > 0 ? +slider.step : 1;
|
||||
range = max - min;
|
||||
draw(true);
|
||||
}
|
||||
|
||||
// recalculates value property
|
||||
function calc() {
|
||||
if (!isValueSet && !areAttrsSet)
|
||||
value = slider.getAttribute('value');
|
||||
if (!isAttrNum(value))
|
||||
value = (min + max) / 2;;
|
||||
// snap to step intervals (WebKit sometimes does not - bug?)
|
||||
value = Math.round((value - min) / step) * step + min;
|
||||
if (value < min)
|
||||
value = min;
|
||||
else if (value > max)
|
||||
value = min + ~~(range / step) * step;
|
||||
}
|
||||
|
||||
// renders slider using CSS background ;)
|
||||
function draw(attrsModified) {
|
||||
calc();
|
||||
var wasUI = isUI;
|
||||
isUI = false;
|
||||
if (wasUI && value != prevValue)
|
||||
slider.dispatchEvent(onInput);
|
||||
if (!attrsModified && value == prevValue)
|
||||
return;
|
||||
prevValue = value;
|
||||
var position = range ? (value - min) / range * 100 : 0;
|
||||
var bg = '-moz-element(#__sliderthumb__) ' + position + '% no-repeat, ';
|
||||
style(slider, { background: bg + track });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function style(element, styles) {
|
||||
for (var prop in styles)
|
||||
element.style.setProperty(prop, styles[prop], 'important');
|
||||
}
|
||||
|
||||
})();
|
||||
@ -49,9 +49,19 @@ table{
|
||||
border-spacing: 0;
|
||||
width:100%;
|
||||
}
|
||||
input{
|
||||
input[type="text"], input[type="button"], select{
|
||||
border:1px solid #393939;
|
||||
}
|
||||
input[type="range"]{
|
||||
margin-left:0px;
|
||||
width:100%;
|
||||
}
|
||||
input[type="text"]:disabled{
|
||||
border: 1px solid #c0c0c0;
|
||||
}
|
||||
label{
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
/* ==== ID ================================================================== */
|
||||
|
||||
@ -80,9 +90,10 @@ input{
|
||||
#uploadprogress{
|
||||
position:absolute;
|
||||
top:5px;
|
||||
z-index:100;
|
||||
left:300px;
|
||||
height:15px;
|
||||
width:500px;
|
||||
width:600px;
|
||||
display:none;
|
||||
}
|
||||
#main_colour{
|
||||
@ -177,6 +188,7 @@ input{
|
||||
}
|
||||
#popup h2{
|
||||
margin-top:0px;
|
||||
cursor:move;
|
||||
}
|
||||
#popup textarea{
|
||||
color:#000000;
|
||||
@ -297,3 +309,8 @@ input{
|
||||
width:400px;
|
||||
font-weight:bold;
|
||||
}
|
||||
.group{
|
||||
border:1px solid #93bdfe;
|
||||
margin:5px 0px 5px 0px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user