mirror of
https://github.com/viliusle/miniPaint.git
synced 2026-02-06 15:31:53 +00:00
code refactor
This commit is contained in:
parent
0172a98394
commit
76b728a0d5
41
config.js
Normal file
41
config.js
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* main config file
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
|
||||
//canvas layers
|
||||
var canvas_back = document.getElementById("canvas_back").getContext("2d"); //layer for grid/transparency
|
||||
var canvas_main = document.getElementById("Background").getContext("2d"); //background
|
||||
var canvas_front = document.getElementById("canvas_front").getContext("2d"); //tmp layer
|
||||
var canvas_grid = document.getElementById("canvas_grid").getContext("2d"); //grid layer
|
||||
var canvas_preview = document.getElementById("canvas_preview").getContext("2d"); //mini preview
|
||||
|
||||
//global settings
|
||||
var VERSION = '2.4';
|
||||
var WIDTH = 800; //default canvas midth
|
||||
var HEIGHT = 600; //default canvas height
|
||||
var COLOR = '#0000ff'; //active color
|
||||
var ALPHA = 255; //active color alpha
|
||||
|
||||
var DRAW_TOOLS_CONFIG = [
|
||||
{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, anti_aliasing: 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, anti_aliasing: false} },
|
||||
{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, type_values: ['Simple', 'Multi-line', 'Arrow', 'Curve'] } },
|
||||
{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} },
|
||||
{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: {type: 'Brush', type_values: ['Brush', 'BezierCurve', 'Chrome', 'Fur', 'Grouped', 'Shaded', 'Sketchy'], size: 5, anti_alias: false }, on_update: 'update_brush', },
|
||||
{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: 0.5} },
|
||||
{name: 'burn_dodge_tool', title: 'Burn/Dodge tool', icon: ['all.png', -500+3, -50+4], attributes: {burn: true, size: 30, power: 50} },
|
||||
{name: 'desaturate_tool', title: 'Desaturate', icon: ['all.png', -550+3, -00+4], attributes: {size: 50, anti_alias: true} },
|
||||
{name: 'clone_tool', title: 'Clone tool', icon: ['all.png', -350+4, -50+3], attributes: {size: 30, anti_alias: true} },
|
||||
{name: 'gradient_tool', title: 'Gradient', icon: ['all.png', -400+3, -50+4], attributes: {radial: false, power: 50} },
|
||||
{name: 'crop_tool', title: 'Crop', icon: ['all.png', -450+2, -50+2], attributes: { } },
|
||||
];
|
||||
200
index.html
200
index.html
@ -1,10 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<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, 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, sprites, keypoints" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" type="text/css" href="styles/styles.css" />
|
||||
<link rel="shortcut icon" href="img/favicon.png" />
|
||||
</head>
|
||||
@ -22,17 +23,17 @@
|
||||
</div>
|
||||
<div style="clear:both;"></div>
|
||||
<div id="main_colour_container">
|
||||
<input type="color" id="main_colour" value="" onchange="TOOLS.set_color(this);" />
|
||||
<div style="display:none;" id="main_colour_alt" onclick="TOOLS.toggle_color_select();"></div>
|
||||
<input type="color" id="main_colour" value="" onchange="GUI.set_color(this);" />
|
||||
<div style="display:none;" id="main_colour_alt" onclick="GUI.toggle_color_select();"></div>
|
||||
</div>
|
||||
<div class="block" id="all_colors"></div>
|
||||
<div class="block">
|
||||
<input type="text" id="color_hex" value="#000000" /><br />
|
||||
<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" /><br />
|
||||
Alpha: <input id="rgb_a" onKeyUp="TOOLS.set_color_rgb(this, 'a')" type="text" value="255" />
|
||||
Red: <input id="rgb_r" onKeyUp="GUI.set_color_rgb(this, 'r')" type="text" value="255" /><br />
|
||||
Green: <input id="rgb_g" onKeyUp="GUI.set_color_rgb(this, 'g')" type="text" value="255" /><br />
|
||||
Blue: <input id="rgb_b" onKeyUp="GUI.set_color_rgb(this, 'b')" type="text" value="255" /><br />
|
||||
Alpha: <input id="rgb_a" onKeyUp="GUI.set_color_rgb(this, 'a')" type="text" value="255" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="block" id="info"></div>
|
||||
@ -53,11 +54,11 @@
|
||||
<div id="preview">
|
||||
<canvas id="canvas_preview"></canvas>
|
||||
<div style="margin-top:105px;padding-left:5px;">
|
||||
<input onclick="DRAW.zoom(-1);" style="width:30px;" class="layer_add" type="button" value="-" />
|
||||
<input onclick="DRAW.zoom(+1);" style="width:30px;" class="layer_add" type="button" value="+" />
|
||||
<input onclick="GUI.zoom(-1);EVENTS.scroll_window();" style="width:30px;" class="layer_add" type="button" value="-" />
|
||||
<input onclick="GUI.zoom(+1);EVENTS.scroll_window();" style="width:30px;" class="layer_add" type="button" value="+" />
|
||||
<b>Zoom: </b><span id="zoom_nr">100</span>%
|
||||
<br />
|
||||
<input style="width:95%;" 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="GUI.zoom(this.value);EVENTS.scroll_window();" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="layers_base">
|
||||
@ -74,145 +75,145 @@
|
||||
<li>
|
||||
<a href="#">File</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['file_new']);" href="#">New</a></li>
|
||||
<li><a onclick="MENU.do_menu(['file_open']);" href="#">Open...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['file_save']);" href="#">Save as...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['file_print']);" href="#">Print...</a></li>
|
||||
<li><a onclick="call_menu(FILE, 'file_new');" href="#">New</a></li>
|
||||
<li><a onclick="call_menu(FILE, 'file_open');" href="#">Open...</a></li>
|
||||
<li><a onclick="call_menu(FILE, 'file_save');" href="#">Save as...</a></li>
|
||||
<li><a onclick="call_menu(FILE, 'file_print');" href="#">Print...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Edit</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['edit_undo']);" href="#">Undo</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_undo');" href="#">Undo</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_cut']);" href="#">Cut selection</a></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_copy']);" href="#">Copy selection</a></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_paste']);" href="#">Paste selection</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_cut');" href="#">Cut selection</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_copy');" href="#">Copy selection</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_paste');" href="#">Paste selection</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_select']);" href="#">Select All</a></li>
|
||||
<li><a onclick="MENU.do_menu(['edit_clear']);" href="#">Clear selection</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_select');" href="#">Select All</a></li>
|
||||
<li><a onclick="call_menu(EDIT, 'edit_clear');" href="#">Clear selection</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<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>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_information');" href="#">Information...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_size');" href="#">Size...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_trim');" href="#">Trim</a>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_crop');" href="#">Crop Selection</a>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['image_resize']);" href="#">Resize...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_resize');" href="#">Resize...</a></li>
|
||||
<li>
|
||||
<a href="#">Rotate</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['image_rotate_left']);" href="#">Left</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_rotate_right']);" href="#">Right</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_rotate']);" href="#">Rotation...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_rotate_left');" href="#">Left</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_rotate_right');" href="#">Right</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_rotate');" href="#">Rotation...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Flip</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['image_vflip']);" href="#">Vertical</a></li>
|
||||
<li><a onclick="MENU.do_menu(['image_hflip']);" href="#">Horizontal</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_vflip');" href="#">Vertical</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_hflip');" href="#">Horizontal</a></li>
|
||||
</ul>
|
||||
</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_GrayScale']);" href="#">GrayScale</a>
|
||||
<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_grid']);" href="#">Grid...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_colors');" href="#">Color corrections...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_auto_adjust');" href="#">Auto adjust colors</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_GrayScale');" href="#">GrayScale</a>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_decrease_colors');" href="#">Decrease color depth...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_negative');" href="#">Negative</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_grid');" href="#">Grid...</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li><a onclick="MENU.do_menu(['image_histogram']);" href="#">Histogram...</a></li>
|
||||
<li><a onclick="call_menu(IMAGE, 'image_histogram');" href="#">Histogram...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Layer</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['layer_new']);" href="#">New</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_dublicate']);" href="#">Dublicate</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_show_hide']);" href="#">Show / Hide</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_crop']);" href="#">Crop Selection</a>
|
||||
<li><a onclick="MENU.do_menu(['layer_delete']);" href="#">Delete</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_new');" href="#">New</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_dublicate');" href="#">Dublicate</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_show_hide');" href="#">Show / Hide</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_crop');" href="#">Crop Selection</a>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_delete');" href="#">Delete</a></li>
|
||||
<li><div class="mid-line"></div></li>
|
||||
<li>
|
||||
<a href="#">Move</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['layer_move_up']);" href="#">Up</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_move_down']);" href="#">Down</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_move_up');" href="#">Up</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_move_down');" href="#">Down</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a onclick="MENU.do_menu(['layer_opacity']);" href="#">Opacity...</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_opacity');" href="#">Opacity...</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_clear']);" href="#">Clear</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_trim');" href="#">Trim</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_resize');" href="#">Resize...</a></li>
|
||||
<li><a onclick="call_menu(LAYER, '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_merge_down']);" href="#">Merge Down...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['layer_flatten']);" href="#">Flatten Image</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_differences');" href="#">Differences Down</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_merge_down');" href="#">Merge Down...</a></li>
|
||||
<li><a onclick="call_menu(LAYER, 'layer_flatten');" href="#">Flatten Image</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Effects</a>
|
||||
<ul id="effects_list">
|
||||
<li><a onclick="MENU.do_menu(['effects_bw']);" href="#">Black and White...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_bw');" href="#">Black and White...</a>
|
||||
<li>
|
||||
<a href="#">Blur</a>
|
||||
<ul>
|
||||
<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><a onclick="call_menu(EFFECTS, 'effects_BoxBlur');" href="#">Blur-Box...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_GaussianBlur');" href="#">Blur-Gaussian...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_StackBlur');" href="#">Blur-Stack...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_zoomblur');" href="#">Blur-Zoom...</a>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a onclick="MENU.do_menu(['effects_bulge_pinch']);" href="#">Bulge/Pinch...</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>
|
||||
<li><a onclick="MENU.do_menu(['effects_Edge']);" href="#">Edge...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Emboss']);" href="#">Emboss...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Enrich']);" href="#">Enrich...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Gamma']);" href="#">Gamma...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_Grains']);" href="#">Grains...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_heatmap']);" href="#">Heatmap...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_HSLAdjustment']);" href="#">HSL Adjustment...</a>
|
||||
<li><a onclick="MENU.do_menu(['effects_jpg_vintage']);" href="#">JPG Compression...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['effects_Mosaic']);" href="#">Mosaic...</a>
|
||||
<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>
|
||||
<li><a onclick="MENU.do_menu(['effects_vintage']);" href="#">Vintage...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_bulge_pinch');" href="#">Bulge/Pinch...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_colorize');" href="#">Colorize...</a></li>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_denoise');" href="#">Denoise...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Desaturate');" href="#">Desaturate...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Dither');" href="#">Dither...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_dot_screen');" href="#">Dot Screen...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Edge');" href="#">Edge...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Emboss');" href="#">Emboss...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Enrich');" href="#">Enrich...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Gamma');" href="#">Gamma...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Grains');" href="#">Grains...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_heatmap');" href="#">Heatmap...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_HSLAdjustment');" href="#">HSL Adjustment...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_jpg_vintage');" href="#">JPG Compression...</a></li>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Mosaic');" href="#">Mosaic...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Oil');" href="#">Oil...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_perspective');" href="#">Perspective...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Posterize');" href="#">Posterize...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Sepia');" href="#">Sepia...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Sharpen');" href="#">Sharpen...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_Solarize');" href="#">Solarize...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_tilt_shift');" href="#">Tilt Shift...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_vignette');" href="#">Vignette...</a>
|
||||
<li><a onclick="call_menu(EFFECTS, 'effects_vintage');" href="#">Vintage...</a>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Tools</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['tools_borders']);" href="#">Borders...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['tools_sprites']);" href="#">Sprites...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['tools_keypoints']);" href="#">Key-points</a></li>
|
||||
<li><a onclick="MENU.do_menu(['tools_color2alpha']);" href="#">Color to Alpha...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['tools_color_zoom']);" href="#">Color Zoom...</a></li>
|
||||
<li><a onclick="MENU.do_menu(['tools_restore_alpha']);" href="#">Restore alpha...</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_borders');" href="#">Borders...</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_sprites');" href="#">Sprites...</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_keypoints');" href="#">Key-points</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_color2alpha');" href="#">Color to Alpha...</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_color_zoom');" href="#">Color Zoom...</a></li>
|
||||
<li><a onclick="call_menu(TOOLS, 'tools_restore_alpha');" href="#">Restore alpha...</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#">Help</a>
|
||||
<ul>
|
||||
<li><a onclick="MENU.do_menu(['help_shortcuts']);" href="#">Keyboard Shortcuts...</a></li>
|
||||
<li><a onclick="call_menu(HELP, 'help_shortcuts');" href="#">Keyboard Shortcuts...</a></li>
|
||||
<li><a onclick="window.location='http://viliusle.github.io/miniPaint/';" href="http://viliusle.github.io/miniPaint/">Website</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>
|
||||
<li><a onclick="call_menu(HELP, 'help_credits');" href="#">Credits...</a></li>
|
||||
<li><a onclick="call_menu(HELP, 'help_about');" href="#">About...</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -229,15 +230,22 @@
|
||||
<script src="libs/vintage.js"></script>
|
||||
<script src="libs/kdtree.js"></script>
|
||||
<script src="libs/sift.js"></script>
|
||||
|
||||
<script src="js/elements.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="libs/popup.js"></script>
|
||||
|
||||
<script src="js/events.js"></script>
|
||||
<script src="js/file.js"></script>
|
||||
<script src="js/edit.js"></script>
|
||||
<script src="js/image.js"></script>
|
||||
<script src="js/layers.js"></script>
|
||||
<script src="js/menu_actions.js"></script>
|
||||
<script src="js/settings.js"></script>
|
||||
<script src="js/effects.js"></script>
|
||||
<script src="js/tools.js"></script>
|
||||
<script src="js/draw_tools.js"></script>
|
||||
<script src="js/gui.js"></script>
|
||||
<script src="js/help.js"></script>
|
||||
|
||||
<script src="config.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
707
js/controlls.js
707
js/controlls.js
@ -1,707 +0,0 @@
|
||||
/* global HELPER, POP, MAIN, LAYERS, CON, TOOLS, LAYER, DRAW, MENU */
|
||||
/* global ACTION, canvas_active, canvas_front, WIDTH, HEIGHT, ZOOM, EXIF */
|
||||
|
||||
var CON = new CONTROLLS_CLASS();
|
||||
|
||||
//keyboard handlers
|
||||
document.onkeydown = function(e) {return CON.on_keyboard_action(e); };
|
||||
document.onkeyup = function(e) {return CON.on_keyboardup_action(e); };
|
||||
//mouse
|
||||
window.ondrop = function(e){ CON.upload_drop(e); }; //drop
|
||||
window.ondragover = function(e){e.preventDefault(); };
|
||||
document.onmousedown = CON.mouse_click; //mouse click
|
||||
document.onmousemove = CON.mouse_move; //mouse move
|
||||
document.onmouseup = CON.mouse_release; //mouse resease
|
||||
document.addEventListener("mousewheel", CON.mouse_wheel_handler, false); //mouse scroll
|
||||
document.addEventListener("DOMMouseScroll", CON.mouse_wheel_handler, false); //mouse scroll
|
||||
window.onresize = CON.calc_preview_auto; //window resize
|
||||
document.oncontextmenu = function(e) {return CON.mouse_right_click(e); }; //mouse right click
|
||||
document.getElementById('color_hex').onkeyup = function(e){ TOOLS.set_color_manual(e); }; //on main color type
|
||||
document.getElementById('color_hex').onpaste = function(e){ TOOLS.set_color_manual(e); }; // on paste in main color input
|
||||
|
||||
function CONTROLLS_CLASS(){
|
||||
this.mouse;
|
||||
this.ctrl_pressed = false; //17
|
||||
this.shift_pressed = false; //16
|
||||
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
|
||||
this.clear_front_on_release = true;
|
||||
var autosize = true;
|
||||
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){
|
||||
k = event.keyCode; //console.log(k);
|
||||
|
||||
if(POP != undefined && POP.active==true && k != 27) return true;
|
||||
if(document.activeElement.type == 'text') return true;
|
||||
|
||||
//up
|
||||
if(k == 38){
|
||||
if(ACTION=='select_tool'){
|
||||
MAIN.save_state();
|
||||
LAYER.layer_move_active(0, -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//down
|
||||
else if(k == 40){
|
||||
if(ACTION=='select_tool'){
|
||||
MAIN.save_state();
|
||||
LAYER.layer_move_active(0, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//left
|
||||
else if(k == 39){
|
||||
if(ACTION=='select_tool'){
|
||||
MAIN.save_state();
|
||||
LAYER.layer_move_active(1, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//right
|
||||
else if(k == 37){
|
||||
if(ACTION=='select_tool'){
|
||||
MAIN.save_state();
|
||||
LAYER.layer_move_active(-1, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//esc
|
||||
else if(k == 27){
|
||||
if(POP != undefined && POP.active == true)
|
||||
POP.hide();
|
||||
delete TOOLS.last_line_x;
|
||||
delete TOOLS.last_line_y;
|
||||
TOOLS.curve_points = [];
|
||||
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){
|
||||
//undo
|
||||
if(CON.ctrl_pressed==true)
|
||||
MAIN.undo();
|
||||
}
|
||||
//t - trim
|
||||
else if(k == 84){
|
||||
MAIN.save_state();
|
||||
DRAW.trim();
|
||||
}
|
||||
//o - open
|
||||
else if(k == 79)
|
||||
MENU.open();
|
||||
//s - save
|
||||
else if(k == 83){
|
||||
if(POP != undefined)
|
||||
MENU.save_dialog(event);
|
||||
}
|
||||
//l - rotate left
|
||||
else if(k == 76){
|
||||
MAIN.save_state();
|
||||
MENU.rotate_resize_doc(270, WIDTH, HEIGHT);
|
||||
MENU.rotate_layer({angle: 270}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//r - resize
|
||||
else if(k == 82)
|
||||
MENU.resize_box();
|
||||
//grid
|
||||
else if(k==71){
|
||||
if(MAIN.grid == false)
|
||||
MAIN.grid = true;
|
||||
else
|
||||
MAIN.grid = false;
|
||||
DRAW.draw_grid();
|
||||
}
|
||||
//del
|
||||
else if(k==46){
|
||||
if(TOOLS.select_data != false){
|
||||
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);
|
||||
}
|
||||
}
|
||||
//shift
|
||||
else if(k==16)
|
||||
CON.shift_pressed = true;
|
||||
//ctrl
|
||||
else if(k==17){
|
||||
if(CON.ctrl_pressed == false)
|
||||
CON.ctrl_pressed = true;
|
||||
}
|
||||
//d
|
||||
else if(k==68){
|
||||
MENU.do_menu(['layer_dublicate']);
|
||||
}
|
||||
//a
|
||||
else if(k==65){
|
||||
if(CON.ctrl_pressed == true){
|
||||
TOOLS.select_data = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: WIDTH,
|
||||
h: HEIGHT
|
||||
};
|
||||
TOOLS.draw_selected_area();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//v
|
||||
else if(k==86){
|
||||
MAIN.save_state();
|
||||
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);
|
||||
//n - new layer
|
||||
else if(k==78)
|
||||
MENU.add_layer();
|
||||
|
||||
//mac support - ctrl
|
||||
if(k==17 || event.metaKey || event.ctrlKey){
|
||||
if(CON.ctrl_pressed == false)
|
||||
CON.ctrl_pressed = true;
|
||||
}
|
||||
|
||||
DRAW.zoom();
|
||||
return true;
|
||||
};
|
||||
//keyboard release
|
||||
this.on_keyboardup_action = function(event){
|
||||
k = event.keyCode;
|
||||
//shift
|
||||
if(k==16)
|
||||
CON.shift_pressed = false;
|
||||
//ctrl
|
||||
else if(k==17)
|
||||
CON.ctrl_pressed = false;
|
||||
//mac support - ctrl
|
||||
if(event.metaKey || event.ctrlKey || event.key == 'Meta')
|
||||
CON.ctrl_pressed = false;
|
||||
};
|
||||
// mouse_x, mouse_y, event.pageX, event.pageY
|
||||
this.get_mouse_position = function(event){
|
||||
var valid = true;
|
||||
if(event.offsetX) {
|
||||
mouse_rel_x = event.offsetX;
|
||||
mouse_rel_y = event.offsetY;
|
||||
}
|
||||
else if(event.layerX) {
|
||||
mouse_rel_x = event.layerX;
|
||||
mouse_rel_y = event.layerY;
|
||||
}
|
||||
else
|
||||
return 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);
|
||||
}
|
||||
}
|
||||
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,
|
||||
y: mouse_y,
|
||||
click_x: mouse_click_x,
|
||||
click_y: mouse_click_y,
|
||||
last_x: mouse_x_move_last,
|
||||
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;
|
||||
CON.get_mouse_position(event);
|
||||
mouse_click_x = CON.mouse.x;
|
||||
mouse_click_y = CON.mouse.y;
|
||||
|
||||
for (var i in TOOLS){
|
||||
if(i == ACTION){
|
||||
return TOOLS[i]('right_click', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
//mouse click
|
||||
this.mouse_click = function(event){
|
||||
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;
|
||||
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;
|
||||
|
||||
|
||||
//check tools functions
|
||||
for (var i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('click', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(event.target.id == "canvas_preview")
|
||||
CON.calc_preview_by_mouse(CON.mouse.x, CON.mouse.y);
|
||||
|
||||
//main window resize
|
||||
resize_all = false;
|
||||
if(ZOOM == 100){
|
||||
if(event.target.id == "resize-w") resize_all = "w";
|
||||
else if(event.target.id == "resize-h") resize_all = "h";
|
||||
else if(event.target.id == "resize-wh") resize_all = "wh";
|
||||
}
|
||||
};
|
||||
//mouse move
|
||||
this.mouse_move = function(event){
|
||||
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" && CON.isDrag==true)
|
||||
CON.calc_preview_by_mouse(CON.mouse.x, CON.mouse.y);
|
||||
LAYER.update_info_block();
|
||||
|
||||
//main window resize
|
||||
if(ZOOM == 100){
|
||||
if(event.target.id == "resize-w") document.body.style.cursor = "w-resize";
|
||||
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 && CON.isDrag==true){
|
||||
document.body.style.cursor = "auto";
|
||||
if(resize_all == "w"){
|
||||
new_w = CON.mouse.x;
|
||||
new_h = HEIGHT;
|
||||
}
|
||||
else if(resize_all == "h"){
|
||||
new_w = WIDTH;
|
||||
new_h = CON.mouse.y;
|
||||
}
|
||||
else if(resize_all == "wh"){
|
||||
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();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//check tools functions
|
||||
if(CON.isDrag === false){
|
||||
for (i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('move', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(CON.isDrag === false) return false; //only drag now
|
||||
|
||||
//check tools functions
|
||||
for (var i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('drag', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
mouse_x_move_last = false;
|
||||
mouse_y_move_last = false;
|
||||
if(TOOLS.select_square_action == '' && CON.mouse.valid == true)
|
||||
TOOLS.select_data = false;
|
||||
|
||||
//check tools functions
|
||||
if(CON.clear_front_on_release == true)
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
TOOLS.draw_selected_area();
|
||||
for (var i in TOOLS){
|
||||
if(i == ACTION){
|
||||
TOOLS[i]('release', CON.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//main window resize
|
||||
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 = CON.mouse.x;
|
||||
else if(resize_all == "h")
|
||||
HEIGHT = CON.mouse.y;
|
||||
else if(resize_all == "wh"){
|
||||
WIDTH = mouse_x;
|
||||
HEIGHT = CON.mouse.y;
|
||||
}
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
DRAW.zoom();
|
||||
}
|
||||
resize_all = false;
|
||||
DRAW.zoom();
|
||||
};
|
||||
//upload drop zone
|
||||
this.upload_drop = function(e){
|
||||
e.preventDefault();
|
||||
MAIN.save_state();
|
||||
var n_valid = 0;
|
||||
for (var i = 0, f; i < e.dataTransfer.files.length ; i++){
|
||||
f = e.dataTransfer.files[i];
|
||||
if(!f.type.match('image.*') && f.type != 'text/xml') continue;
|
||||
n_valid++;
|
||||
|
||||
var FR = new FileReader();
|
||||
FR.file = e.dataTransfer.files[i];
|
||||
|
||||
if(e.dataTransfer.files.length == 1)
|
||||
SAVE_NAME = f.name.split('.')[f.name.split('.').length - 2];
|
||||
|
||||
FR.onload = function(event){
|
||||
if(this.file.type != 'text/xml'){
|
||||
//image
|
||||
LAYER.layer_add(this.file.name, event.target.result, this.file.type);
|
||||
EXIF.getData(this.file, TOOLS.save_EXIF);
|
||||
}
|
||||
else{
|
||||
//xml
|
||||
var responce = MAIN.load_xml(event.target.result);
|
||||
if(responce === true)
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if(f.type == "text/plain")
|
||||
FR.readAsText(f);
|
||||
else if(f.type == "text/xml")
|
||||
FR.readAsText(f);
|
||||
else
|
||||
FR.readAsDataURL(f);
|
||||
}
|
||||
if(n_valid == 0)
|
||||
progress.style.display='none';
|
||||
};
|
||||
this.mouse_wheel_handler = function(e){ //return true;
|
||||
var step = 100; e.preventDefault();
|
||||
//zoom
|
||||
if(CON.ctrl_pressed==true){
|
||||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
|
||||
if(ZOOM <=100 && delta < 0)
|
||||
step = 10;
|
||||
if(ZOOM <100 && delta > 0)
|
||||
step = 10;
|
||||
delta = delta * step;
|
||||
if(ZOOM + delta > 0){
|
||||
ZOOM = ZOOM + delta;
|
||||
CON.calc_preview_auto();
|
||||
DRAW.zoom();
|
||||
}
|
||||
if(TOOLS.action_data().name == 'zoom'){
|
||||
TOOLS.action_data().attributes.zoom = ZOOM;
|
||||
show_action_attributes();
|
||||
}
|
||||
|
||||
//disable page scroll if ctrl pressed
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
this.scroll_window = function(){
|
||||
var pad_left = 109;
|
||||
var pad_top = 34;
|
||||
var pad_right = 170;
|
||||
var dim = HELPER.get_dimensions();
|
||||
var page_w = dim[0];
|
||||
var page_h = dim[1];
|
||||
var total_w = (WIDTH * ZOOM/100) + pad_left + pad_right;
|
||||
var total_h = (HEIGHT * ZOOM/100) + pad_top;
|
||||
var visible_w = page_w - 60;
|
||||
var visible_h = page_h - 60;
|
||||
|
||||
var scrollbar_w = page_w * visible_w / total_w;
|
||||
var scrollbar_h = page_h * visible_h / total_h;
|
||||
|
||||
xx = total_w * CON.ZOOM_X / (DRAW.PREVIEW_SIZE.w);
|
||||
yy = total_h * CON.ZOOM_Y / (DRAW.PREVIEW_SIZE.h );
|
||||
|
||||
//minuus scrollbar size
|
||||
xx = xx - scrollbar_w/2;
|
||||
yy = yy - scrollbar_h/2;
|
||||
|
||||
var canvas_wrapper = document.getElementById('canvas_wrapper');
|
||||
canvas_wrapper.scrollTop = yy;
|
||||
canvas_wrapper.scrollLeft = xx;
|
||||
};
|
||||
this.calc_preview_by_mouse = function(mouse_x, mouse_y){
|
||||
CON.ZOOM_X = mouse_x - CON.mini_rect_data.w/2;
|
||||
CON.ZOOM_Y = mouse_y - CON.mini_rect_data.h/2;
|
||||
if(CON.ZOOM_X < 0) CON.ZOOM_X = 0;
|
||||
if(CON.ZOOM_Y < 0) CON.ZOOM_Y = 0;
|
||||
|
||||
DRAW.zoom(undefined, true);
|
||||
return true;
|
||||
};
|
||||
this.calc_preview_auto = function(){
|
||||
var pad_left = 109;
|
||||
var pad_top = 34;
|
||||
var pad_right = 170;
|
||||
var dim = HELPER.get_dimensions();
|
||||
var page_w = dim[0];
|
||||
var page_h = dim[1];
|
||||
var total_w = (WIDTH * ZOOM/100) + pad_left + pad_right;
|
||||
var total_h = (HEIGHT * ZOOM/100) + pad_top;
|
||||
var visible_w = page_w - 60;
|
||||
var visible_h = page_h - 60;
|
||||
|
||||
CON.mini_rect_data.w = round(visible_w * DRAW.PREVIEW_SIZE.w / total_w);
|
||||
CON.mini_rect_data.h = round(visible_h * DRAW.PREVIEW_SIZE.h / total_h);
|
||||
|
||||
DRAW.redraw_preview();
|
||||
};
|
||||
}
|
||||
|
||||
//=== Clipboard ================================================================
|
||||
|
||||
var CLIPBOARD = new CLIPBOARD_CLASS('cc');
|
||||
|
||||
function CLIPBOARD_CLASS(canvas_id){
|
||||
var _self = this;
|
||||
var ctrl_pressed = false;
|
||||
var reading_dom = false;
|
||||
var text_top = 15;
|
||||
var pasteCatcher;
|
||||
var paste_mode;
|
||||
|
||||
//handlers
|
||||
document.addEventListener('keydown', function(e){ _self.on_keyboard_action(e); }, false);
|
||||
document.addEventListener('keyup', function(e){ _self.on_keyboardup_action(e); }, false);
|
||||
document.addEventListener('paste', function(e){ _self.paste_auto(e); }, false);
|
||||
|
||||
//constructor - prepare
|
||||
this.init = function(){
|
||||
//if using auto
|
||||
if(window.Clipboard) return true;
|
||||
|
||||
pasteCatcher = document.createElement("div");
|
||||
pasteCatcher.setAttribute("id", "paste_ff");
|
||||
pasteCatcher.setAttribute("contenteditable", "");
|
||||
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;';
|
||||
pasteCatcher.style.marginLeft = "-20px";
|
||||
pasteCatcher.style.width = "10px";
|
||||
document.body.appendChild(pasteCatcher);
|
||||
document.getElementById('paste_ff').addEventListener('DOMSubtreeModified', function(){
|
||||
reading_dom = false;
|
||||
if(paste_mode == 'auto' || ctrl_pressed == false) return true;
|
||||
//if paste handle failed - capture pasted object manually
|
||||
if(pasteCatcher.children.length == 1){
|
||||
if(pasteCatcher.firstElementChild.src != undefined){
|
||||
//image
|
||||
img = pasteCatcher.firstElementChild.src;
|
||||
_self.paste_createImage(pasteCatcher.firstElementChild.src);
|
||||
}
|
||||
else{
|
||||
//html
|
||||
/*setTimeout(function(){
|
||||
if(reading_dom == true) return false;
|
||||
_self.paste_createText(pasteCatcher.innerHTML, false);
|
||||
reading_dom = true;
|
||||
}, 10);*/
|
||||
}
|
||||
}
|
||||
/*else if(pasteCatcher.children.length == 0){
|
||||
//text
|
||||
setTimeout(function(){
|
||||
if(reading_dom == true) return false;
|
||||
_self.paste_createText(pasteCatcher.innerHTML, false);
|
||||
reading_dom = true;
|
||||
}, 10);
|
||||
}*/
|
||||
//register cleanup after some time.
|
||||
setTimeout(function(){
|
||||
pasteCatcher.innerHTML = '';
|
||||
}, 20);
|
||||
},false);
|
||||
}();
|
||||
//default paste action
|
||||
this.paste_auto = function(e){
|
||||
paste_mode = '';
|
||||
pasteCatcher.innerHTML = '';
|
||||
var plain_text_used = false;
|
||||
|
||||
|
||||
|
||||
if(e.clipboardData){
|
||||
var items = e.clipboardData.items;
|
||||
if (items){
|
||||
paste_mode = 'auto';
|
||||
//access data directly
|
||||
for (var i = 0; i < items.length; i++){
|
||||
if(items[i].type.indexOf("image") !== -1){
|
||||
//image
|
||||
var blob = items[i].getAsFile();
|
||||
var URLObj = window.URL || window.webkitURL;
|
||||
var source = URLObj.createObjectURL(blob);
|
||||
this.paste_createImage(source);
|
||||
}
|
||||
else if(items[i].type.indexOf("text") !== -1){
|
||||
//text or html
|
||||
/*if(plain_text_used == false)
|
||||
this.paste_createText(e.clipboardData.getData('text/plain'));
|
||||
plain_text_used = true;*/
|
||||
}
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
else{
|
||||
//wait for DOMSubtreeModified event
|
||||
//https://bugzilla.mozilla.org/show_bug.cgi?id=891247
|
||||
}
|
||||
}
|
||||
};
|
||||
//on keyboard press
|
||||
this.on_keyboard_action = function(event){
|
||||
if(POP.active == true) return true;
|
||||
k = event.keyCode;
|
||||
//ctrl
|
||||
if(k==17 || event.metaKey || event.ctrlKey){
|
||||
if(ctrl_pressed == false)
|
||||
ctrl_pressed = true;
|
||||
}
|
||||
//v
|
||||
if(k==86){
|
||||
if(document.activeElement != undefined && document.activeElement.type == 'text'){
|
||||
//let user paste into some input
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ctrl_pressed == true && !window.Clipboard)
|
||||
pasteCatcher.focus();
|
||||
}
|
||||
};
|
||||
//on kaybord release
|
||||
this.on_keyboardup_action = function(event){
|
||||
k = event.keyCode;
|
||||
//ctrl
|
||||
if(k==17 || event.metaKey || event.ctrlKey || event.key == 'Meta')
|
||||
ctrl_pressed = false;
|
||||
};
|
||||
//draw image
|
||||
this.paste_createImage = function(source){
|
||||
var pastedImage = new Image();
|
||||
pastedImage.onload = function(){
|
||||
LAYER.layer_add('Paste', source);
|
||||
};
|
||||
pastedImage.src = source;
|
||||
};
|
||||
//draw text
|
||||
this.paste_createText = function(text, parsed){
|
||||
var ctx = canvas_active();
|
||||
if(text == '') return false;
|
||||
if(parsed == false){
|
||||
text = text.replace(/<br\s*[\/]?>/gi, "\n");
|
||||
text = text.replace(/(<([^>]+)>)/g, "");
|
||||
text = text.replace(/ /gi, " ");
|
||||
}
|
||||
ctx.font = '13px Tahoma';
|
||||
var lines = text.split("\n");
|
||||
for(var i in lines){
|
||||
ctx.fillText(lines[i], 10, text_top);
|
||||
text_top += 15;
|
||||
}
|
||||
text_top += 15;
|
||||
};
|
||||
};
|
||||
914
js/draw.js
914
js/draw.js
@ -1,914 +0,0 @@
|
||||
/* global HELPER, POP, MAIN, LAYERS, CON, LAYER, DRAW, MENU */
|
||||
/* global ACTION, canvas_active, canvas_front, canvas_preview, canvas_grid, WIDTH, HEIGHT, ZOOM, ImageFilters */
|
||||
|
||||
var DRAW = new DRAW_CLASS();
|
||||
|
||||
function DRAW_CLASS(){
|
||||
this.PREVIEW_SIZE = {w: 148, h: 100 };
|
||||
this.grid_size = [50, 50];
|
||||
|
||||
this.draw_grid = function(gap_x, gap_y){
|
||||
if(MAIN.grid == false){
|
||||
document.getElementById("canvas_grid").style.display = 'none';
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
document.getElementById("canvas_grid").style.display = '';
|
||||
canvas_grid.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
//size
|
||||
if(gap_x != undefined && gap_y != undefined)
|
||||
this.grid_size = [gap_x, gap_y];
|
||||
else{
|
||||
gap_x = this.grid_size[0];
|
||||
gap_y = this.grid_size[1];
|
||||
}
|
||||
gap_x = parseInt(gap_x);
|
||||
gap_y = parseInt(gap_y);
|
||||
if(gap_x<2) gap_x=2;
|
||||
if(gap_y<2) gap_y=2;
|
||||
for(var i=gap_x; i<WIDTH; i=i+gap_x){
|
||||
if(gap_x==0) break;
|
||||
if(i%(gap_x*5) == 0) //main lines
|
||||
canvas_grid.strokeStyle = '#222222';
|
||||
else{
|
||||
HELPER.dashedLine(canvas_grid, i, 0, i, HEIGHT, 3, '#888888');
|
||||
continue;
|
||||
}
|
||||
canvas_grid.beginPath();
|
||||
canvas_grid.moveTo(0.5 + i, 0);
|
||||
canvas_grid.lineTo(0.5 + i, HEIGHT);
|
||||
canvas_grid.stroke();
|
||||
}
|
||||
for(var i=gap_y; i<HEIGHT; i=i+gap_y){
|
||||
if(gap_y==0) break;
|
||||
if(i%(gap_y*5) == 0) //main lines
|
||||
canvas_grid.strokeStyle = '#222222';
|
||||
else{
|
||||
HELPER.dashedLine(canvas_grid, 0, i, WIDTH, i, 3, '#888888');
|
||||
continue;
|
||||
}
|
||||
canvas_grid.beginPath();
|
||||
canvas_grid.moveTo(0, 0.5 + i);
|
||||
canvas_grid.lineTo(WIDTH, 0.5 + i);
|
||||
canvas_grid.stroke();
|
||||
}
|
||||
};
|
||||
this.draw_background = function(canvas, W, H, gap, force){
|
||||
if(MAIN.TRANSPARENCY == false && force == undefined){
|
||||
canvas.beginPath();
|
||||
canvas.rect(0, 0, W, H);
|
||||
canvas.fillStyle = "#ffffff";
|
||||
canvas.fill();
|
||||
return false;
|
||||
}
|
||||
if(gap == undefined)
|
||||
gap = 10;
|
||||
var fill = true;
|
||||
for(var i=0; i<W; i=i+gap){
|
||||
if(i%(gap*2) == 0)
|
||||
fill=true;
|
||||
else
|
||||
fill=false;
|
||||
for(var j=0; j<H; j=j+gap){
|
||||
if(fill==true){
|
||||
canvas.fillStyle = '#eeeeee';
|
||||
canvas.fillRect(i, j, gap, gap);
|
||||
fill = false;
|
||||
}
|
||||
else
|
||||
fill = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
//credits to Victor Haydin
|
||||
this.toolFiller = function(context, W, H, x, y, color_to, sensitivity, anti_aliasing){
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
var img_tmp = canvas_front.getImageData(0, 0, W, H);
|
||||
var imgData_tmp = img_tmp.data;
|
||||
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
var dx = [ 0, -1, +1, 0];
|
||||
var dy = [-1, 0, 0, +1];
|
||||
var color_from = {
|
||||
r: imgData[k+0],
|
||||
g: imgData[k+1],
|
||||
b: imgData[k+2],
|
||||
a: imgData[k+3]
|
||||
};
|
||||
if(color_from.r == color_to.r &&
|
||||
color_from.g == color_to.g &&
|
||||
color_from.b == color_to.b &&
|
||||
color_from.a == color_to.a)
|
||||
return false;
|
||||
var stack = [];
|
||||
stack.push([x, y]);
|
||||
while (stack.length > 0){
|
||||
var curPoint = stack.pop();
|
||||
for (var i = 0; i < 4; i++){
|
||||
var nextPointX = curPoint[0] + dx[i];
|
||||
var nextPointY = curPoint[1] + dy[i];
|
||||
if (nextPointX < 0 || nextPointY < 0 || nextPointX >= W || nextPointY >= H)
|
||||
continue;
|
||||
var k = (nextPointY * W + nextPointX) * 4;
|
||||
if(imgData_tmp[k+3] != 0) continue; //already parsed
|
||||
|
||||
//check
|
||||
if(Math.abs(imgData[k+0] - color_from.r) <= sensitivity &&
|
||||
Math.abs(imgData[k+1] - color_from.g) <= sensitivity &&
|
||||
Math.abs(imgData[k+2] - color_from.b) <= sensitivity &&
|
||||
Math.abs(imgData[k+3] - color_from.a) <= sensitivity){
|
||||
//fill pixel
|
||||
imgData_tmp[k] = color_to.r; //r
|
||||
imgData_tmp[k+1] = color_to.g; //g
|
||||
imgData_tmp[k+2] = color_to.b; //b
|
||||
imgData_tmp[k+3] = color_to.a; //a
|
||||
|
||||
stack.push([nextPointX, nextPointY]);
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas_front.putImageData(img_tmp, 0, 0);
|
||||
if(anti_aliasing == true){
|
||||
context.shadowColor = "rgba("+color_to.r+", "+color_to.g+", "+color_to.b+", "+color_to.a/255+")";
|
||||
context.shadowBlur = 5;
|
||||
}
|
||||
context.drawImage(document.getElementById("canvas_front"), 0, 0);
|
||||
//reset
|
||||
context.shadowBlur = 0;
|
||||
};
|
||||
this.tool_magic_wand = function(context, W, H, x, y, sensitivity, anti_aliasing){
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
canvas_front.rect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_front.fillStyle = "rgba(255, 255, 255, 0)";
|
||||
canvas_front.fill();
|
||||
|
||||
var img_tmp = canvas_front.getImageData(0, 0, W, H);
|
||||
var imgData_tmp = img_tmp.data;
|
||||
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
var k = ((y * (img.width * 4)) + (x * 4));
|
||||
var dx = [ 0, -1, +1, 0];
|
||||
var dy = [-1, 0, 0, +1];
|
||||
var color_to = {
|
||||
r: 255,
|
||||
g: 255,
|
||||
b: 255,
|
||||
a: 255
|
||||
};
|
||||
var color_from = {
|
||||
r: imgData[k+0],
|
||||
g: imgData[k+1],
|
||||
b: imgData[k+2],
|
||||
a: imgData[k+3]
|
||||
};
|
||||
if(color_from.r == color_to.r &&
|
||||
color_from.g == color_to.g &&
|
||||
color_from.b == color_to.b &&
|
||||
color_from.a == 0){
|
||||
return false;
|
||||
}
|
||||
var stack = [];
|
||||
stack.push([x, y]);
|
||||
while (stack.length > 0){
|
||||
var curPoint = stack.pop();
|
||||
for (var i = 0; i < 4; i++){
|
||||
var nextPointX = curPoint[0] + dx[i];
|
||||
var nextPointY = curPoint[1] + dy[i];
|
||||
if (nextPointX < 0 || nextPointY < 0 || nextPointX >= W || nextPointY >= H)
|
||||
continue;
|
||||
var k = (nextPointY * W + nextPointX) * 4;
|
||||
if(imgData_tmp[k+3] != 0) continue; //already parsed
|
||||
|
||||
if(Math.abs(imgData[k] - color_from.r) <= sensitivity
|
||||
&& Math.abs(imgData[k+1] - color_from.g) <= sensitivity
|
||||
&& Math.abs(imgData[k+2] - color_from.b) <= sensitivity
|
||||
&& Math.abs(imgData[k+3] - color_from.a) <= sensitivity){
|
||||
imgData_tmp[k] = color_to.r; //r
|
||||
imgData_tmp[k+1] = color_to.g; //g
|
||||
imgData_tmp[k+2] = color_to.b; //b
|
||||
imgData_tmp[k+3] = color_to.a; //a
|
||||
|
||||
stack.push([nextPointX, nextPointY]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//destination-out + blur = anti-aliasing
|
||||
if(anti_aliasing == true)
|
||||
img_tmp = ImageFilters.StackBlur(img_tmp, 2);
|
||||
canvas_front.putImageData(img_tmp, 0, 0);
|
||||
context.globalCompositeOperation = "destination-out";
|
||||
context.drawImage(document.getElementById("canvas_front"), 0, 0);
|
||||
//reset
|
||||
context.shadowBlur = 0;
|
||||
context.globalCompositeOperation = 'source-over';
|
||||
};
|
||||
this.if_blank = function(canvas){
|
||||
var img = canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height);
|
||||
var imgData = img.data;
|
||||
|
||||
if(MAIN.TRANSPARENCY == false){
|
||||
//transparency disabled
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i] < 255 || imgData[i+1] < 255 || imgData[i+2] < 255) return false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//transparenc enabled
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
if(imgData[i] < 255 || imgData[i+1] < 255 || imgData[i+2] < 255) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
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;
|
||||
var all_right = WIDTH;
|
||||
for(var i in LAYERS){
|
||||
if(layer != undefined && LAYERS[i].name != layer) continue;
|
||||
|
||||
var top = 0;
|
||||
var left = 0;
|
||||
var bottom = 0;
|
||||
var right = 0;
|
||||
var img = document.getElementById(LAYERS[i].name).getContext("2d").getImageData(0, 0, WIDTH, 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++;
|
||||
}
|
||||
all_top = Math.min(all_top, top);
|
||||
all_left = Math.min(all_left, left);
|
||||
all_bottom = Math.min(all_bottom, bottom);
|
||||
all_right = Math.min(all_right, right);
|
||||
}
|
||||
//move to top-left corner
|
||||
for(var i in LAYERS){
|
||||
if(layer != undefined && LAYERS[i].name != layer) continue;
|
||||
|
||||
tmp_data = document.getElementById(LAYERS[i].name).getContext("2d").getImageData(0, 0, WIDTH, HEIGHT);
|
||||
document.getElementById(LAYERS[i].name).getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
document.getElementById(LAYERS[i].name).getContext("2d").putImageData(tmp_data, -all_left, -all_top);
|
||||
var canvas_name = LAYERS[i].name;
|
||||
}
|
||||
//resize
|
||||
if(no_resize != undefined) return false;
|
||||
if(layer != undefined){
|
||||
var W = round(WIDTH - all_left - all_right);
|
||||
var H = round(HEIGHT - all_top - all_bottom);
|
||||
|
||||
var imageData = document.getElementById(layer).getContext("2d").getImageData(0, 0, W, H);
|
||||
document.getElementById(layer).width = W;
|
||||
document.getElementById(layer).height = H;
|
||||
document.getElementById(layer).getContext("2d").clearRect(0, 0, W, H);
|
||||
document.getElementById(layer).getContext("2d").putImageData(imageData, 0, 0);
|
||||
|
||||
return {
|
||||
top: all_top,
|
||||
left: all_left,
|
||||
bottom: all_bottom,
|
||||
right: all_right
|
||||
};
|
||||
}
|
||||
else{
|
||||
WIDTH = WIDTH - all_left - all_right;
|
||||
HEIGHT = HEIGHT - all_top - all_bottom;
|
||||
if(WIDTH<1) WIDTH = 1;
|
||||
if(HEIGHT<1) HEIGHT = 1;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
}
|
||||
LAYER.update_info_block();
|
||||
};
|
||||
this.effect_bw = function(context, W, H, level, dithering){
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
var grey, c, quant_error, m;
|
||||
if(dithering !== true){
|
||||
//no differing
|
||||
for(var i = 0; i < imgData.length; i += 4){
|
||||
if(imgData[i+3] == 0) continue; //transparent
|
||||
grey = round(0.2126 * imgData[i] + 0.7152 * imgData[i+1] + 0.0722 * imgData[i+2]);
|
||||
if(grey <= level)
|
||||
c = 0;
|
||||
else
|
||||
c = 255;
|
||||
imgData[i] = c;
|
||||
imgData[i+1] = c;
|
||||
imgData[i+2] = c;
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Floyd–Steinberg dithering
|
||||
canvas_front.clearRect(0, 0, W, H); //temp canvas for storing pixel data shifts
|
||||
var img2 = canvas_front.getImageData(0, 0, W, H);
|
||||
var imgData2 = img2.data;
|
||||
for(var j = 0; j < H; j++){
|
||||
for(var i = 0; i < W; i++){
|
||||
var k = ((j * (W * 4)) + (i * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
|
||||
grey = round(0.2126 * imgData[k] + 0.7152 * imgData[k+1] + 0.0722 * imgData[k+2]);
|
||||
grey = grey + imgData2[k]; //add data shft from previous iterations
|
||||
c = Math.floor(grey / 256);
|
||||
if(c == 1)
|
||||
c = 255;
|
||||
imgData[k] = c;
|
||||
imgData[k+1] = c;
|
||||
imgData[k+2] = c;
|
||||
quant_error = grey - c;
|
||||
if(i+1 < W){
|
||||
m = k + 4;
|
||||
imgData2[m] += Math.round(quant_error * 7/16);
|
||||
}
|
||||
if(i-1 > 0 && j+1 < H){
|
||||
m = k - 4 + W*4;
|
||||
imgData2[m] += Math.round(quant_error * 3/16);
|
||||
}
|
||||
if(j+1 < H){
|
||||
m = k + W*4;
|
||||
imgData2[m] += Math.round(quant_error * 5/16);
|
||||
}
|
||||
if(i+1 < W && j+1 < H){
|
||||
m = k + 4 + W*4;
|
||||
imgData2[m] += Math.round(quant_error * 1/16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
};
|
||||
this.decrease_colors = function(canvas_source, canvas_destination, W, H, colors, dithering, greyscale){
|
||||
var context = canvas_destination.getContext("2d");
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
var imgData = img.data;
|
||||
var palette = [];
|
||||
|
||||
//collect top colors
|
||||
var block_size = 10;
|
||||
var ctx = canvas_front; //use temp canvas
|
||||
ctx.clearRect(0, 0, W, H);
|
||||
ctx.drawImage(canvas_source, 0, 0, Math.ceil(canvas_source.width/block_size), Math.ceil(canvas_source.height/block_size)); //simple resize
|
||||
var img_p = ctx.getImageData(0, 0, Math.ceil(canvas_source.width/block_size), Math.ceil(canvas_source.height/block_size));
|
||||
var imgData_p = img_p.data;
|
||||
ctx.clearRect(0, 0, W, H);
|
||||
|
||||
for(var i = 0; i < imgData_p.length; i += 4){
|
||||
if(imgData_p[i+3] == 0) continue; //transparent
|
||||
var grey = round(0.2126 * imgData_p[i] + 0.7152 * imgData_p[i+1] + 0.0722 * imgData_p[i+2]);
|
||||
palette.push([ imgData_p[i], imgData_p[i+1], imgData_p[i+2], grey ]);
|
||||
}
|
||||
|
||||
//calculate weights
|
||||
var grey_palette = [];
|
||||
for(var i = 0; i < 256; i++)
|
||||
grey_palette[i] = 0;
|
||||
for(var i = 0; i < palette.length; i++)
|
||||
grey_palette[palette[i][3]]++;
|
||||
|
||||
//remove similar colors
|
||||
for(var max = 10*3; max < 100*3; max = max + 10*3){
|
||||
if(palette.length <= colors) break;
|
||||
for(var i = 0; i < palette.length; i++){
|
||||
if(palette.length <= colors) break;
|
||||
var valid = true;
|
||||
for(var j = 0; j < palette.length; j++){
|
||||
if(palette.length <= colors) break;
|
||||
if(i == j) continue;
|
||||
if(Math.abs(palette[i][0] - palette[j][0]) + Math.abs(palette[i][1] - palette[j][1]) + Math.abs(palette[i][2] - palette[j][2]) < max){
|
||||
if(grey_palette[palette[i][3]] > grey_palette[palette[j][3]]){
|
||||
//remove color
|
||||
palette.splice(j, 1);
|
||||
j--;
|
||||
}
|
||||
else{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//remove color
|
||||
if(valid == false){
|
||||
palette.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//change
|
||||
var p_n = palette.length;
|
||||
for(var j = 0; j < H; j++){
|
||||
for(var i = 0; i < W; i++){
|
||||
var k = ((j * (W * 4)) + (i * 4));
|
||||
if(imgData[k+3] == 0) continue; //transparent
|
||||
var grey = round(0.2126 * imgData_p[k] + 0.7152 * imgData_p[k+1] + 0.0722 * imgData_p[k+2]);
|
||||
|
||||
//find closest color
|
||||
var index1 = 0;
|
||||
var min = 999999;
|
||||
var diff1;
|
||||
for(var m=0; m < p_n; m++){
|
||||
var diff = Math.abs(palette[m][0] - imgData[k]) + Math.abs(palette[m][1] - imgData[k+1]) + Math.abs(palette[m][2] - imgData[k+2]);
|
||||
if(diff < min){
|
||||
min = diff;
|
||||
index1 = m;
|
||||
diff1 = diff;
|
||||
}
|
||||
}
|
||||
|
||||
if(dithering == false){
|
||||
imgData[k] = palette[index1][0];
|
||||
imgData[k+1] = palette[index1][1];
|
||||
imgData[k+2] = palette[index1][2];
|
||||
}
|
||||
else{
|
||||
//dithering
|
||||
if(diff1 >= 10){
|
||||
//find second close color
|
||||
var index2;
|
||||
var min2 = 256*3;
|
||||
var diff2;
|
||||
for(var m=0; m < p_n; m++){
|
||||
if(m== index1) continue; //we already have this
|
||||
if(palette[index1][3] < grey && palette[m][3] < grey) continue;
|
||||
if(palette[index1][3] > grey && palette[m][3] > grey) continue;
|
||||
var diff = Math.abs(palette[m][0] - imgData[k]) + Math.abs(palette[m][1] - imgData[k+1]) + Math.abs(palette[m][2] - imgData[k+2]);
|
||||
if(diff < min2){
|
||||
min2 = diff;
|
||||
index2 = m;
|
||||
diff2 = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var c;
|
||||
if(index2 == undefined)
|
||||
c = palette[index1]; //only 1 match
|
||||
else{
|
||||
//randomize
|
||||
var rand = HELPER.getRandomInt(-diff1, diff2);
|
||||
if(rand < 0)
|
||||
c = palette[index2];
|
||||
else
|
||||
c = palette[index1];
|
||||
}
|
||||
imgData[k] = c[0];
|
||||
imgData[k+1] = c[1];
|
||||
imgData[k+2] = c[2];
|
||||
}
|
||||
|
||||
if(greyscale == true){
|
||||
var mid = round(0.2126 * imgData[k] + 0.7152 * imgData[k+1] + 0.0722 * imgData[k+2]);
|
||||
imgData[k] = mid;
|
||||
imgData[k+1] = mid;
|
||||
imgData[k+2] = mid;
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas_destination.getContext("2d").putImageData(img, 0, 0);
|
||||
};
|
||||
//converts greyscale images to coloured
|
||||
this.colorize = function(context, W, H, rand_power, max_gap, dither, manual_colors){
|
||||
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;
|
||||
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
|
||||
//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
|
||||
if(recalc == 1 || recalc == -1){
|
||||
var step = 100;
|
||||
if(ZOOM <= 100 && recalc < 0)
|
||||
step = 10;
|
||||
if(ZOOM <100 && recalc > 0)
|
||||
step = 10;
|
||||
if(recalc*step + ZOOM > 0){
|
||||
ZOOM = ZOOM + recalc*step;
|
||||
if(ZOOM > 100 && ZOOM < 200)
|
||||
ZOOM = 100;
|
||||
}
|
||||
}
|
||||
//zoom using exact value
|
||||
else
|
||||
ZOOM = parseInt(recalc);
|
||||
CON.calc_preview_auto();
|
||||
}
|
||||
document.getElementById("zoom_nr").innerHTML = ZOOM;
|
||||
document.getElementById("zoom_range").value = ZOOM;
|
||||
|
||||
//change scale and repaint
|
||||
document.getElementById('canvas_back').style.width = round(WIDTH * ZOOM / 100)+"px";
|
||||
document.getElementById('canvas_back').style.height = round(HEIGHT * ZOOM / 100)+"px";
|
||||
for(var i in LAYERS){
|
||||
document.getElementById(LAYERS[i].name).style.width = round(WIDTH * ZOOM / 100)+"px";
|
||||
document.getElementById(LAYERS[i].name).style.height = round(HEIGHT * ZOOM / 100)+"px";
|
||||
}
|
||||
document.getElementById('canvas_front').style.width = round(WIDTH * ZOOM / 100)+"px";
|
||||
document.getElementById('canvas_front').style.height = round(HEIGHT * ZOOM / 100)+"px";
|
||||
|
||||
document.getElementById('canvas_grid').style.width = round(WIDTH * ZOOM / 100)+"px";
|
||||
document.getElementById('canvas_grid').style.height = round(HEIGHT * ZOOM / 100)+"px";
|
||||
|
||||
//check main resize corners
|
||||
if(ZOOM != 100){
|
||||
document.getElementById('resize-w').style.display = "none";
|
||||
document.getElementById('resize-h').style.display = "none";
|
||||
document.getElementById('resize-wh').style.display = "none";
|
||||
}
|
||||
else{
|
||||
document.getElementById('resize-w').style.display = "block";
|
||||
document.getElementById('resize-h').style.display = "block";
|
||||
document.getElementById('resize-wh').style.display = "block";
|
||||
}
|
||||
|
||||
if(scroll != undefined)
|
||||
CON.scroll_window();
|
||||
DRAW.redraw_preview();
|
||||
return true;
|
||||
};
|
||||
this.redraw_preview = function(){
|
||||
canvas_preview.beginPath();
|
||||
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, DRAW.PREVIEW_SIZE.w, DRAW.PREVIEW_SIZE.h, 5);
|
||||
|
||||
//redraw preview area
|
||||
canvas_preview.save();
|
||||
canvas_preview.scale(DRAW.PREVIEW_SIZE.w/WIDTH, DRAW.PREVIEW_SIZE.h/HEIGHT);
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS[i].visible == false) continue;
|
||||
canvas_preview.drawImage(document.getElementById(LAYERS[i].name), 0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
canvas_preview.restore();
|
||||
|
||||
//active zone
|
||||
z_x = CON.ZOOM_X;
|
||||
z_y = CON.ZOOM_Y;
|
||||
if(z_x > DRAW.PREVIEW_SIZE.w - CON.mini_rect_data.w)
|
||||
z_x = DRAW.PREVIEW_SIZE.w - CON.mini_rect_data.w;
|
||||
if(z_y > DRAW.PREVIEW_SIZE.h - CON.mini_rect_data.h)
|
||||
z_y = DRAW.PREVIEW_SIZE.h - CON.mini_rect_data.h;
|
||||
|
||||
canvas_preview.lineWidth = 1;
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.rect(round(z_x) + 0.5, round(z_y) + 0.5, CON.mini_rect_data.w, CON.mini_rect_data.h);
|
||||
canvas_preview.fillStyle = "rgba(0, 0, 0, 0.2)";
|
||||
canvas_preview.strokeStyle = "#393939";
|
||||
canvas_preview.fill();
|
||||
canvas_preview.stroke();
|
||||
return true;
|
||||
};
|
||||
this.draw_arrow = function(context, fromx, fromy, tox, toy, headlen){
|
||||
if(headlen == undefined)
|
||||
headlen = 10; // length of head in pixels
|
||||
var dx = tox-fromx;
|
||||
var dy = toy-fromy;
|
||||
var angle = Math.atan2(dy,dx);
|
||||
context.beginPath();
|
||||
context.moveTo(fromx, fromy);
|
||||
context.lineTo(tox, toy);
|
||||
context.stroke();
|
||||
context.beginPath();
|
||||
context.moveTo(tox-headlen*Math.cos(angle-Math.PI/6),toy-headlen*Math.sin(angle-Math.PI/6));
|
||||
context.lineTo(tox, toy);
|
||||
context.lineTo(tox-headlen*Math.cos(angle+Math.PI/6),toy-headlen*Math.sin(angle+Math.PI/6));
|
||||
context.stroke();
|
||||
};
|
||||
//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);
|
||||
|
||||
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 weights_alpha = 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);
|
||||
//alpha
|
||||
gx_a += weight * data[dx + 3];
|
||||
weights_alpha += weight;
|
||||
//colors
|
||||
if(data[dx + 3] < 255)
|
||||
weight = weight * data[dx + 3] / 250;
|
||||
gx_r += weight * data[dx];
|
||||
gx_g += weight * data[dx + 1];
|
||||
gx_b += weight * data[dx + 2];
|
||||
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_alpha;
|
||||
}
|
||||
}
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
|
||||
if(MENU.last_menu != 'layer_resize')
|
||||
DRAW.trim();
|
||||
DRAW.zoom();
|
||||
}
|
||||
};
|
||||
my_worker.postMessage([img, W, H, W2, H2, c, cores]);
|
||||
}
|
||||
};
|
||||
}
|
||||
1598
js/draw_tools.js
Normal file
1598
js/draw_tools.js
Normal file
File diff suppressed because it is too large
Load Diff
148
js/edit.js
Normal file
148
js/edit.js
Normal file
@ -0,0 +1,148 @@
|
||||
/* global MAIN, POP, LAYER, DRAW, GUI */
|
||||
/* global WIDTH, HEIGHT, canvas_active, canvas_front */
|
||||
|
||||
var EDIT = new EDIT_CLASS();
|
||||
|
||||
/**
|
||||
* manages edit actions
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function EDIT_CLASS() {
|
||||
|
||||
/**
|
||||
* used to store internal copied objects data
|
||||
*/
|
||||
var PASTE_DATA = false;
|
||||
|
||||
/**
|
||||
* latest 3 saved states of all layers for undo
|
||||
*/
|
||||
var layers_archive = [{}, {}, {}];
|
||||
|
||||
/**
|
||||
* on undo, current data index in layers_archive array
|
||||
*/
|
||||
var undo_level = 0;
|
||||
|
||||
//undo
|
||||
this.edit_undo = function () {
|
||||
this.undo();
|
||||
};
|
||||
|
||||
//cut
|
||||
this.edit_cut = function () {
|
||||
this.save_state();
|
||||
if (DRAW.select_data != false) {
|
||||
this.copy_to_clipboard();
|
||||
canvas_active().clearRect(DRAW.select_data.x, DRAW.select_data.y, DRAW.select_data.w, DRAW.select_data.h);
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
//copy
|
||||
this.edit_copy = function () {
|
||||
if (DRAW.select_data != false) {
|
||||
this.copy_to_clipboard();
|
||||
}
|
||||
};
|
||||
|
||||
//paste
|
||||
this.edit_paste = function () {
|
||||
this.save_state();
|
||||
this.paste('menu');
|
||||
};
|
||||
|
||||
//select all
|
||||
this.edit_select = function () {
|
||||
DRAW.select_data = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: WIDTH,
|
||||
h: HEIGHT
|
||||
};
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
GUI.draw_selected_area();
|
||||
};
|
||||
|
||||
//clear selection
|
||||
this.edit_clear = function () {
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
};
|
||||
|
||||
this.copy_to_clipboard = function () {
|
||||
PASTE_DATA = false;
|
||||
PASTE_DATA = document.createElement("canvas");
|
||||
PASTE_DATA.width = DRAW.select_data.w;
|
||||
PASTE_DATA.height = DRAW.select_data.h;
|
||||
PASTE_DATA.getContext("2d").drawImage(canvas_active(true), DRAW.select_data.x, DRAW.select_data.y, DRAW.select_data.w, DRAW.select_data.h, 0, 0, DRAW.select_data.w, DRAW.select_data.h);
|
||||
};
|
||||
|
||||
this.paste = function (type) {
|
||||
if (PASTE_DATA == false) {
|
||||
if (type == 'menu') {
|
||||
POP.add({title: "Error:", value: 'Empty data'});
|
||||
POP.add({title: "Notice:", value: 'To paste from clipboard, use Ctrl-V.'});
|
||||
POP.show('Notice', '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp = new Array();
|
||||
var new_name = 'Layer #' + (LAYER.layers.length + 1);
|
||||
LAYER.create_canvas(new_name);
|
||||
LAYER.layers.push({name: new_name, visible: true});
|
||||
LAYER.layer_active = LAYER.layers.length - 1;
|
||||
canvas_active().drawImage(PASTE_DATA, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
};
|
||||
|
||||
this.save_state = function () {
|
||||
undo_level = 0;
|
||||
j = 0;
|
||||
|
||||
//move previous
|
||||
layers_archive[2] = layers_archive[1];
|
||||
layers_archive[1] = layers_archive[0];
|
||||
|
||||
//save last state
|
||||
layers_archive[j] = {};
|
||||
layers_archive[j].width = WIDTH;
|
||||
layers_archive[j].height = HEIGHT;
|
||||
layers_archive[j].data = {};
|
||||
for (var i in LAYER.layers) {
|
||||
layers_archive[j].data[LAYER.layers[i].name] = document.createElement('canvas');
|
||||
layers_archive[j].data[LAYER.layers[i].name].width = WIDTH;
|
||||
layers_archive[j].data[LAYER.layers[i].name].height = HEIGHT;
|
||||
layers_archive[j].data[LAYER.layers[i].name].getContext('2d').drawImage(document.getElementById(LAYER.layers[i].name), 0, 0);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
//supports 3 levels undo system - more levels requires more memory
|
||||
this.undo = function () {
|
||||
if (layers_archive.length == 0)
|
||||
return false;
|
||||
j = undo_level;
|
||||
undo_level++;
|
||||
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;
|
||||
LAYER.set_canvas_size(true);
|
||||
return true; //size changed, cant undo
|
||||
}
|
||||
|
||||
//undo
|
||||
for (var i in LAYER.layers) {
|
||||
if (layers_archive[j].data[LAYER.layers[i].name] != undefined) {
|
||||
document.getElementById(LAYER.layers[i].name).getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
document.getElementById(LAYER.layers[i].name).getContext("2d").drawImage(layers_archive[j].data[LAYER.layers[i].name], 0, 0);
|
||||
}
|
||||
}
|
||||
GUI.zoom();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
1178
js/effects.js
vendored
Normal file
1178
js/effects.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
289
js/elements.js
Normal file
289
js/elements.js
Normal file
@ -0,0 +1,289 @@
|
||||
/* global WIDTH, HEIGHT */
|
||||
|
||||
var EL = new ELEMENTS_CLASS();
|
||||
|
||||
/**
|
||||
* class that draw simple elements
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function ELEMENTS_CLASS() {
|
||||
|
||||
//draw lines
|
||||
this.line = function(ctx, from_x, from_y, to_x, to_y, size){
|
||||
ctx.beginPath();
|
||||
if(size != undefined)
|
||||
ctx.lineWidth = size;
|
||||
ctx.moveTo(from_x + 0.5, from_y + 0.5);
|
||||
ctx.lineTo(to_x + 0.5, to_y + 0.5);
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
//draws rectangle
|
||||
this.rectangle = function (ctx, x, y, width, height, fill, stroke) {
|
||||
x = x + 0.5;
|
||||
y = y + 0.5;
|
||||
if (typeof stroke == "undefined")
|
||||
stroke = true;
|
||||
if(fill == false && stroke == undefined)
|
||||
stroke = true;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x + width, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y);
|
||||
ctx.lineTo(x + width, y + height);
|
||||
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height);
|
||||
ctx.lineTo(x, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height);
|
||||
ctx.lineTo(x, y);
|
||||
ctx.quadraticCurveTo(x, y, x, y);
|
||||
ctx.closePath();
|
||||
if (stroke) {
|
||||
ctx.stroke();
|
||||
}
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
};
|
||||
|
||||
//draws square
|
||||
this.square = function (ctx, x, y, width, height, fill, stroke) {
|
||||
x = x + 0.5;
|
||||
y = y + 0.5;
|
||||
if (typeof stroke == "undefined")
|
||||
stroke = true;
|
||||
if(fill == false && stroke == undefined)
|
||||
stroke = true;
|
||||
|
||||
if (Math.abs(width) < Math.abs(height)){
|
||||
if(width > 0)
|
||||
width = Math.abs(height);
|
||||
else
|
||||
width = -Math.abs(height);
|
||||
}
|
||||
else{
|
||||
if(height > 0)
|
||||
height = Math.abs(width);
|
||||
else
|
||||
height = -Math.abs(width);
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x + width, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y);
|
||||
ctx.lineTo(x + width, y + height);
|
||||
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height);
|
||||
ctx.lineTo(x, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height);
|
||||
ctx.lineTo(x, y);
|
||||
ctx.quadraticCurveTo(x, y, x, y);
|
||||
ctx.closePath();
|
||||
if (stroke) {
|
||||
ctx.stroke();
|
||||
}
|
||||
if (fill) {
|
||||
ctx.fill();
|
||||
}
|
||||
};
|
||||
|
||||
this.circle = function (ctx, x, y, size, color) {
|
||||
ctx.lineWidth = 1;
|
||||
if(color != undefined)
|
||||
ctx.strokeStyle = color;
|
||||
else
|
||||
ctx.strokeStyle = "#000000";
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, size / 2, 0, Math.PI * 2, true);
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
this.ellipse_by_center = function (ctx, cx, cy, w, h, color, fill) {
|
||||
this.ellipse(ctx, cx - w / 2.0, cy - h / 2.0, w, h, color, fill);
|
||||
};
|
||||
|
||||
this.ellipse = function (ctx, x, y, w, h, color, fill) {
|
||||
var kappa = .5522848,
|
||||
ox = (w / 2) * kappa, // control point offset horizontal
|
||||
oy = (h / 2) * kappa, // control point offset vertical
|
||||
xe = x + w, // x-end
|
||||
ye = y + h, // y-end
|
||||
xm = x + w / 2, // x-middle
|
||||
ym = y + h / 2; // y-middle
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, ym);
|
||||
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
|
||||
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
|
||||
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
|
||||
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = color;
|
||||
ctx.strokeStyle = color;
|
||||
if (fill == undefined)
|
||||
ctx.stroke();
|
||||
else
|
||||
ctx.fill();
|
||||
};
|
||||
|
||||
this.arrow = function (context, fromx, fromy, tox, toy, headlen) {
|
||||
if (headlen == undefined)
|
||||
headlen = 10; // length of head in pixels
|
||||
var dx = tox - fromx;
|
||||
var dy = toy - fromy;
|
||||
var angle = Math.atan2(dy, dx);
|
||||
context.beginPath();
|
||||
context.moveTo(fromx, fromy);
|
||||
context.lineTo(tox, toy);
|
||||
context.stroke();
|
||||
context.beginPath();
|
||||
context.moveTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
|
||||
context.lineTo(tox, toy);
|
||||
context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
|
||||
context.stroke();
|
||||
};
|
||||
|
||||
//dashed objects
|
||||
this.rectangle_dashed = function (canvas, x1, y1, x2, y2, dashLen, color) {
|
||||
this.line_dashed(canvas, x1, y1, x2, y1, dashLen, color);
|
||||
this.line_dashed(canvas, x2, y1, x2, y2, dashLen, color);
|
||||
this.line_dashed(canvas, x2, y2, x1, y2, dashLen, color);
|
||||
this.line_dashed(canvas, x1, y2, x1, y1, dashLen, color);
|
||||
};
|
||||
|
||||
this.line_dashed = function (canvas, x1, y1, x2, y2, dashLen, color) {
|
||||
x1 = x1 + 0.5;
|
||||
y1 = y1 + 0.5;
|
||||
x2 = x2 + 0.5;
|
||||
y2 = y2 + 0.5;
|
||||
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;
|
||||
var dY = y2 - y1;
|
||||
var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
|
||||
var dashX = dX / dashes;
|
||||
var dashY = dY / dashes;
|
||||
var q = 0;
|
||||
while (q++ < dashes) {
|
||||
x1 += dashX;
|
||||
y1 += dashY;
|
||||
canvas[q % 2 == 0 ? 'moveTo' : 'lineTo'](x1, y1);
|
||||
}
|
||||
canvas[q % 2 == 0 ? 'moveTo' : 'lineTo'](x2, y2);
|
||||
canvas.stroke();
|
||||
canvas.closePath();
|
||||
};
|
||||
|
||||
this.image_round = function (canvas, mouse_x, mouse_y, size, img_data, canvas_tmp, anti_alias) {
|
||||
var size_half = Math.round(size / 2);
|
||||
var ctx_tmp = canvas_tmp.getContext("2d");
|
||||
var xx = mouse_x - size_half;
|
||||
var yy = mouse_y - size_half;
|
||||
if (xx < 0)
|
||||
xx = 0;
|
||||
if (yy < 0)
|
||||
yy = 0;
|
||||
|
||||
ctx_tmp.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
ctx_tmp.save();
|
||||
//draw main data
|
||||
try {
|
||||
ctx_tmp.drawImage(img_data, mouse_x - size_half, mouse_y - size_half, size, size);
|
||||
}
|
||||
catch (err) {
|
||||
try {
|
||||
ctx_tmp.putImageData(img_data, xx, yy);
|
||||
}
|
||||
catch (err) {
|
||||
console.log("Error: " + err.message);
|
||||
}
|
||||
}
|
||||
ctx_tmp.globalCompositeOperation = 'destination-in';
|
||||
|
||||
//create form
|
||||
ctx_tmp.fillStyle = '#ffffff';
|
||||
if (anti_alias == true) {
|
||||
var gradient = ctx_tmp.createRadialGradient(mouse_x, mouse_y, 0, mouse_x, mouse_y, size_half);
|
||||
gradient.addColorStop(0, '#ffffff');
|
||||
gradient.addColorStop(0.8, '#ffffff');
|
||||
gradient.addColorStop(1, 'rgba(25115,255,255,0');
|
||||
ctx_tmp.fillStyle = gradient;
|
||||
}
|
||||
ctx_tmp.beginPath();
|
||||
ctx_tmp.arc(mouse_x, mouse_y, size_half, 0, 2 * Math.PI, true);
|
||||
ctx_tmp.fill();
|
||||
//draw final data
|
||||
if (xx + size > WIDTH)
|
||||
size = WIDTH - xx;
|
||||
if (yy + size > HEIGHT)
|
||||
size = HEIGHT - yy;
|
||||
canvas.drawImage(canvas_tmp, xx, yy, size, size, xx, yy, size, size);
|
||||
//reset
|
||||
ctx_tmp.restore();
|
||||
ctx_tmp.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
};
|
||||
}
|
||||
|
||||
//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, size) {
|
||||
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 = size;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.strokeStyle = 'rgba(' + color_rgb.r + ', ' + color_rgb.g + ', ' + color_rgb.b + ', 0.9)';
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
// draw extra strokes
|
||||
ctx.lineWidth = 1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
784
js/events.js
Normal file
784
js/events.js
Normal file
@ -0,0 +1,784 @@
|
||||
/* global FILE, EDIT, HELPER, POP, MAIN, EVENTS, LAYER, IMAGE, GUI, DRAW */
|
||||
/* global canvas_active, canvas_front, WIDTH, HEIGHT, EXIF */
|
||||
|
||||
var EVENTS = new EVENTS_CLASS();
|
||||
|
||||
//keyboard handlers
|
||||
document.onkeydown = function(e) { return EVENTS.on_keyboard_action(e); };
|
||||
document.onkeyup = function(e) {return EVENTS.on_keyboardup_action(e); };
|
||||
//mouse
|
||||
window.ondrop = function(e) { EVENTS.upload_drop(e); }; //drop
|
||||
window.ondragover = function(e) { e.preventDefault(); };
|
||||
window.onresize = function(e){ EVENTS.on_resize(); }; //window resize
|
||||
document.onmousedown = EVENTS.mouse_click; //mouse click
|
||||
document.onmousemove = EVENTS.mouse_move; //mouse move
|
||||
document.onmouseup = EVENTS.mouse_release; //mouse resease
|
||||
document.addEventListener("mousewheel", EVENTS.mouse_wheel_handler, false); //mouse scroll
|
||||
document.addEventListener("DOMMouseScroll", EVENTS.mouse_wheel_handler, false); //mouse scroll
|
||||
document.oncontextmenu = function (e) { return EVENTS.mouse_right_click(e); }; //mouse right click
|
||||
document.getElementById('color_hex').onkeyup = function (e) { GUI.set_color_manual(e); }; //on main color type
|
||||
document.getElementById('color_hex').onpaste = function (e) { GUI.set_color_manual(e); }; // on paste in main color input
|
||||
|
||||
/**
|
||||
* all events handling
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function EVENTS_CLASS() {
|
||||
|
||||
/**
|
||||
* mouse data, like positions, clicks
|
||||
*/
|
||||
this.mouse;
|
||||
|
||||
/**
|
||||
* if user is holding ctrl
|
||||
*/
|
||||
this.ctrl_pressed = false; //17
|
||||
|
||||
/**
|
||||
* if use is holding shift
|
||||
*/
|
||||
this.shift_pressed = false; //16
|
||||
|
||||
/**
|
||||
* active area start position in preview canvas in right sidebar
|
||||
*/
|
||||
this.ZOOM_POS = [0, 0];
|
||||
|
||||
/**
|
||||
* active area dimensions in preview canvas in right sidebar
|
||||
*/
|
||||
this.mini_rect_data = {w: 0, h: 0};
|
||||
|
||||
/**
|
||||
* if use is draging
|
||||
*/
|
||||
this.isDrag = false;
|
||||
|
||||
/**
|
||||
* selected area resize rect. size (controlls, where you can resize area)
|
||||
*/
|
||||
this.sr_size = 8;
|
||||
|
||||
/**
|
||||
* if false, font canvas is not cleared on mouse release
|
||||
*/
|
||||
this.clear_front_on_release = true;
|
||||
|
||||
/**
|
||||
* if canvas size was not changed - autosize possible
|
||||
*/
|
||||
var autosize = true;
|
||||
|
||||
/**
|
||||
* mouse click positions
|
||||
*/
|
||||
var mouse_click_pos = [false, false];
|
||||
|
||||
/**
|
||||
* last mouse move position
|
||||
*/
|
||||
var mouse_move_last = [false, false];
|
||||
|
||||
/**
|
||||
* main canvas resize action
|
||||
*/
|
||||
var resize_all = false;
|
||||
|
||||
/**
|
||||
* if mouse was click on canvas
|
||||
*/
|
||||
var mouse_click_valid = false;
|
||||
|
||||
/**
|
||||
* mouse click position of popup drag start
|
||||
*/
|
||||
var last_pop_click = [0, 0];
|
||||
|
||||
/**
|
||||
* popup position for drgable ability
|
||||
*/
|
||||
var popup_pos = [0, 0];
|
||||
|
||||
/**
|
||||
* if popup is dragged
|
||||
*/
|
||||
var popup_dragable = false;
|
||||
|
||||
//keyboard actions
|
||||
this.on_keyboard_action = function (event) {
|
||||
k = event.keyCode; //console.log(k);
|
||||
|
||||
if (k != 27) {
|
||||
if (POP != undefined && POP.active == true)
|
||||
return true; //dialog active
|
||||
if (document.activeElement.type == 'text')
|
||||
return true; //text input selected
|
||||
}
|
||||
|
||||
//up
|
||||
if (k == 38) {
|
||||
if (DRAW.active_tool == 'select_tool') {
|
||||
EDIT.save_state();
|
||||
LAYER.layer_move_active(0, -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//down
|
||||
else if (k == 40) {
|
||||
if (DRAW.active_tool == 'select_tool') {
|
||||
EDIT.save_state();
|
||||
LAYER.layer_move_active(0, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//left
|
||||
else if (k == 39) {
|
||||
if (DRAW.active_tool == 'select_tool') {
|
||||
EDIT.save_state();
|
||||
LAYER.layer_move_active(1, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//right
|
||||
else if (k == 37) {
|
||||
if (DRAW.active_tool == 'select_tool') {
|
||||
EDIT.save_state();
|
||||
LAYER.layer_move_active(-1, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//esc
|
||||
else if (k == 27) {
|
||||
if (POP != undefined && POP.active == true)
|
||||
POP.hide();
|
||||
DRAW.last_line = [false, false];
|
||||
|
||||
DRAW.curve_points = [];
|
||||
if (DRAW.select_data != false) {
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
DRAW.select_square_action = '';
|
||||
}
|
||||
}
|
||||
//z - undo
|
||||
else if (k == 90) {
|
||||
//undo
|
||||
if (EVENTS.ctrl_pressed == true)
|
||||
EDIT.undo();
|
||||
}
|
||||
//t - trim
|
||||
else if (k == 84) {
|
||||
EDIT.save_state();
|
||||
IMAGE.trim();
|
||||
}
|
||||
//o - open
|
||||
else if (k == 79)
|
||||
FILE.open();
|
||||
//s - save
|
||||
else if (k == 83) {
|
||||
if (POP != undefined)
|
||||
FILE.save_dialog(event);
|
||||
}
|
||||
//l - rotate left
|
||||
else if (k == 76) {
|
||||
EDIT.save_state();
|
||||
IMAGE.rotate_resize_doc(270, WIDTH, HEIGHT);
|
||||
IMAGE.rotate_layer({angle: 270}, canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//r - resize
|
||||
else if (k == 82)
|
||||
IMAGE.resize_box();
|
||||
//grid
|
||||
else if (k == 71) {
|
||||
if (GUI.grid == false)
|
||||
GUI.grid = true;
|
||||
else
|
||||
GUI.grid = false;
|
||||
GUI.draw_grid();
|
||||
}
|
||||
//del
|
||||
else if (k == 46) {
|
||||
if (DRAW.select_data != false) {
|
||||
EDIT.save_state();
|
||||
canvas_active().clearRect(DRAW.select_data.x, DRAW.select_data.y, DRAW.select_data.w, DRAW.select_data.h);
|
||||
DRAW.select_data = false;
|
||||
DRAW.select_square_action = '';
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
}
|
||||
//shift
|
||||
else if (k == 16)
|
||||
EVENTS.shift_pressed = true;
|
||||
//ctrl
|
||||
else if (k == 17) {
|
||||
if (EVENTS.ctrl_pressed == false)
|
||||
EVENTS.ctrl_pressed = true;
|
||||
}
|
||||
//d
|
||||
else if (k == 68) {
|
||||
call_menu(LAYER, 'layer_dublicate');
|
||||
}
|
||||
//a
|
||||
else if (k == 65) {
|
||||
if (EVENTS.ctrl_pressed == true) {
|
||||
DRAW.select_data = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: WIDTH,
|
||||
h: HEIGHT
|
||||
};
|
||||
GUI.draw_selected_area();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//v
|
||||
else if (k == 86) {
|
||||
EDIT.save_state();
|
||||
if (EVENTS.ctrl_pressed == true)
|
||||
EDIT.paste();
|
||||
}
|
||||
//f - fix images
|
||||
else if (k == 70) {
|
||||
EDIT.save_state();
|
||||
IMAGE.auto_adjust(canvas_active(), WIDTH, HEIGHT);
|
||||
}
|
||||
//h - histogram
|
||||
else if (k == 72) {
|
||||
IMAGE.histogram();
|
||||
}
|
||||
//-
|
||||
else if (k == 109)
|
||||
GUI.zoom(-1);
|
||||
//+
|
||||
else if (k == 107)
|
||||
GUI.zoom(+1);
|
||||
//n - new layer
|
||||
else if (k == 78)
|
||||
LAYER.add_layer();
|
||||
|
||||
//mac support - ctrl
|
||||
if (k == 17 || event.metaKey || event.ctrlKey) {
|
||||
if (EVENTS.ctrl_pressed == false)
|
||||
EVENTS.ctrl_pressed = true;
|
||||
}
|
||||
|
||||
GUI.zoom();
|
||||
return true;
|
||||
};
|
||||
//keyboard release
|
||||
this.on_keyboardup_action = function (event) {
|
||||
k = event.keyCode;
|
||||
//shift
|
||||
if (k == 16)
|
||||
EVENTS.shift_pressed = false;
|
||||
//ctrl
|
||||
else if (k == 17)
|
||||
EVENTS.ctrl_pressed = false;
|
||||
//mac support - ctrl
|
||||
if (event.metaKey || event.ctrlKey || event.key == 'Meta')
|
||||
EVENTS.ctrl_pressed = false;
|
||||
};
|
||||
// mouse_x, mouse_y, event.pageX, event.pageY
|
||||
this.get_mouse_position = function (event) {
|
||||
var valid = true;
|
||||
if (event.offsetX) {
|
||||
mouse_rel_x = event.offsetX;
|
||||
mouse_rel_y = event.offsetY;
|
||||
}
|
||||
else if (event.layerX) {
|
||||
mouse_rel_x = event.layerX;
|
||||
mouse_rel_y = event.layerY;
|
||||
}
|
||||
else
|
||||
return 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 (GUI.ZOOM != 100) {
|
||||
mouse_x = Math.floor(mouse_x / GUI.ZOOM * 100);
|
||||
mouse_y = Math.floor(mouse_y / GUI.ZOOM * 100);
|
||||
}
|
||||
}
|
||||
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
|
||||
EVENTS.mouse = {
|
||||
x: mouse_x,
|
||||
y: mouse_y,
|
||||
click_x: mouse_click_pos[0],
|
||||
click_y: mouse_click_pos[1],
|
||||
last_x: mouse_move_last[0],
|
||||
last_y: mouse_move_last[1],
|
||||
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;
|
||||
EVENTS.get_mouse_position(event);
|
||||
mouse_click_pos[0] = EVENTS.mouse.x;
|
||||
mouse_click_pos[1] = EVENTS.mouse.y;
|
||||
|
||||
for (var i in DRAW) {
|
||||
if (i == DRAW.active_tool) {
|
||||
return DRAW[i]('right_click', EVENTS.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
//mouse click
|
||||
this.mouse_click = function (event) {
|
||||
EVENTS.isDrag = true;
|
||||
if (POP != undefined && POP.active == true) {
|
||||
EVENTS.get_mouse_position(event);
|
||||
last_pop_click[0] = EVENTS.mouse.abs_x;
|
||||
last_pop_click[1] = EVENTS.mouse.abs_y;
|
||||
popup = document.getElementById('popup');
|
||||
popup_pos[0] = parseInt(popup.style.top);
|
||||
popup_pos[1] = 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;
|
||||
EVENTS.get_mouse_position(event);
|
||||
mouse_click_pos[0] = EVENTS.mouse.x;
|
||||
mouse_click_pos[1] = EVENTS.mouse.y;
|
||||
if (EVENTS.mouse.valid == false)
|
||||
mouse_click_valid = false;
|
||||
else
|
||||
mouse_click_valid = true;
|
||||
|
||||
|
||||
//check tools functions
|
||||
for (var i in DRAW) {
|
||||
if (i == DRAW.active_tool) {
|
||||
DRAW[i]('click', EVENTS.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.target.id == "canvas_preview")
|
||||
EVENTS.calc_preview_by_mouse(EVENTS.mouse.x, EVENTS.mouse.y);
|
||||
|
||||
//main window resize
|
||||
resize_all = false;
|
||||
if (GUI.ZOOM == 100) {
|
||||
if (event.target.id == "resize-w")
|
||||
resize_all = "w";
|
||||
else if (event.target.id == "resize-h")
|
||||
resize_all = "h";
|
||||
else if (event.target.id == "resize-wh")
|
||||
resize_all = "wh";
|
||||
}
|
||||
};
|
||||
//mouse move
|
||||
this.mouse_move = function (event) {
|
||||
if (POP != undefined && POP.active == true) {
|
||||
//drag popup
|
||||
if (EVENTS.isDrag == true && popup_dragable == true) {
|
||||
EVENTS.get_mouse_position(event);
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = (popup_pos[0] + EVENTS.mouse.abs_y - last_pop_click[1]) + 'px';
|
||||
popup.style.left = (popup_pos[1] + EVENTS.mouse.abs_x - last_pop_click[0]) + 'px';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EVENTS.get_mouse_position(event);
|
||||
if (event.target.id == "canvas_preview" && EVENTS.isDrag == true)
|
||||
EVENTS.calc_preview_by_mouse(EVENTS.mouse.x, EVENTS.mouse.y);
|
||||
LAYER.update_info_block();
|
||||
|
||||
//main window resize
|
||||
if (GUI.ZOOM == 100) {
|
||||
if (event.target.id == "resize-w")
|
||||
document.body.style.cursor = "w-resize";
|
||||
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 && EVENTS.isDrag == true) {
|
||||
document.body.style.cursor = "auto";
|
||||
if (resize_all == "w") {
|
||||
new_w = EVENTS.mouse.x;
|
||||
new_h = HEIGHT;
|
||||
}
|
||||
else if (resize_all == "h") {
|
||||
new_w = WIDTH;
|
||||
new_h = EVENTS.mouse.y;
|
||||
}
|
||||
else if (resize_all == "wh") {
|
||||
new_w = EVENTS.mouse.x;
|
||||
new_h = EVENTS.mouse.y;
|
||||
}
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_front.lineWidth = 1;
|
||||
canvas_front.fillStyle = "#ff0000";
|
||||
EL.rectangle_dashed(canvas_front, 0, 0, new_w - 1, new_h - 1);
|
||||
event.preventDefault();
|
||||
HELPER.remove_selection();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//check tools functions
|
||||
if (EVENTS.isDrag === false) {
|
||||
for (i in DRAW) {
|
||||
if (i == DRAW.active_tool) {
|
||||
DRAW[i]('move', EVENTS.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (EVENTS.isDrag === false)
|
||||
return false; //only drag now
|
||||
|
||||
//check tools functions
|
||||
for (var i in DRAW) {
|
||||
if (i == DRAW.active_tool) {
|
||||
DRAW[i]('drag', EVENTS.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (DRAW.active_tool != 'select_square')
|
||||
DRAW.select_square_action = '';
|
||||
|
||||
mouse_move_last[0] = EVENTS.mouse.x;
|
||||
mouse_move_last[1] = EVENTS.mouse.y;
|
||||
};
|
||||
//release mouse click
|
||||
this.mouse_release = function (event) {
|
||||
EVENTS.isDrag = false;
|
||||
if (POP != undefined && POP.active == true)
|
||||
return true;
|
||||
var mouse = EVENTS.get_mouse_position(event);
|
||||
mouse_move_last[0] = false;
|
||||
mouse_move_last[1] = false;
|
||||
if (DRAW.select_square_action == '' && EVENTS.mouse.valid == true)
|
||||
DRAW.select_data = false;
|
||||
|
||||
//check tools functions
|
||||
if (EVENTS.clear_front_on_release == true)
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
GUI.draw_selected_area();
|
||||
for (var i in DRAW) {
|
||||
if (i == DRAW.active_tool) {
|
||||
DRAW[i]('release', EVENTS.mouse, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//main window resize
|
||||
if (resize_all != false && GUI.ZOOM == 100 && EVENTS.mouse.x > 0 && EVENTS.mouse.y > 0) {
|
||||
EVENTS.autosize = false;
|
||||
document.body.style.cursor = "auto";
|
||||
if (resize_all == "w")
|
||||
WIDTH = EVENTS.mouse.x;
|
||||
else if (resize_all == "h")
|
||||
HEIGHT = EVENTS.mouse.y;
|
||||
else if (resize_all == "wh") {
|
||||
WIDTH = mouse_x;
|
||||
HEIGHT = EVENTS.mouse.y;
|
||||
}
|
||||
LAYER.set_canvas_size();
|
||||
GUI.zoom();
|
||||
}
|
||||
resize_all = false;
|
||||
GUI.zoom();
|
||||
};
|
||||
//upload drop zone
|
||||
this.upload_drop = function (e) {
|
||||
e.preventDefault();
|
||||
EDIT.save_state();
|
||||
var n_valid = 0;
|
||||
for (var i = 0, f; i < e.dataTransfer.files.length; i++) {
|
||||
f = e.dataTransfer.files[i];
|
||||
if (!f.type.match('image.*') && f.type != 'text/xml')
|
||||
continue;
|
||||
n_valid++;
|
||||
|
||||
var FR = new FileReader();
|
||||
FR.file = e.dataTransfer.files[i];
|
||||
|
||||
if (e.dataTransfer.files.length == 1)
|
||||
FILE.SAVE_NAME = f.name.split('.')[f.name.split('.').length - 2];
|
||||
|
||||
FR.onload = function (event) {
|
||||
if (this.file.type != 'text/xml') {
|
||||
//image
|
||||
LAYER.layer_add(this.file.name, event.target.result, this.file.type);
|
||||
EXIF.getData(this.file, FILE.save_EXIF);
|
||||
}
|
||||
else {
|
||||
//xml
|
||||
var responce = MAIN.load_xml(event.target.result);
|
||||
if (responce === true)
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if (f.type == "text/plain")
|
||||
FR.readAsText(f);
|
||||
else if (f.type == "text/xml")
|
||||
FR.readAsText(f);
|
||||
else
|
||||
FR.readAsDataURL(f);
|
||||
}
|
||||
};
|
||||
this.mouse_wheel_handler = function (e) { //return true;
|
||||
var step = 100;
|
||||
e.preventDefault();
|
||||
//zoom
|
||||
if (EVENTS.ctrl_pressed == true) {
|
||||
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
|
||||
if (GUI.ZOOM <= 100 && delta < 0)
|
||||
step = 10;
|
||||
if (GUI.ZOOM < 100 && delta > 0)
|
||||
step = 10;
|
||||
delta = delta * step;
|
||||
if (GUI.ZOOM + delta > 0) {
|
||||
GUI.ZOOM = GUI.ZOOM + delta;
|
||||
EVENTS.calc_preview_auto();
|
||||
GUI.zoom();
|
||||
}
|
||||
if (GUI.action_data().name == 'zoom') {
|
||||
GUI.action_data().attributes.zoom = GUI.ZOOM;
|
||||
show_action_attributes();
|
||||
}
|
||||
EVENTS.scroll_window();
|
||||
|
||||
//disable page scroll if ctrl pressed
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
this.scroll_window = function () {
|
||||
var total_w = (WIDTH * GUI.ZOOM / 100);
|
||||
var total_h = (HEIGHT * GUI.ZOOM / 100);
|
||||
|
||||
xx = total_w * EVENTS.ZOOM_POS[0] / (GUI.PREVIEW_SIZE.w);
|
||||
yy = total_h * EVENTS.ZOOM_POS[1] / (GUI.PREVIEW_SIZE.h);
|
||||
|
||||
var canvas_wrapper = document.querySelector('#canvas_wrapper');
|
||||
canvas_wrapper.scrollTop = yy;
|
||||
canvas_wrapper.scrollLeft = xx;
|
||||
};
|
||||
this.calc_preview_by_mouse = function (mouse_x, mouse_y) {
|
||||
EVENTS.ZOOM_POS[0] = mouse_x - EVENTS.mini_rect_data.w / 2;
|
||||
EVENTS.ZOOM_POS[1] = mouse_y - EVENTS.mini_rect_data.h / 2;
|
||||
if (EVENTS.ZOOM_POS[0] < 0)
|
||||
EVENTS.ZOOM_POS[1] = 0;
|
||||
if (EVENTS.ZOOM_Y < 0)
|
||||
EVENTS.ZOOM_Y = 0;
|
||||
|
||||
GUI.zoom(undefined, true);
|
||||
return true;
|
||||
};
|
||||
this.calc_preview_auto = function () {
|
||||
var canvas_wrapper = document.querySelector('#canvas_wrapper');
|
||||
var page_w = canvas_wrapper.clientWidth;
|
||||
var page_h = canvas_wrapper.clientHeight;
|
||||
|
||||
var total_w = (WIDTH * GUI.ZOOM / 100);
|
||||
var total_h = (HEIGHT * GUI.ZOOM / 100);
|
||||
|
||||
EVENTS.mini_rect_data.w = Math.round(page_w * GUI.PREVIEW_SIZE.w / total_w);
|
||||
EVENTS.mini_rect_data.h = Math.round(page_h * GUI.PREVIEW_SIZE.h / total_h);
|
||||
|
||||
GUI.redraw_preview();
|
||||
};
|
||||
this.on_resize = function(){
|
||||
EVENTS.calc_preview_auto();
|
||||
|
||||
//recalc popup position
|
||||
var dim = HELPER.get_dimensions();
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = 150 + 'px';
|
||||
popup.style.left = Math.round(dim[0] / 2) + 'px';
|
||||
};
|
||||
}
|
||||
|
||||
function call_menu(class_name, function_name) {
|
||||
$('#main_menu').find('.selected').click(); //close menu
|
||||
GUI.last_menu = function_name;
|
||||
|
||||
//exec
|
||||
class_name[function_name]();
|
||||
|
||||
GUI.zoom();
|
||||
}
|
||||
|
||||
//=== Clipboard ================================================================
|
||||
|
||||
var CLIPBOARD = new CLIPBOARD_CLASS('', false);
|
||||
|
||||
/**
|
||||
* image pasting into canvas
|
||||
*
|
||||
* @param {string} canvas_id - canvas id
|
||||
* @param {boolean} autoresize - if canvas will be resized
|
||||
*/
|
||||
function CLIPBOARD_CLASS(canvas_id, autoresize) {
|
||||
var _self = this;
|
||||
if (canvas_id != ''){
|
||||
var canvas = document.getElementById(canvas_id);
|
||||
var ctx = document.getElementById(canvas_id).getContext("2d");
|
||||
}
|
||||
var ctrl_pressed = false;
|
||||
var reading_dom = false;
|
||||
var text_top = 15;
|
||||
var pasteCatcher;
|
||||
var paste_mode;
|
||||
|
||||
//handlers
|
||||
document.addEventListener('keydown', function (e) {
|
||||
_self.on_keyboard_action(e);
|
||||
}, false); //firefox fix
|
||||
document.addEventListener('keyup', function (e) {
|
||||
_self.on_keyboardup_action(e);
|
||||
}, false); //firefox fix
|
||||
document.addEventListener('paste', function (e) {
|
||||
_self.paste_auto(e);
|
||||
}, false); //official paste handler
|
||||
|
||||
//constructor - prepare
|
||||
this.init = function () {
|
||||
//if using auto
|
||||
if (window.Clipboard)
|
||||
return true;
|
||||
|
||||
pasteCatcher = document.createElement("div");
|
||||
pasteCatcher.setAttribute("id", "paste_ff");
|
||||
pasteCatcher.setAttribute("contenteditable", "");
|
||||
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;';
|
||||
pasteCatcher.style.marginLeft = "-20px";
|
||||
pasteCatcher.style.width = "10px";
|
||||
document.body.appendChild(pasteCatcher);
|
||||
|
||||
// create an observer instance
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (paste_mode == 'auto' || ctrl_pressed == false || mutation.type != 'childList')
|
||||
return true;
|
||||
|
||||
//if paste handle failed - capture pasted object manually
|
||||
if(mutation.addedNodes.length == 1) {
|
||||
if (mutation.addedNodes[0].src != undefined) {
|
||||
//image
|
||||
_self.paste_createImage(mutation.addedNodes[0].src);
|
||||
}
|
||||
//register cleanup after some time.
|
||||
setTimeout(function () {
|
||||
pasteCatcher.innerHTML = '';
|
||||
}, 20);
|
||||
}
|
||||
});
|
||||
});
|
||||
var target = document.getElementById('paste_ff');
|
||||
var config = { attributes: true, childList: true, characterData: true };
|
||||
observer.observe(target, config);
|
||||
}();
|
||||
//default paste action
|
||||
this.paste_auto = function (e) {
|
||||
paste_mode = '';
|
||||
pasteCatcher.innerHTML = '';
|
||||
var plain_text_used = false;
|
||||
if (e.clipboardData) {
|
||||
var items = e.clipboardData.items;
|
||||
if (items) {
|
||||
paste_mode = 'auto';
|
||||
//access data directly
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf("image") !== -1) {
|
||||
//image
|
||||
var blob = items[i].getAsFile();
|
||||
var URLObj = window.URL || window.webkitURL;
|
||||
var source = URLObj.createObjectURL(blob);
|
||||
this.paste_createImage(source);
|
||||
}
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
else {
|
||||
//wait for DOMSubtreeModified event
|
||||
//https://bugzilla.mozilla.org/show_bug.cgi?id=891247
|
||||
}
|
||||
}
|
||||
};
|
||||
//on keyboard press
|
||||
this.on_keyboard_action = function (event) {
|
||||
if (POP.active == true)
|
||||
return true;
|
||||
k = event.keyCode;
|
||||
//ctrl
|
||||
if (k == 17 || event.metaKey || event.ctrlKey) {
|
||||
if (ctrl_pressed == false)
|
||||
ctrl_pressed = true;
|
||||
}
|
||||
//v
|
||||
if (k == 86) {
|
||||
if (document.activeElement != undefined && document.activeElement.type == 'text') {
|
||||
//let user paste into some input
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctrl_pressed == true && !window.Clipboard)
|
||||
pasteCatcher.focus();
|
||||
}
|
||||
};
|
||||
//on kaybord release
|
||||
this.on_keyboardup_action = function (event) {
|
||||
k = event.keyCode;
|
||||
//ctrl
|
||||
if (k == 17 || event.metaKey || event.ctrlKey || event.key == 'Meta')
|
||||
ctrl_pressed = false;
|
||||
};
|
||||
//draw image
|
||||
this.paste_createImage = function (source) {
|
||||
var pastedImage = new Image();
|
||||
pastedImage.onload = function () {
|
||||
if(canvas_id != ''){
|
||||
if(autoresize == true){
|
||||
//resize
|
||||
canvas.width = pastedImage.width;
|
||||
canvas.height = pastedImage.height;
|
||||
}
|
||||
else{
|
||||
//clear canvas
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
}
|
||||
LAYER.layer_add('Paste', source);
|
||||
};
|
||||
pastedImage.src = source;
|
||||
};
|
||||
}
|
||||
378
js/file.js
Normal file
378
js/file.js
Normal file
@ -0,0 +1,378 @@
|
||||
/* global MAIN, POP, LAYER, EXIF, HELPER, IMAGE, GUI */
|
||||
/* global SAVE_TYPES */
|
||||
|
||||
var FILE = new FILE_CLASS();
|
||||
|
||||
/**
|
||||
* manages files actions
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function FILE_CLASS() {
|
||||
|
||||
/**
|
||||
* exif data
|
||||
*/
|
||||
this.EXIF = false;
|
||||
|
||||
/**
|
||||
* default name used for saving file
|
||||
*/
|
||||
this.SAVE_NAME = 'example'; //default save name
|
||||
|
||||
/**
|
||||
* save types config
|
||||
*/
|
||||
this.SAVE_TYPES = [
|
||||
"PNG - Portable Network Graphics", //default
|
||||
"JPG - JPG/JPEG Format", //autodetect on photos where png useless?
|
||||
"XML - Full layers data", //aka PSD
|
||||
"BMP - Windows Bitmap", //firefox only, useless?
|
||||
"WEBP - Weppy File Format", //chrome only
|
||||
];
|
||||
//new
|
||||
this.file_new = function () {
|
||||
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);
|
||||
|
||||
if (response.transparency == 'Yes')
|
||||
GUI.TRANSPARENCY = true;
|
||||
else
|
||||
GUI.TRANSPARENCY = false;
|
||||
|
||||
GUI.ZOOM = 100;
|
||||
WIDTH = width;
|
||||
HEIGHT = height;
|
||||
MAIN.init();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
//open
|
||||
this.file_open = function () {
|
||||
this.open();
|
||||
};
|
||||
|
||||
//save
|
||||
this.file_save = function () {
|
||||
this.save_dialog();
|
||||
};
|
||||
|
||||
//print
|
||||
this.file_print = function () {
|
||||
window.print();
|
||||
};
|
||||
|
||||
this.open = function () {
|
||||
document.getElementById("tmp").innerHTML = '';
|
||||
var a = document.createElement('input');
|
||||
a.setAttribute("id", "file_open");
|
||||
a.type = 'file';
|
||||
a.multiple = 'multiple ';
|
||||
document.getElementById("tmp").appendChild(a);
|
||||
document.getElementById('file_open').addEventListener('change', this.open_handler, false);
|
||||
|
||||
//force click
|
||||
document.querySelector('#file_open').click();
|
||||
};
|
||||
|
||||
this.open_handler = function (e) {
|
||||
var files = e.target.files;
|
||||
for (var i = 0, f; i < files.length; i++) {
|
||||
f = files[i];
|
||||
if (!f.type.match('image.*') && f.type != 'text/xml')
|
||||
continue;
|
||||
if (files.length == 1)
|
||||
this.SAVE_NAME = f.name.split('.')[f.name.split('.').length - 2];
|
||||
|
||||
var FR = new FileReader();
|
||||
FR.file = e.target.files[i];
|
||||
|
||||
FR.onload = function (event) {
|
||||
if (this.file.type != 'text/xml') {
|
||||
//image
|
||||
LAYER.layer_add(this.file.name, event.target.result, this.file.type);
|
||||
EXIF.getData(this.file, this.save_EXIF);
|
||||
}
|
||||
else {
|
||||
//xml
|
||||
var responce = MAIN.load_xml(event.target.result);
|
||||
if (responce === true)
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if (f.type == "text/plain")
|
||||
FR.readAsText(f);
|
||||
else if (f.type == "text/xml")
|
||||
FR.readAsText(f);
|
||||
else
|
||||
FR.readAsDataURL(f);
|
||||
}
|
||||
};
|
||||
|
||||
this.save_dialog = function (e) {
|
||||
//find default format
|
||||
var save_default = this.SAVE_TYPES[0]; //png
|
||||
if (HELPER.getCookie('save_default') == 'jpg')
|
||||
save_default = this.SAVE_TYPES[1]; //jpg
|
||||
|
||||
POP.add({name: "name", title: "File name:", value: this.SAVE_NAME});
|
||||
POP.add({name: "type", title: "Save as type:", values: this.SAVE_TYPES, value: save_default});
|
||||
POP.add({name: "quality", title: "Quality (1-100):", value: 90, range: [1, 100]});
|
||||
POP.add({name: "layers", title: "Save layers:", values: ['All', 'Selected']});
|
||||
POP.add({name: "trim", title: "Trim:", values: ['No', 'Yes']});
|
||||
POP.show('Save as ...', [FILE, 'save']);
|
||||
document.getElementById("pop_data_name").select();
|
||||
if (e != undefined)
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
this.save = function (user_response) {
|
||||
fname = user_response.name;
|
||||
var tempCanvas = document.createElement("canvas");
|
||||
var tempCtx = tempCanvas.getContext("2d");
|
||||
tempCanvas.width = WIDTH;
|
||||
tempCanvas.height = HEIGHT;
|
||||
|
||||
//save choosen type
|
||||
var save_default = this.SAVE_TYPES[0]; //png
|
||||
if (HELPER.getCookie('save_default') == 'jpg')
|
||||
save_default = this.SAVE_TYPES[1]; //jpg
|
||||
if (user_response.type != save_default && user_response.type == this.SAVE_TYPES[0])
|
||||
HELPER.setCookie('save_default', 'png', 30);
|
||||
else if (user_response.type != save_default && user_response.type == this.SAVE_TYPES[1])
|
||||
HELPER.setCookie('save_default', 'jpg', 30);
|
||||
|
||||
if (GUI.TRANSPARENCY == false) {
|
||||
tempCtx.beginPath();
|
||||
tempCtx.rect(0, 0, WIDTH, HEIGHT);
|
||||
tempCtx.fillStyle = "#ffffff";
|
||||
tempCtx.fill();
|
||||
}
|
||||
|
||||
//take data
|
||||
for (var i in LAYER.layers) {
|
||||
if (LAYER.layers[i].visible == false)
|
||||
continue;
|
||||
if (user_response.layers == 'Selected' && user_response.type != 'XML' && i != LAYER.layer_active)
|
||||
continue;
|
||||
tempCtx.drawImage(document.getElementById(LAYER.layers[i].name), 0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
if (user_response.trim == 'Yes' && user_response.type != 'XML') {
|
||||
//trim
|
||||
var trim_info = IMAGE.trim_info(tempCanvas);
|
||||
tmp_data = tempCtx.getImageData(0, 0, WIDTH, HEIGHT);
|
||||
tempCtx.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
tempCanvas.width = WIDTH - trim_info.right - trim_info.left;
|
||||
tempCanvas.height = HEIGHT - trim_info.bottom - trim_info.top;
|
||||
tempCtx.putImageData(tmp_data, -trim_info.left, -trim_info.top);
|
||||
}
|
||||
|
||||
//detect type
|
||||
var parts = user_response.type.split(" ");
|
||||
user_response.type = parts[0];
|
||||
|
||||
//auto detect?
|
||||
if (HELPER.strpos(fname, '.png') !== false)
|
||||
user_response.type = 'PNG';
|
||||
else if (HELPER.strpos(fname, '.jpg') !== false)
|
||||
user_response.type = 'JPG';
|
||||
else if (HELPER.strpos(fname, '.xml') !== false)
|
||||
user_response.type = 'XML';
|
||||
else if (HELPER.strpos(fname, '.bmp') !== false)
|
||||
user_response.type = 'BMP';
|
||||
else if (HELPER.strpos(fname, '.webp') !== false)
|
||||
user_response.type = 'WEBP';
|
||||
|
||||
//prepare data
|
||||
if (user_response.type == 'PNG') {
|
||||
//png - default format
|
||||
var data = tempCanvas.toDataURL("image/png");
|
||||
var data_header = "image/png";
|
||||
if (HELPER.strpos(fname, '.png') == false)
|
||||
fname = fname + ".png";
|
||||
}
|
||||
else if (user_response.type == 'JPG') {
|
||||
//jpg
|
||||
var quality = parseInt(user_response.quality);
|
||||
if (quality > 100 || quality < 1 || isNaN(quality) == true)
|
||||
quality = 90;
|
||||
quality = quality / 100;
|
||||
var data = tempCanvas.toDataURL('image/jpeg', quality);
|
||||
var data_header = "image/jpeg";
|
||||
if (HELPER.strpos(fname, '.jpg') == false)
|
||||
fname = fname + ".jpg";
|
||||
}
|
||||
else if (user_response.type == 'BMP') {
|
||||
//bmp - lets hope user really needs this - chrome do not support it
|
||||
var data = tempCanvas.toDataURL("image/bmp");
|
||||
var data_header = "image/bmp";
|
||||
if (HELPER.strpos(fname, '.bmp') == false)
|
||||
fname = fname + ".bmp";
|
||||
}
|
||||
else if (user_response.type == 'WEBP') {
|
||||
//WEBP - new format for chrome only
|
||||
if (HELPER.strpos(fname, '.webp') == false)
|
||||
fname = fname + ".webp";
|
||||
var data_header = "image/webp";
|
||||
var data = tempCanvas.toDataURL("image/webp");
|
||||
}
|
||||
else if (user_response.type == 'XML') {
|
||||
//xml - full data with layers
|
||||
if (HELPER.strpos(fname, '.xml') == false)
|
||||
fname = fname + ".xml";
|
||||
var data_header = "text/plain";
|
||||
|
||||
var XML = '';
|
||||
//basic info
|
||||
XML += "<xml>\n";
|
||||
XML += " <info>\n";
|
||||
XML += " <width>" + WIDTH + "</width>\n";
|
||||
XML += " <height>" + HEIGHT + "</height>\n";
|
||||
XML += " </info>\n";
|
||||
//add layers info
|
||||
XML += " <layers>\n";
|
||||
for (var i in LAYER.layers) {
|
||||
XML += " <layer>\n";
|
||||
XML += " <name>" + LAYER.layers[i].name + "</name>\n";
|
||||
if (LAYER.layers[i].visible == true)
|
||||
XML += " <visible>1</visible>\n";
|
||||
else
|
||||
XML += " <visible>0</visible>\n";
|
||||
XML += " <opacity>" + LAYER.layers[i].opacity + "</opacity>\n";
|
||||
XML += " </layer>\n";
|
||||
}
|
||||
XML += " </layers>\n";
|
||||
//add data ???
|
||||
XML += " <image_data>\n";
|
||||
for (var i in LAYER.layers) {
|
||||
var data_tmp = document.getElementById(LAYER.layers[i].name).toDataURL("image/png");
|
||||
XML += " <data>\n";
|
||||
XML += " <name>" + LAYER.layers[i].name + "</name>\n";
|
||||
XML += " <data>" + data_tmp + "</data>\n";
|
||||
XML += " </data>\n";
|
||||
}
|
||||
XML += " </image_data>\n";
|
||||
XML += "</xml>\n";
|
||||
|
||||
var bb = new Blob([XML], {type: data_header});
|
||||
var data = window.URL.createObjectURL(bb);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
//check support
|
||||
var actualType = data.replace(/^data:([^;]*).*/, '$1');
|
||||
if (data_header != actualType && data_header != "text/plain") {
|
||||
//error - no support
|
||||
POP.add({title: "Error:", value: "Your browser do not support " + user_response.type});
|
||||
POP.show('Sorry', '');
|
||||
return false;
|
||||
}
|
||||
|
||||
//push data to user
|
||||
window.URL = window.webkitURL || window.URL;
|
||||
var a = document.createElement('a');
|
||||
if (typeof a.download != "undefined") {
|
||||
//a.download is supported
|
||||
a.setAttribute("id", "save_data");
|
||||
a.download = fname;
|
||||
a.href = data;
|
||||
a.textContent = 'Downloading...';
|
||||
document.getElementById("tmp").appendChild(a);
|
||||
|
||||
//release memory
|
||||
a.onclick = function (e) {
|
||||
this.save_cleanup(this);
|
||||
};
|
||||
//force click
|
||||
document.querySelector('#save_data').click();
|
||||
}
|
||||
else {
|
||||
//poor browser or poor user - not sure here. No support
|
||||
if (user_response.type == 'PNG')
|
||||
window.open(data);
|
||||
else if (user_response.type == 'JPG')
|
||||
window.open(data, quality);
|
||||
}
|
||||
};
|
||||
|
||||
this.save_cleanup = function (a) {
|
||||
a.textContent = 'Downloaded';
|
||||
setTimeout(function () {
|
||||
a.href = '';
|
||||
var element = document.getElementById("save_data");
|
||||
element.parentNode.removeChild(element);
|
||||
}, 1500);
|
||||
};
|
||||
|
||||
this.save_EXIF = function () {
|
||||
this.EXIF = this.exifdata;
|
||||
//check length
|
||||
var n = 0;
|
||||
for (var i in this.EXIF){
|
||||
n++;
|
||||
}
|
||||
if (n == 0)
|
||||
this.EXIF = false;
|
||||
};
|
||||
|
||||
this.load_xml = function (data) {
|
||||
var xml = $.parseXML(data);
|
||||
w = $(xml).find("width").text();
|
||||
h = $(xml).find("height").text();
|
||||
|
||||
//delete old layers
|
||||
for (var i in LAYER.layers)
|
||||
LAYER.layer_remove(i);
|
||||
|
||||
//init new file
|
||||
GUI.ZOOM = 100;
|
||||
MAIN.init();
|
||||
|
||||
//set attributes
|
||||
WIDTH = w;
|
||||
HEIGHT = h;
|
||||
LAYER.set_canvas_size();
|
||||
|
||||
//add layers
|
||||
$('layer', xml).each(function (i) {
|
||||
var name = $(this).find("name").text();
|
||||
var visible = $(this).find("visible").text();
|
||||
var opacity = $(this).find("opacity").text();
|
||||
|
||||
if (i > 0) { //first layer exists by default - Background
|
||||
LAYER.layer_add(name);
|
||||
//update attributes
|
||||
LAYER.layers[LAYER.layer_active].name = name;
|
||||
if (visible == 0)
|
||||
LAYER.layer_visibility(LAYER.layer_active);
|
||||
LAYER.layers[LAYER.layer_active].opacity = opacity;
|
||||
}
|
||||
});
|
||||
LAYER.layer_renew();
|
||||
|
||||
//add data
|
||||
$('data', xml).each(function (i) {
|
||||
var name = $(this).find("name").text();
|
||||
var data = $(this).find("data").text();
|
||||
|
||||
var img = new Image();
|
||||
img.src = data;
|
||||
img.onload = function () {
|
||||
document.getElementById(name).getContext('2d').drawImage(img, 0, 0);
|
||||
|
||||
LAYER.layer_renew();
|
||||
GUI.zoom();
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
607
js/gui.js
Normal file
607
js/gui.js
Normal file
@ -0,0 +1,607 @@
|
||||
/* global EVENTS, HELPER, POP, DRAW, LAYER, EL */
|
||||
/* global WIDTH, HEIGHT, canvas_front, DRAW_TOOLS_CONFIG, canvas_grid, canvas_preview */
|
||||
|
||||
var GUI = new GUI_CLASS();
|
||||
|
||||
/**
|
||||
* manages grapchic interface functionality: left/right sidebar actions
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function GUI_CLASS() {
|
||||
|
||||
/**
|
||||
* preview mini window size on right sidebar
|
||||
*/
|
||||
this.PREVIEW_SIZE = {w: 148, h: 100};
|
||||
|
||||
/**
|
||||
* last used menu id
|
||||
*/
|
||||
this.last_menu = '';
|
||||
|
||||
/**
|
||||
* grid dimnesions config
|
||||
*/
|
||||
this.grid_size = [50, 50];
|
||||
|
||||
/**
|
||||
* if grid is visible
|
||||
*/
|
||||
this.grid = false;
|
||||
|
||||
/**
|
||||
* true if using transparecy, false if using white background
|
||||
*/
|
||||
this.TRANSPARENCY = true;
|
||||
|
||||
/**
|
||||
* zoom level, original - 100%, can vary from 10% to 1000%
|
||||
*/
|
||||
this.ZOOM = 100;
|
||||
|
||||
/**
|
||||
* last color copy
|
||||
*/
|
||||
var COLOR_copy;
|
||||
|
||||
this.draw_helpers = function () {
|
||||
//left menu
|
||||
var html = '';
|
||||
for (var i in DRAW_TOOLS_CONFIG) {
|
||||
html += '<a title="' + DRAW_TOOLS_CONFIG[i].title + '"';
|
||||
html += ' style="background: #989898 url(\'img/' + DRAW_TOOLS_CONFIG[i].icon[0] + '\') no-repeat ' + DRAW_TOOLS_CONFIG[i].icon[1] + 'px ' + DRAW_TOOLS_CONFIG[i].icon[2] + 'px;"';
|
||||
if (DRAW_TOOLS_CONFIG[i].name == DRAW.active_tool)
|
||||
html += ' class="active"';
|
||||
html += ' onclick="return GUI.action(\'' + DRAW_TOOLS_CONFIG[i].name + '\');"';
|
||||
html += ' id="' + DRAW_TOOLS_CONFIG[i].name + '"';
|
||||
html += ' href="#"></a>' + "\n";
|
||||
}
|
||||
document.getElementById("menu_left_container").innerHTML = html;
|
||||
|
||||
//draw colors
|
||||
var html = '';
|
||||
var colors_data = [
|
||||
['#ff0000', '#ff5b31', '#ffa500', '#ff007f', '#ff00ff'], //red
|
||||
['#00ff00', '#008000', '#7fff00', '#00ff7f', '#8ac273'], //green
|
||||
['#0000ff', '#007fff', '#37629c', '#000080', '#8000ff'], //blue
|
||||
['#ffff00', '#ffff80', '#ddd06a', '#808000', '#bcb88a'], //yellow
|
||||
['#ffffff', '#c0c0c0', '#808080', '#404040', '#000000'] //grey
|
||||
];
|
||||
for (var i in colors_data) {
|
||||
for (var j in colors_data[i]) {
|
||||
html += '<div style="background-color:' + colors_data[i][j] + ';" class="mini-color" onclick="GUI.set_color(this);"></div>' + "\n";
|
||||
}
|
||||
html += '<div style="clear:both;"></div>' + "\n";
|
||||
}
|
||||
document.getElementById("all_colors").innerHTML = html;
|
||||
};
|
||||
|
||||
this.draw_background = function (canvas, W, H, gap, force) {
|
||||
if (this.TRANSPARENCY == false && force == undefined) {
|
||||
canvas.beginPath();
|
||||
canvas.rect(0, 0, W, H);
|
||||
canvas.fillStyle = "#ffffff";
|
||||
canvas.fill();
|
||||
return false;
|
||||
}
|
||||
if (gap == undefined)
|
||||
gap = 10;
|
||||
var fill = true;
|
||||
for (var i = 0; i < W; i = i + gap) {
|
||||
if (i % (gap * 2) == 0)
|
||||
fill = true;
|
||||
else
|
||||
fill = false;
|
||||
for (var j = 0; j < H; j = j + gap) {
|
||||
if (fill == true) {
|
||||
canvas.fillStyle = '#eeeeee';
|
||||
canvas.fillRect(i, j, gap, gap);
|
||||
fill = false;
|
||||
}
|
||||
else
|
||||
fill = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.draw_grid = function (gap_x, gap_y) {
|
||||
if (this.grid == false) {
|
||||
document.getElementById("canvas_grid").style.display = 'none';
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
document.getElementById("canvas_grid").style.display = '';
|
||||
canvas_grid.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
//size
|
||||
if (gap_x != undefined && gap_y != undefined)
|
||||
this.grid_size = [gap_x, gap_y];
|
||||
else {
|
||||
gap_x = this.grid_size[0];
|
||||
gap_y = this.grid_size[1];
|
||||
}
|
||||
gap_x = parseInt(gap_x);
|
||||
gap_y = parseInt(gap_y);
|
||||
if (gap_x < 2)
|
||||
gap_x = 2;
|
||||
if (gap_y < 2)
|
||||
gap_y = 2;
|
||||
for (var i = gap_x; i < WIDTH; i = i + gap_x) {
|
||||
if (gap_x == 0)
|
||||
break;
|
||||
if (i % (gap_x * 5) == 0) //main lines
|
||||
canvas_grid.strokeStyle = '#222222';
|
||||
else {
|
||||
EL.line_dashed(canvas_grid, i, 0, i, HEIGHT, 3, '#888888');
|
||||
continue;
|
||||
}
|
||||
canvas_grid.beginPath();
|
||||
canvas_grid.moveTo(0.5 + i, 0);
|
||||
canvas_grid.lineTo(0.5 + i, HEIGHT);
|
||||
canvas_grid.stroke();
|
||||
}
|
||||
for (var i = gap_y; i < HEIGHT; i = i + gap_y) {
|
||||
if (gap_y == 0)
|
||||
break;
|
||||
if (i % (gap_y * 5) == 0) //main lines
|
||||
canvas_grid.strokeStyle = '#222222';
|
||||
else {
|
||||
EL.line_dashed(canvas_grid, 0, i, WIDTH, i, 3, '#888888');
|
||||
continue;
|
||||
}
|
||||
canvas_grid.beginPath();
|
||||
canvas_grid.moveTo(0, 0.5 + i);
|
||||
canvas_grid.lineTo(WIDTH, 0.5 + i);
|
||||
canvas_grid.stroke();
|
||||
}
|
||||
};
|
||||
this.redraw_preview = function () {
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.rect(0, 0, GUI.PREVIEW_SIZE.w, GUI.PREVIEW_SIZE.h);
|
||||
canvas_preview.fillStyle = "#ffffff";
|
||||
canvas_preview.fill();
|
||||
this.draw_background(canvas_preview, GUI.PREVIEW_SIZE.w, GUI.PREVIEW_SIZE.h, 5);
|
||||
|
||||
//redraw preview area
|
||||
canvas_preview.save();
|
||||
canvas_preview.scale(GUI.PREVIEW_SIZE.w / WIDTH, GUI.PREVIEW_SIZE.h / HEIGHT);
|
||||
for (var i in LAYER.layers) {
|
||||
if (LAYER.layers[i].visible == false)
|
||||
continue;
|
||||
canvas_preview.drawImage(document.getElementById(LAYER.layers[i].name), 0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
canvas_preview.restore();
|
||||
|
||||
//active zone
|
||||
z_x = EVENTS.ZOOM_POS[0];
|
||||
z_y = EVENTS.ZOOM_POS[1];
|
||||
|
||||
if (z_x > GUI.PREVIEW_SIZE.w - EVENTS.mini_rect_data.w - 1)
|
||||
z_x = GUI.PREVIEW_SIZE.w - EVENTS.mini_rect_data.w - 1;
|
||||
if (z_y > GUI.PREVIEW_SIZE.h - EVENTS.mini_rect_data.h - 1)
|
||||
z_y = GUI.PREVIEW_SIZE.h - EVENTS.mini_rect_data.h - 1;
|
||||
|
||||
canvas_preview.lineWidth = 1;
|
||||
canvas_preview.beginPath();
|
||||
canvas_preview.rect(Math.round(z_x) + 0.5, Math.round(z_y) + 0.5, EVENTS.mini_rect_data.w, EVENTS.mini_rect_data.h);
|
||||
canvas_preview.fillStyle = "rgba(0, 0, 0, 0.2)";
|
||||
canvas_preview.strokeStyle = "#393939";
|
||||
canvas_preview.fill();
|
||||
canvas_preview.stroke();
|
||||
return true;
|
||||
};
|
||||
this.zoom = function (recalc, scroll) {
|
||||
if (recalc != undefined) {
|
||||
//zoom-in or zoom-out
|
||||
if (recalc == 1 || recalc == -1) {
|
||||
var step = 100;
|
||||
if (this.ZOOM <= 100 && recalc < 0)
|
||||
step = 10;
|
||||
if (this.ZOOM < 100 && recalc > 0)
|
||||
step = 10;
|
||||
if (recalc * step + this.ZOOM > 0) {
|
||||
this.ZOOM = this.ZOOM + recalc * step;
|
||||
if (this.ZOOM > 100 && this.ZOOM < 200)
|
||||
this.ZOOM = 100;
|
||||
}
|
||||
}
|
||||
//zoom using exact value
|
||||
else
|
||||
this.ZOOM = parseInt(recalc);
|
||||
EVENTS.calc_preview_auto();
|
||||
}
|
||||
document.getElementById("zoom_nr").innerHTML = this.ZOOM;
|
||||
document.getElementById("zoom_range").value = this.ZOOM;
|
||||
|
||||
//change scale and repaint
|
||||
document.getElementById('canvas_back').style.width = Math.round(WIDTH * this.ZOOM / 100) + "px";
|
||||
document.getElementById('canvas_back').style.height = Math.round(HEIGHT * this.ZOOM / 100) + "px";
|
||||
for (var i in LAYER.layers) {
|
||||
document.getElementById(LAYER.layers[i].name).style.width = Math.round(WIDTH * this.ZOOM / 100) + "px";
|
||||
document.getElementById(LAYER.layers[i].name).style.height = Math.round(HEIGHT * this.ZOOM / 100) + "px";
|
||||
}
|
||||
document.getElementById('canvas_front').style.width = Math.round(WIDTH * this.ZOOM / 100) + "px";
|
||||
document.getElementById('canvas_front').style.height = Math.round(HEIGHT * this.ZOOM / 100) + "px";
|
||||
|
||||
document.getElementById('canvas_grid').style.width = Math.round(WIDTH * this.ZOOM / 100) + "px";
|
||||
document.getElementById('canvas_grid').style.height = Math.round(HEIGHT * this.ZOOM / 100) + "px";
|
||||
|
||||
//check main resize corners
|
||||
if (this.ZOOM != 100) {
|
||||
document.getElementById('resize-w').style.display = "none";
|
||||
document.getElementById('resize-h').style.display = "none";
|
||||
document.getElementById('resize-wh').style.display = "none";
|
||||
}
|
||||
else {
|
||||
document.getElementById('resize-w').style.display = "block";
|
||||
document.getElementById('resize-h').style.display = "block";
|
||||
document.getElementById('resize-wh').style.display = "block";
|
||||
}
|
||||
|
||||
if (scroll != undefined)
|
||||
EVENTS.scroll_window();
|
||||
this.redraw_preview();
|
||||
return true;
|
||||
};
|
||||
|
||||
this.update_attribute = function (object, next_value) {
|
||||
var max_value = 500;
|
||||
for (var k in this.action_data().attributes) {
|
||||
if (k != object.id)
|
||||
continue;
|
||||
if (this.action_data().attributes[k] === true || this.action_data().attributes[k] === false) {
|
||||
//true / false
|
||||
var value;
|
||||
if (next_value == 0)
|
||||
value = true;
|
||||
else
|
||||
value = false;
|
||||
//save
|
||||
this.action_data().attributes[k] = value;
|
||||
this.show_action_attributes();
|
||||
}
|
||||
else if (typeof this.action_data().attributes[k] == 'object') {
|
||||
//select
|
||||
var key = k.replace("_values", "");
|
||||
this.action_data().attributes[key] = object.value;
|
||||
}
|
||||
else if (this.action_data().attributes[k][0] == '#') {
|
||||
//color
|
||||
var key = k.replace("_values", "");
|
||||
this.action_data().attributes[key] = object.value;
|
||||
}
|
||||
else {
|
||||
//numbers
|
||||
if (next_value != undefined) {
|
||||
if (next_value > 0) {
|
||||
if (parseInt(this.action_data().attributes[k]) == 0)
|
||||
object.value = 1;
|
||||
else if (parseInt(this.action_data().attributes[k]) == 1)
|
||||
object.value = 5;
|
||||
else if (parseInt(this.action_data().attributes[k]) == 5)
|
||||
object.value = 10;
|
||||
else
|
||||
object.value = parseInt(this.action_data().attributes[k]) + next_value;
|
||||
}
|
||||
else if (next_value < 0) {
|
||||
if (parseInt(this.action_data().attributes[k]) == 1)
|
||||
object.value = 0;
|
||||
else if (parseInt(this.action_data().attributes[k]) <= 5)
|
||||
object.value = 1;
|
||||
else if (parseInt(this.action_data().attributes[k]) <= 10)
|
||||
object.value = 5;
|
||||
else if (parseInt(this.action_data().attributes[k]) <= 20)
|
||||
object.value = 10;
|
||||
else
|
||||
object.value = parseInt(this.action_data().attributes[k]) + next_value;
|
||||
}
|
||||
|
||||
if (object.value < 0)
|
||||
object.value = 0;
|
||||
if (object.value > max_value)
|
||||
object.value = max_value;
|
||||
}
|
||||
else {
|
||||
if (object.value.length == 0)
|
||||
return false;
|
||||
object.value = parseInt(object.value);
|
||||
object.value = Math.abs(object.value);
|
||||
if (object.value == 0 || isNaN(object.value) || value > max_value)
|
||||
object.value = this.action_data().attributes[k];
|
||||
}
|
||||
if (k == 'power' && object.value > 100)
|
||||
object.value = 100;
|
||||
|
||||
//save
|
||||
this.action_data().attributes[k] = object.value;
|
||||
|
||||
document.getElementById(k).value = object.value;
|
||||
}
|
||||
if (this.action_data().on_update != undefined)
|
||||
DRAW[this.action_data().on_update](object.value);
|
||||
}
|
||||
};
|
||||
|
||||
this.action = function (key) {
|
||||
DRAW[key]('init', {valid: true});
|
||||
if (DRAW.active_tool == key)
|
||||
return false;
|
||||
|
||||
//change
|
||||
if (DRAW.active_tool != '')
|
||||
document.getElementById(DRAW.active_tool).className = "";
|
||||
DRAW.active_tool = key;
|
||||
document.getElementById(key).className = "active";
|
||||
this.show_action_attributes();
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
this.action_data = function () {
|
||||
for (var i in DRAW_TOOLS_CONFIG) {
|
||||
if (DRAW_TOOLS_CONFIG[i].name == DRAW.active_tool)
|
||||
return DRAW_TOOLS_CONFIG[i];
|
||||
}
|
||||
};
|
||||
|
||||
this.show_action_attributes = function () {
|
||||
html = '';
|
||||
var step = 10;
|
||||
for (var k in this.action_data().attributes) {
|
||||
var title = k[0].toUpperCase() + k.slice(1);
|
||||
title = title.replace("_", " ");
|
||||
if (this.action_data().attributes[k + "_values"] != undefined)
|
||||
continue;
|
||||
if (this.action_data().attributes[k] === true || this.action_data().attributes[k] === false) {
|
||||
//true / false
|
||||
if (this.action_data().attributes[k] == true)
|
||||
html += '<div onclick="GUI.update_attribute(this, 1)" style="background-color:#5680c1;" class="attribute-area" id="' + k + '">' + title + '</div>';
|
||||
else
|
||||
html += '<div onclick="GUI.update_attribute(this, 0)" class="attribute-area" id="' + k + '">' + title + '</div>';
|
||||
}
|
||||
else if (typeof GUI.action_data().attributes[k] == 'object') {
|
||||
//drop down select
|
||||
html += '<select style="font-size:11px;margin-bottom:10px;" onchange="GUI.update_attribute(this);" id="' + k + '">';
|
||||
for (var j in GUI.action_data().attributes[k]) {
|
||||
var sel = '';
|
||||
var key = k.replace("_values", "");
|
||||
if (GUI.action_data().attributes[key] == GUI.action_data().attributes[k][j])
|
||||
sel = 'selected="selected"';
|
||||
html += '<option ' + sel + ' name="' + GUI.action_data().attributes[k][j] + '">' + GUI.action_data().attributes[k][j] + '</option>';
|
||||
}
|
||||
html += '</select>';
|
||||
}
|
||||
else if (GUI.action_data().attributes[k][0] == '#') {
|
||||
//color
|
||||
html += '<table style="width:100%;">'; //table for 100% width
|
||||
html += '<tr>';
|
||||
html += '<td style="font-weight:bold;width:45px;">' + title + ':</td>';
|
||||
html += '<td><input onchange="GUI.update_attribute(this);" type="color" id="' + k + '" value="' + GUI.action_data().attributes[k] + '" /></td>';
|
||||
html += '</tr>';
|
||||
html += '</table>';
|
||||
}
|
||||
else {
|
||||
//numbers
|
||||
html += '<div id="' + k + '_container">';
|
||||
html += '<table style="width:100%;">'; //table for 100% width
|
||||
html += '<tr>';
|
||||
html += '<td style="font-weight:bold;padding-right:2px;white-space:nowrap;">' + title + ':</td>';
|
||||
html += '<td><input onKeyUp="GUI.update_attribute(this);" type="text" id="' + k + '" value="' + GUI.action_data().attributes[k] + '" /></td>';
|
||||
html += '</tr>';
|
||||
html += '</table>';
|
||||
html += '<div style="float:left;width:32px;" onclick="GUI.update_attribute(this, ' + (step) + ')" class="attribute-area" id="' + k + '">+</div>';
|
||||
html += '<div style="margin-left:48px;margin-bottom:15px;" onclick="GUI.update_attribute(this, ' + (-step) + ')" class="attribute-area" id="' + k + '">-</div>';
|
||||
html += '</div>';
|
||||
}
|
||||
}
|
||||
document.getElementById("action_attributes").innerHTML = html;
|
||||
};
|
||||
|
||||
this.set_color = function (object) {
|
||||
if (HELPER.chech_input_color_support('main_colour') == true && object.id == 'main_colour')
|
||||
COLOR = object.value;
|
||||
else
|
||||
COLOR = HELPER.rgb2hex_all(object.style.backgroundColor);
|
||||
COLOR_copy = COLOR;
|
||||
|
||||
if (HELPER.chech_input_color_support('main_colour') == true)
|
||||
document.getElementById("main_colour").value = COLOR; //supported
|
||||
else
|
||||
document.getElementById("main_colour_alt").style.backgroundColor = COLOR; //not supported
|
||||
|
||||
document.getElementById("color_hex").value = COLOR;
|
||||
var colours = HELPER.hex2rgb(COLOR);
|
||||
document.getElementById("rgb_r").value = colours.r;
|
||||
document.getElementById("rgb_g").value = colours.g;
|
||||
document.getElementById("rgb_b").value = colours.b;
|
||||
};
|
||||
|
||||
this.set_color_manual = function (event) {
|
||||
var object = event.target;
|
||||
if (object.value.length == 6 && object.value[0] != '#') {
|
||||
COLOR = '#' + object.value;
|
||||
this.sync_colors();
|
||||
}
|
||||
if (object.value.length == 7) {
|
||||
COLOR = object.value;
|
||||
this.sync_colors();
|
||||
}
|
||||
else if (object.value.length > 7)
|
||||
object.value = COLOR;
|
||||
};
|
||||
|
||||
this.set_color_rgb = function (object, c) {
|
||||
var colours = HELPER.hex2rgb(COLOR);
|
||||
if (object.value.length > 3) {
|
||||
object.value = colours[c];
|
||||
}
|
||||
else if (object.value.length > 0) {
|
||||
value = object.value;
|
||||
value = parseInt(value);
|
||||
if (isNaN(value) || value != object.value || value > 255 || value < 0) {
|
||||
object.value = colours[c];
|
||||
return false;
|
||||
}
|
||||
COLOR = "#" + ("000000" + HELPER.rgbToHex(document.getElementById("rgb_r").value, document.getElementById("rgb_g").value, document.getElementById("rgb_b").value)).slice(-6);
|
||||
ALPHA = document.getElementById("rgb_a").value;
|
||||
document.getElementById("rgb_a").value = ALPHA;
|
||||
this.sync_colors();
|
||||
}
|
||||
};
|
||||
|
||||
this.sync_colors = function () {
|
||||
document.getElementById("color_hex").value = COLOR;
|
||||
|
||||
if (HELPER.chech_input_color_support('main_colour') == true)
|
||||
document.getElementById("main_colour").value = COLOR; //supported
|
||||
else
|
||||
document.getElementById("main_colour_alt").style.backgroundColor = COLOR; //not supported
|
||||
|
||||
var colours = HELPER.hex2rgb(COLOR);
|
||||
document.getElementById("rgb_r").value = colours.r;
|
||||
document.getElementById("rgb_g").value = colours.g;
|
||||
document.getElementById("rgb_b").value = colours.b;
|
||||
};
|
||||
|
||||
this.toggle_color_select = function () {
|
||||
if (POP.active == false) {
|
||||
POP.add({
|
||||
title: 'Colour:',
|
||||
function: function () {
|
||||
COLOR_copy = COLOR;
|
||||
var html = '<canvas style="position:relative;margin-bottom:5px;" id="c_all" width="300" height="300"></canvas>';
|
||||
html += '<table>';
|
||||
html += '<tr>';
|
||||
html += ' <td><b>Lum:</b></td>';
|
||||
html += ' <td><input id="lum_ranger" oninput="GUI.change_lum(this.value);document.getElementById(\'lum_preview\').innerHTML=this.value;" type="range" value="0" min="-255" max="255" step="1"></td>';
|
||||
html += ' <td style="padding-left:10px;width:30px;" id="lum_preview">0</td>';
|
||||
html += '</tr>';
|
||||
html += '<tr>';
|
||||
html += ' <td><b>Alpha:</b></td>';
|
||||
html += ' <td><input oninput="GUI.change_alpha(this.value);document.getElementById(\'alpha_preview\').innerHTML=this.value;" type="range" value="' + ALPHA + '" min="0" max="255" step="1"></td>';
|
||||
html += ' <td style="padding-left:10px;" id="alpha_preview">' + ALPHA + '</td></tr>';
|
||||
html += '</tr>';
|
||||
html += '</table>';
|
||||
return html;
|
||||
}
|
||||
});
|
||||
POP.show(
|
||||
'Select color',
|
||||
function (user_response) {
|
||||
var param1 = parseInt(user_response.param1);
|
||||
},
|
||||
undefined,
|
||||
this.toggle_color_select_onload
|
||||
);
|
||||
}
|
||||
else{
|
||||
POP.hide();
|
||||
}
|
||||
};
|
||||
|
||||
this.change_lum = function (lumi) {
|
||||
lumi = parseInt(lumi);
|
||||
var c3 = HELPER.hex2rgb(COLOR_copy);
|
||||
c3.r += lumi;
|
||||
c3.g += lumi;
|
||||
c3.b += lumi;
|
||||
|
||||
if (c3.r < 0)
|
||||
c3.r = 0;
|
||||
if (c3.g < 0)
|
||||
c3.g = 0;
|
||||
if (c3.b < 0)
|
||||
c3.b = 0;
|
||||
if (c3.r > 255)
|
||||
c3.r = 255;
|
||||
if (c3.g > 255)
|
||||
c3.g = 255;
|
||||
if (c3.b > 255)
|
||||
c3.b = 255;
|
||||
|
||||
COLOR = "#" + ("000000" + HELPER.rgbToHex(c3.r, c3.g, c3.b)).slice(-6);
|
||||
this.sync_colors();
|
||||
};
|
||||
|
||||
this.change_alpha = function (value) {
|
||||
ALPHA = parseInt(value);
|
||||
document.getElementById("rgb_a").value = ALPHA;
|
||||
};
|
||||
|
||||
this.toggle_color_select_onload = function () {
|
||||
var img = new Image();
|
||||
img.onload = function () {
|
||||
document.getElementById("c_all").getContext("2d").drawImage(img, 0, 0);
|
||||
document.getElementById("c_all").onmousedown = function (event) {
|
||||
if (event.offsetX) {
|
||||
mouse_x = event.offsetX;
|
||||
mouse_y = event.offsetY;
|
||||
}
|
||||
else if (event.layerX) {
|
||||
mouse_x = event.layerX;
|
||||
mouse_y = event.layerY;
|
||||
}
|
||||
var c = document.getElementById("c_all").getContext("2d").getImageData(mouse_x, mouse_y, 1, 1).data;
|
||||
COLOR = "#" + ("000000" + HELPER.rgbToHex(c[0], c[1], c[2])).slice(-6);
|
||||
this.sync_colors();
|
||||
COLOR_copy = COLOR;
|
||||
document.getElementById("lum_ranger").value = 0;
|
||||
};
|
||||
};
|
||||
img.src = 'img/colorwheel.png';
|
||||
};
|
||||
|
||||
this.draw_selected_area = function (no_resize) {
|
||||
if (DRAW.select_data == false)
|
||||
return false;
|
||||
//draw area
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
var x = DRAW.select_data.x;
|
||||
var y = DRAW.select_data.y;
|
||||
var w = DRAW.select_data.w;
|
||||
var h = DRAW.select_data.h;
|
||||
if (this.ZOOM != 100) {
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
w = Math.round(w);
|
||||
h = Math.round(h);
|
||||
}
|
||||
|
||||
//fill
|
||||
canvas_front.fillStyle = "rgba(0, 255, 0, 0.3)";
|
||||
canvas_front.fillRect(x, y, w, h);
|
||||
if (this.ZOOM <= 100) {
|
||||
//borders
|
||||
canvas_front.strokeStyle = "rgba(0, 255, 0, 1)";
|
||||
canvas_front.lineWidth = 1;
|
||||
canvas_front.strokeRect(x + 0.5, y + 0.5, w, h);
|
||||
}
|
||||
if (no_resize == true)
|
||||
return true;
|
||||
|
||||
//draw carners
|
||||
square(x, y, 0, 0);
|
||||
square(x + w, y, -1, 0);
|
||||
square(x, y + h, 0, -1);
|
||||
square(x + w, y + h, -1, -1);
|
||||
|
||||
//draw centers
|
||||
square(x + w / 2, y, 0, 0);
|
||||
square(x, y + h / 2, 0, 0);
|
||||
square(x + w / 2, y + h, 0, -1);
|
||||
square(x + w, y + h / 2, -1, 0);
|
||||
|
||||
function square(x, y, mx, my) {
|
||||
var sr_size = Math.ceil(EVENTS.sr_size / this.ZOOM * 100);
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
canvas_front.beginPath();
|
||||
canvas_front.rect(x + mx * Math.round(sr_size), y + my * Math.round(sr_size), sr_size, sr_size);
|
||||
canvas_front.fillStyle = "#0000ff";
|
||||
canvas_front.fill();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
67
js/help.js
Normal file
67
js/help.js
Normal file
@ -0,0 +1,67 @@
|
||||
/* global POP */
|
||||
/* global VERSION */
|
||||
|
||||
var HELP = new HELP_CLASS();
|
||||
|
||||
/**
|
||||
* manages help actions
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function HELP_CLASS() {
|
||||
|
||||
/**
|
||||
* credits list config
|
||||
*/
|
||||
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: 'Image filters', name: 'ImageFilters.js',link: 'https://github.com/arahaya/ImageFilters.js' },
|
||||
{title: 'KD-tree', name: 'kdtree.js', link: 'http://jsdo.it/peko/wKvk' },
|
||||
];
|
||||
|
||||
//shortcuts
|
||||
this.help_shortcuts = function () {
|
||||
POP.add({title: "D", value: 'Dublicate'});
|
||||
POP.add({title: "Del", value: 'Delete selection'});
|
||||
POP.add({title: "F", value: 'Auto adjust colors'});
|
||||
POP.add({title: "G", value: 'Grid on/off'});
|
||||
POP.add({title: "L", value: 'Rotate left'});
|
||||
POP.add({title: "N", value: 'New layer'});
|
||||
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 + 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
|
||||
this.help_credits = function () {
|
||||
for (var i in CREDITS) {
|
||||
if (CREDITS[i].link != undefined)
|
||||
POP.add({title: CREDITS[i].title, html: '<a href="' + CREDITS[i].link + '">' + CREDITS[i].name + '</a>'});
|
||||
else
|
||||
POP.add({title: CREDITS[i].title, html: CREDITS[i].name});
|
||||
}
|
||||
POP.show('Credits', '');
|
||||
};
|
||||
//about
|
||||
this.help_about = function () {
|
||||
var email = 'www.viliusl@gmail.com';
|
||||
POP.add({title: "Name:", value: "miniPaint " + VERSION});
|
||||
POP.add({title: "Description:", value: 'online image editor'});
|
||||
POP.add({title: "Author:", value: 'ViliusL'});
|
||||
POP.add({title: "Email:", html: '<a href="mailto:' + email + '">' + email + '</a>'});
|
||||
POP.add({title: "Source:", html: '<a href="https://github.com/viliusle/miniPaint">github.com/viliusle/miniPaint</a>'});
|
||||
POP.show('About', '');
|
||||
};
|
||||
}
|
||||
513
js/helpers.js
513
js/helpers.js
@ -2,441 +2,176 @@
|
||||
|
||||
var HELPER = new HELPER_CLASS();
|
||||
|
||||
function HELPER_CLASS(){
|
||||
/**
|
||||
* various helpers
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function HELPER_CLASS() {
|
||||
var time;
|
||||
|
||||
this.drawImage_round = function(canvas, mouse_x, mouse_y, size, img_data, canvas_tmp, anti_alias){
|
||||
var size_half = Math.round(size/2);
|
||||
var ctx_tmp = canvas_tmp.getContext("2d");
|
||||
var xx = mouse_x - size_half;
|
||||
var yy = mouse_y - size_half;
|
||||
if(xx < 0) xx = 0;
|
||||
if(yy < 0) yy = 0;
|
||||
|
||||
ctx_tmp.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
ctx_tmp.save();
|
||||
//draw main data
|
||||
try{
|
||||
ctx_tmp.drawImage(img_data, mouse_x - size_half, mouse_y - size_half, size, size);
|
||||
}
|
||||
catch(err){
|
||||
try{
|
||||
ctx_tmp.putImageData(img_data, xx, yy);
|
||||
}
|
||||
catch(err){
|
||||
console.log("Error: "+err.message);
|
||||
}
|
||||
}
|
||||
ctx_tmp.globalCompositeOperation = 'destination-in';
|
||||
|
||||
//create form
|
||||
ctx_tmp.fillStyle = '#ffffff';
|
||||
if(anti_alias == true){
|
||||
var gradient = ctx_tmp.createRadialGradient(mouse_x, mouse_y, 0, mouse_x, mouse_y, size_half);
|
||||
gradient.addColorStop(0, '#ffffff');
|
||||
gradient.addColorStop(0.8, '#ffffff');
|
||||
gradient.addColorStop(1, 'rgba(25115,255,255,0');
|
||||
ctx_tmp.fillStyle = gradient;
|
||||
}
|
||||
ctx_tmp.beginPath();
|
||||
ctx_tmp.arc(mouse_x, mouse_y, size_half, 0, 2*Math.PI, true);
|
||||
ctx_tmp.fill();
|
||||
//draw final data
|
||||
if(xx + size > WIDTH)
|
||||
size = WIDTH - xx;
|
||||
if(yy + size > HEIGHT)
|
||||
size = HEIGHT - yy;
|
||||
canvas.drawImage(canvas_tmp, xx, yy, size, size, xx, yy, size, size);
|
||||
//reset
|
||||
ctx_tmp.restore();
|
||||
ctx_tmp.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
};
|
||||
this.timer_init = function(){
|
||||
|
||||
this.timer_init = function () {
|
||||
time = Date.now();
|
||||
};
|
||||
this.timer = function(s, echo){
|
||||
var str = "time("+s+") = "+(Math.round(Date.now() - time)/1000)+" s";
|
||||
if(echo === true)
|
||||
};
|
||||
|
||||
this.timer = function (s, echo) {
|
||||
var str = "time(" + s + ") = " + (Math.round(Date.now() - time) / 1000) + " s";
|
||||
if (echo === true)
|
||||
return str;
|
||||
else
|
||||
console.log(str);
|
||||
};
|
||||
//get url param
|
||||
this.get_url_param = function(name){
|
||||
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
||||
var regexS = "[\\?&]"+name+"=([^&#]*)";
|
||||
var regex = new RegExp( regexS );
|
||||
var results = regex.exec( window.location.href );
|
||||
if( results == null )
|
||||
return "";
|
||||
else
|
||||
return results[1];
|
||||
};
|
||||
this.strpos = function(haystack, needle, offset) {
|
||||
var i = (haystack+'').indexOf(needle, (offset || 0));
|
||||
};
|
||||
|
||||
this.strpos = function (haystack, needle, offset) {
|
||||
var i = (haystack + '').indexOf(needle, (offset || 0));
|
||||
return i === -1 ? false : i;
|
||||
};
|
||||
this.sleep = function(millis){
|
||||
var date = new Date();
|
||||
var curDate = null;
|
||||
do { curDate = new Date(); }
|
||||
while(curDate-date < millis);
|
||||
};
|
||||
this.js_dump = function(arr,level) {
|
||||
var dumped_text = "";
|
||||
if(!level) level = 0;
|
||||
|
||||
//The padding given at the beginning of the line.
|
||||
var level_padding = "";
|
||||
for(var j=0;j<level+1;j++) level_padding += " ";
|
||||
|
||||
if(typeof(arr) == 'object') { //Array/Hashes/Objects
|
||||
for(var item in arr) {
|
||||
var value = arr[item];
|
||||
|
||||
if(typeof(value) == 'object') { //If it is an array,
|
||||
dumped_text += level_padding + "'" + item + "' ...\n";
|
||||
dumped_text += dump(value,level+1);
|
||||
} else {
|
||||
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
|
||||
}
|
||||
};
|
||||
|
||||
this.getCookie = function (NameOfCookie) {
|
||||
if (document.cookie.length > 0){
|
||||
begin = document.cookie.indexOf(NameOfCookie + "=");
|
||||
if (begin != -1){
|
||||
begin += NameOfCookie.length + 1;
|
||||
end = document.cookie.indexOf(";", begin);
|
||||
if (end == -1)
|
||||
end = document.cookie.length;
|
||||
return unescape(document.cookie.substring(begin, end));
|
||||
}
|
||||
} else { //Stings/Chars/Numbers etc.
|
||||
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
|
||||
}
|
||||
alert(dumped_text);
|
||||
};
|
||||
this.unique = function(list){
|
||||
var o = {}, i, l = list.length, r = [];
|
||||
for(i=0; i<l;i+=1) o[list[i]] = list[i];
|
||||
for(i in o) r.push(o[i]);
|
||||
return r;
|
||||
};
|
||||
this.preload = function(image) {
|
||||
var imageObj = new Image();
|
||||
imageObj.src=image;
|
||||
};
|
||||
this.getCookie = function(NameOfCookie){
|
||||
if (document.cookie.length > 0)
|
||||
{ begin = document.cookie.indexOf(NameOfCookie+"=");
|
||||
if (begin != -1)
|
||||
{ begin += NameOfCookie.length+1;
|
||||
end = document.cookie.indexOf(";", begin);
|
||||
if (end == -1) end = document.cookie.length;
|
||||
return unescape(document.cookie.substring(begin, end)); }
|
||||
}
|
||||
return '';
|
||||
};
|
||||
this.setCookie = function(NameOfCookie, value, expiredays){
|
||||
var ExpireDate = new Date ();
|
||||
};
|
||||
|
||||
this.setCookie = function (NameOfCookie, value, expiredays) {
|
||||
var ExpireDate = new Date();
|
||||
ExpireDate.setTime(ExpireDate.getTime() + (expiredays * 24 * 3600 * 1000));
|
||||
document.cookie = NameOfCookie + "=" + escape(value) +
|
||||
((expiredays == null) ? "" : "; expires=" + ExpireDate.toGMTString());
|
||||
};
|
||||
this.delCookie = function(NameOfCookie){
|
||||
((expiredays == null) ? "" : "; expires=" + ExpireDate.toGMTString());
|
||||
};
|
||||
|
||||
this.delCookie = function (NameOfCookie) {
|
||||
if (HELPER.getCookie(NameOfCookie)) {
|
||||
document.cookie = NameOfCookie + "=" +
|
||||
"; expires=Thu, 01-Jan-70 00:00:01 GMT";
|
||||
}
|
||||
};
|
||||
/*
|
||||
ctx.strokeStyle = "#2d6";
|
||||
ctx.fillStyle = "#abc";
|
||||
HELPER.roundRect(ctx, 100, 200, 200, 100, 50, true);
|
||||
*/
|
||||
this.roundRect = function(ctx, x, y, width, height, radius, fill, stroke){
|
||||
if (typeof stroke == "undefined" ){
|
||||
stroke = true;
|
||||
}
|
||||
if (typeof radius === "undefined"){
|
||||
radius = 5;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + radius, y);
|
||||
ctx.lineTo(x + width - radius, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
||||
ctx.lineTo(x + width, y + height - radius);
|
||||
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
|
||||
ctx.lineTo(x + radius, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
||||
ctx.lineTo(x, y + radius);
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y);
|
||||
ctx.closePath();
|
||||
if (stroke){
|
||||
ctx.stroke();
|
||||
}
|
||||
if (fill){
|
||||
ctx.fill();
|
||||
}
|
||||
};
|
||||
this.getRandomInt = function(min, max) {
|
||||
"; expires=Thu, 01-Jan-70 00:00:01 GMT";
|
||||
}
|
||||
};
|
||||
|
||||
this.getRandomInt = function (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
};
|
||||
//dashed objects
|
||||
this.dashedRect = function(canvas, x1, y1, x2, y2, dashLen, color) {
|
||||
HELPER.dashedLine(canvas, x1, y1, x2, y1, dashLen, color);
|
||||
HELPER.dashedLine(canvas, x2, y1, x2, y2, dashLen, color);
|
||||
HELPER.dashedLine(canvas, x2, y2, x1, y2, dashLen, color);
|
||||
HELPER.dashedLine(canvas, x1, y2, x1, y1, dashLen, color);
|
||||
};
|
||||
this.dashedLine = function(canvas, x1, y1, x2, y2, dashLen, color) {
|
||||
x1 = x1 + 0.5;
|
||||
y1 = y1 + 0.5;
|
||||
x2 = x2 + 0.5;
|
||||
y2 = y2 + 0.5;
|
||||
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;
|
||||
var dY = y2 - y1;
|
||||
var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
|
||||
var dashX = dX / dashes;
|
||||
var dashY = dY / dashes;
|
||||
var q = 0;
|
||||
while (q++ < dashes){
|
||||
x1 += dashX;
|
||||
y1 += dashY;
|
||||
canvas[q % 2 == 0 ? 'moveTo' : 'lineTo'](x1, y1);
|
||||
}
|
||||
canvas[q % 2 == 0 ? 'moveTo' : 'lineTo'](x2, y2);
|
||||
canvas.stroke();
|
||||
canvas.closePath();
|
||||
};
|
||||
this.font_pixel_to_height = function(px){
|
||||
return Math.round(px*0.75);
|
||||
};
|
||||
this.rgbToHex = function(r, g, b) {
|
||||
};
|
||||
|
||||
this.font_pixel_to_height = function (px) {
|
||||
return Math.round(px * 0.75);
|
||||
};
|
||||
|
||||
this.rgbToHex = function (r, g, b) {
|
||||
if (r > 255 || g > 255 || b > 255)
|
||||
throw "Invalid color component";
|
||||
return ((r << 16) | (g << 8) | b).toString(16);
|
||||
};
|
||||
this.rgb2hex_all = function(rgb){
|
||||
};
|
||||
|
||||
this.rgb2hex_all = function (rgb) {
|
||||
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
||||
return "#" + HELPER.hex(rgb[1]) + HELPER.hex(rgb[2]) + HELPER.hex(rgb[3]);
|
||||
};
|
||||
this.hex = function(x){
|
||||
};
|
||||
|
||||
this.hex = function (x) {
|
||||
return ("0" + parseInt(x).toString(16)).slice(-2);
|
||||
};
|
||||
this.hex2rgb = function(hex) {
|
||||
if (hex[0]=="#") hex=hex.substr(1);
|
||||
if (hex.length==3) {
|
||||
var temp=hex; hex='';
|
||||
};
|
||||
|
||||
this.hex2rgb = function (hex) {
|
||||
if (hex[0] == "#")
|
||||
hex = hex.substr(1);
|
||||
if (hex.length == 3) {
|
||||
var temp = hex;
|
||||
hex = '';
|
||||
temp = /^([a-f0-9])([a-f0-9])([a-f0-9])$/i.exec(temp).slice(1);
|
||||
for (var i=0;i<3;i++) hex+=temp[i]+temp[i];
|
||||
}
|
||||
for (var i = 0; i < 3; i++)
|
||||
hex += temp[i] + temp[i];
|
||||
}
|
||||
var triplets = /^([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i.exec(hex).slice(1);
|
||||
return {
|
||||
r: parseInt(triplets[0],16),
|
||||
g: parseInt(triplets[1],16),
|
||||
b: parseInt(triplets[2],16),
|
||||
r: parseInt(triplets[0], 16),
|
||||
g: parseInt(triplets[1], 16),
|
||||
b: parseInt(triplets[2], 16),
|
||||
a: 255
|
||||
};
|
||||
};
|
||||
this.ColorLuminance = function(hex, lum){
|
||||
// validate hex string
|
||||
hex = String(hex).replace(/[^0-9a-f]/gi, '');
|
||||
lum = lum || 0;
|
||||
// convert to decimal and change luminosity
|
||||
var rgb = "#", c, i;
|
||||
for (i = 0; i < 3; i++){
|
||||
c = parseInt(hex.substr(i*2,2), 16);
|
||||
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
|
||||
rgb += ("00"+c).substr(c.length);
|
||||
}
|
||||
return rgb;
|
||||
};
|
||||
this.drawImage_rotated = function(canvas, file, x, y, width, height, angle){
|
||||
var TO_RADIANS = Math.PI/180;
|
||||
var img = new Image();
|
||||
img.src = file;
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(x, y);
|
||||
canvas.rotate(angle * TO_RADIANS);
|
||||
canvas.drawImage(img, -(width/2), -(height/2));
|
||||
canvas.restore();
|
||||
};
|
||||
this.drawEllipseByCenter = function(ctx, cx, cy, w, h, color, fill) {
|
||||
HELPER.drawEllipse(ctx, cx - w/2.0, cy - h/2.0, w, h, color, fill);
|
||||
};
|
||||
this.drawEllipse = function(ctx, x, y, w, h, color, fill) {
|
||||
var kappa = .5522848,
|
||||
ox = (w / 2) * kappa, // control point offset horizontal
|
||||
oy = (h / 2) * kappa, // control point offset vertical
|
||||
xe = x + w, // x-end
|
||||
ye = y + h, // y-end
|
||||
xm = x + w / 2, // x-middle
|
||||
ym = y + h / 2; // y-middle
|
||||
};
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, ym);
|
||||
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
|
||||
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
|
||||
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
|
||||
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = color;
|
||||
ctx.strokeStyle = color;
|
||||
if(fill==undefined)
|
||||
ctx.stroke();
|
||||
else
|
||||
ctx.fill();
|
||||
};
|
||||
this.remove_selection = function(){
|
||||
this.remove_selection = function () {
|
||||
if (window.getSelection) {
|
||||
if (window.getSelection().empty) // Chrome
|
||||
if (window.getSelection().empty) // Chrome
|
||||
window.getSelection().empty();
|
||||
else if (window.getSelection().removeAllRanges) // Firefox
|
||||
else if (window.getSelection().removeAllRanges) // Firefox
|
||||
window.getSelection().removeAllRanges();
|
||||
}
|
||||
else if (document.selection) // IE?
|
||||
}
|
||||
else if (document.selection) // IE?
|
||||
document.selection.empty();
|
||||
};
|
||||
this.get_dimensions = function(){
|
||||
};
|
||||
|
||||
this.get_dimensions = function () {
|
||||
var theWidth, theHeight;
|
||||
if (window.innerWidth) {
|
||||
theWidth=window.innerWidth;
|
||||
}
|
||||
theWidth = window.innerWidth;
|
||||
}
|
||||
else if (document.documentElement && document.documentElement.clientWidth) {
|
||||
theWidth=document.documentElement.clientWidth;
|
||||
}
|
||||
theWidth = document.documentElement.clientWidth;
|
||||
}
|
||||
else if (document.body) {
|
||||
theWidth=document.body.clientWidth;
|
||||
}
|
||||
theWidth = document.body.clientWidth;
|
||||
}
|
||||
if (window.innerHeight) {
|
||||
theHeight=window.innerHeight;
|
||||
}
|
||||
theHeight = window.innerHeight;
|
||||
}
|
||||
else if (document.documentElement && document.documentElement.clientHeight) {
|
||||
theHeight=document.documentElement.clientHeight;
|
||||
}
|
||||
theHeight = document.documentElement.clientHeight;
|
||||
}
|
||||
else if (document.body) {
|
||||
theHeight=document.body.clientHeight;
|
||||
}
|
||||
theHeight = document.body.clientHeight;
|
||||
}
|
||||
return [theWidth, theHeight];
|
||||
};
|
||||
this.save_as_chrome = function(fileContents, fileName){
|
||||
var link = document.createElement('a');
|
||||
link.download = fileName;
|
||||
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;
|
||||
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.number_format = function(n, decPlaces, thouSeparator, decSeparator){
|
||||
this.number_format = function (n, decPlaces, thouSeparator, decSeparator) {
|
||||
var decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
|
||||
var decSeparator = decSeparator == undefined ? "." : decSeparator;
|
||||
var thouSeparator = thouSeparator == undefined ? "," : thouSeparator;
|
||||
var sign = n < 0 ? "-" : "";
|
||||
var n = Math.abs(+n || 0).toFixed(decPlaces);
|
||||
var i = parseInt(n);
|
||||
var i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "";
|
||||
var j = (j = i.length) > 3 ? j % 3 : 0;
|
||||
return sign + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
|
||||
};
|
||||
this.length = function(object){
|
||||
var n = 0;
|
||||
for(var i in object){
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
};
|
||||
this.chech_input_color_support = function(id){
|
||||
if(document.getElementById(id).value != undefined && document.getElementById(id).value[0] == '#')
|
||||
};
|
||||
|
||||
this.chech_input_color_support = function (id) {
|
||||
if (document.getElementById(id).value != undefined && document.getElementById(id).value[0] == '#')
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
//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, size) {
|
||||
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 = size;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.strokeStyle = 'rgba(' + color_rgb.r + ', ' + color_rgb.g + ', ' + color_rgb.b + ', 0.9)';
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
|
||||
// draw extra strokes
|
||||
ctx.lineWidth = 1;
|
||||
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){
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
1052
js/image.js
Normal file
1052
js/image.js
Normal file
File diff suppressed because it is too large
Load Diff
781
js/layers.js
781
js/layers.js
@ -1,92 +1,327 @@
|
||||
/* global HELPER, POP, MAIN, LAYERS, CON, LAYER, DRAW, MENU, TOOLS */
|
||||
/* global WIDTH, HEIGHT, ZOOM, LAYERS, canvas_front, canvas_back */
|
||||
/* global HELPER, POP, MAIN, EVENTS, LAYER, IMAGE, DRAW, EDIT, GUI */
|
||||
/* global WIDTH, HEIGHT, canvas_front, canvas_back */
|
||||
|
||||
var LAYER = new LAYER_CLASS();
|
||||
|
||||
function LAYER_CLASS(){
|
||||
this.layer_active = 0;
|
||||
var imageData_tmp;
|
||||
var layer_max_index = 0;
|
||||
/**
|
||||
* layers class - manages layers
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function LAYER_CLASS() {
|
||||
|
||||
/**
|
||||
* active layer index
|
||||
*/
|
||||
this.layer_active = 0;
|
||||
|
||||
/**
|
||||
* data layers array
|
||||
*/
|
||||
this.layers = [];
|
||||
|
||||
/**
|
||||
* latest layer index
|
||||
*/
|
||||
var layer_max_index = 0;
|
||||
|
||||
//new layer
|
||||
this.layer_new = function () {
|
||||
this.add_layer();
|
||||
};
|
||||
|
||||
//dublicate
|
||||
this.layer_dublicate = function () {
|
||||
EDIT.save_state();
|
||||
if (DRAW.select_data != false) {
|
||||
//selection
|
||||
this.copy_to_clipboard();
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
var tmp = LAYER.layer_active;
|
||||
this.paste('menu');
|
||||
LAYER.layer_active = tmp;
|
||||
LAYER.layer_renew();
|
||||
}
|
||||
else {
|
||||
//copy all layer
|
||||
tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = WIDTH;
|
||||
tmp_data.height = HEIGHT;
|
||||
tmp_data.getContext("2d").drawImage(canvas_active(true), 0, 0);
|
||||
|
||||
//create
|
||||
var new_name = 'Layer #' + (this.layers.length + 1);
|
||||
LAYER.create_canvas(new_name);
|
||||
this.layers.push({name: new_name, visible: true});
|
||||
LAYER.layer_active = this.layers.length - 1;
|
||||
canvas_active().drawImage(tmp_data, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
}
|
||||
};
|
||||
|
||||
//show / hide
|
||||
this.layer_show_hide = function () {
|
||||
LAYER.layer_visibility(LAYER.layer_active);
|
||||
};
|
||||
|
||||
//crop
|
||||
this.layer_crop = function () {
|
||||
EDIT.save_state();
|
||||
if (DRAW.select_data == false) {
|
||||
POP.add({html: 'Select area first'});
|
||||
POP.show('Error', '');
|
||||
}
|
||||
else {
|
||||
var layer = LAYER.canvas_active();
|
||||
|
||||
var tmp = layer.getImageData(DRAW.select_data.x, DRAW.select_data.y, DRAW.select_data.w, DRAW.select_data.h);
|
||||
layer.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
layer.putImageData(tmp, 0, 0);
|
||||
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
//delete
|
||||
this.layer_delete = function () {
|
||||
EDIT.save_state();
|
||||
LAYER.layer_remove(LAYER.layer_active);
|
||||
};
|
||||
|
||||
//move up
|
||||
this.layer_move_up = function () {
|
||||
EDIT.save_state();
|
||||
LAYER.move_layer('up');
|
||||
};
|
||||
|
||||
//move down
|
||||
this.layer_move_down = function () {
|
||||
EDIT.save_state();
|
||||
LAYER.move_layer('down');
|
||||
};
|
||||
|
||||
//opacity
|
||||
this.layer_opacity = function () {
|
||||
LAYER.set_alpha();
|
||||
};
|
||||
|
||||
//trim
|
||||
this.layer_trim = function () {
|
||||
EDIT.save_state();
|
||||
IMAGE.trim(this.layers[LAYER.layer_active].name, true);
|
||||
};
|
||||
|
||||
//resize
|
||||
this.layer_resize = function () {
|
||||
IMAGE.resize_box();
|
||||
};
|
||||
|
||||
//clear
|
||||
this.layer_clear = function () {
|
||||
EDIT.save_state();
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
};
|
||||
|
||||
//show differences
|
||||
this.layer_differences = function () {
|
||||
if (parseInt(LAYER.layer_active) + 1 >= this.layers.length) {
|
||||
POP.add({html: '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);
|
||||
LAYER.calc_differences(param1);
|
||||
},
|
||||
function (user_response, canvas_preview, w, h) {
|
||||
var param1 = parseInt(user_response.param1);
|
||||
LAYER.calc_differences(param1, canvas_preview, w, h);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
//merge
|
||||
this.layer_merge_down = function () {
|
||||
var compositions = ["source-over", "source-in", "source-out", "source-atop",
|
||||
"destination-over", "destination-in", "destination-out", "destination-atop",
|
||||
"lighter", "darker", "copy", "xor"];
|
||||
|
||||
var blend_modes = ["normal", "multiply", "screen", "overlay", "darken", "lighten",
|
||||
"color-dodge", "color-burn", "hard-light", "soft-light", "difference",
|
||||
"exclusion", "hue", "saturation", "color", "luminosity"];
|
||||
|
||||
if (parseInt(LAYER.layer_active) + 1 >= this.layers.length) {
|
||||
POP.add({html: 'This can not be last layer.'});
|
||||
POP.show('Error', '');
|
||||
return false;
|
||||
}
|
||||
POP.add({name: "param1", title: "Composition:", values: compositions});
|
||||
POP.add({name: "param2", title: "Blend:", values: blend_modes});
|
||||
POP.add({name: "param3", title: "Mode:", values: ["Composite", "Blend"]});
|
||||
POP.show(
|
||||
'Merge',
|
||||
function (response) {
|
||||
var param1 = response.param1;
|
||||
var param2 = response.param2;
|
||||
var param3 = response.param3;
|
||||
|
||||
EDIT.save_state();
|
||||
//copy
|
||||
LAYER.layer_active++;
|
||||
var tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = WIDTH;
|
||||
tmp_data.height = HEIGHT;
|
||||
tmp_data.getContext("2d").drawImage(LAYER.canvas_active(true), 0, 0);
|
||||
|
||||
//paste
|
||||
LAYER.layer_active--;
|
||||
LAYER.canvas_active().save();
|
||||
if (param3 == "Composite")
|
||||
LAYER.canvas_active().globalCompositeOperation = param1;
|
||||
else
|
||||
LAYER.canvas_active().globalCompositeOperation = param2;
|
||||
LAYER.canvas_active().drawImage(tmp_data, 0, 0);
|
||||
LAYER.canvas_active().restore();
|
||||
|
||||
//remove next layer
|
||||
LAYER.layer_remove(LAYER.layer_active + 1);
|
||||
LAYER.layer_renew();
|
||||
},
|
||||
function (response, canvas_preview, w, h) {
|
||||
var param1 = response.param1;
|
||||
var param2 = response.param2;
|
||||
var param3 = response.param3;
|
||||
|
||||
//copy
|
||||
LAYER.layer_active++;
|
||||
var tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = w;
|
||||
tmp_data.height = h;
|
||||
tmp_data.getContext("2d").drawImage(LAYER.canvas_active(true), 0, 0, WIDTH, HEIGHT, 0, 0, w, h);
|
||||
|
||||
//paste
|
||||
LAYER.layer_active--;
|
||||
canvas_preview.save();
|
||||
if (param3 == "Composite")
|
||||
canvas_preview.globalCompositeOperation = param1;
|
||||
else
|
||||
canvas_preview.globalCompositeOperation = param2;
|
||||
canvas_preview.drawImage(tmp_data, 0, 0);
|
||||
canvas_preview.restore();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
//flatten all
|
||||
this.layer_flatten = function () {
|
||||
EDIT.save_state();
|
||||
if (this.layers.length == 1)
|
||||
return false;
|
||||
tmp_data = document.createElement("canvas");
|
||||
tmp_data.width = WIDTH;
|
||||
tmp_data.height = HEIGHT;
|
||||
for (var i = 1; i < this.layers.length; i++) {
|
||||
//copy
|
||||
LAYER.layer_active = i;
|
||||
tmp_data.getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
tmp_data.getContext("2d").drawImage(canvas_active(true), 0, 0);
|
||||
|
||||
//paste
|
||||
LAYER.layer_active = 0;
|
||||
canvas_active().drawImage(tmp_data, 0, 0);
|
||||
}
|
||||
for (var i = this.layers.length - 1; i > 0; i--) {
|
||||
//delete layer
|
||||
LAYER.layer_active = i;
|
||||
LAYER.layer_remove(LAYER.layer_active);
|
||||
}
|
||||
LAYER.layer_renew();
|
||||
};
|
||||
|
||||
//create layer
|
||||
this.layer_add = function(name, data, type){
|
||||
this.layer_add = function (name, data, type) {
|
||||
tmp = new Array();
|
||||
if(data == undefined){
|
||||
if (data == undefined) {
|
||||
//empty layer
|
||||
if(name==undefined){
|
||||
if (name == undefined) {
|
||||
layer_max_index++;
|
||||
name = 'Layer #'+(layer_max_index+1);
|
||||
}
|
||||
name = 'Layer #' + (layer_max_index + 1);
|
||||
}
|
||||
tmp.name = name;
|
||||
tmp.visible = true;
|
||||
tmp.opacity = 1;
|
||||
if(LAYERS.length==0)
|
||||
if (this.layers.length == 0)
|
||||
tmp.primary = 1;
|
||||
else
|
||||
LAYER.create_canvas(name);
|
||||
LAYERS.push(tmp);
|
||||
}
|
||||
else{
|
||||
this.layers.push(tmp);
|
||||
}
|
||||
else {
|
||||
var img = new Image();
|
||||
if(data.substring(0,4) == 'http')
|
||||
if (data.substring(0, 4) == 'http')
|
||||
img.crossOrigin = "Anonymous"; //data from other domain - turn on CORS
|
||||
img.onload = function(){
|
||||
var _this = this;
|
||||
img.onload = function () {
|
||||
//check size
|
||||
var size_increased = false;
|
||||
if(img.width > WIDTH || img.height > HEIGHT){
|
||||
if(img.width > WIDTH)
|
||||
if (img.width > WIDTH || img.height > HEIGHT) {
|
||||
if (img.width > WIDTH)
|
||||
WIDTH = img.width;
|
||||
if(img.height > HEIGHT)
|
||||
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){
|
||||
}
|
||||
if (_this.layers.length == 1 && EVENTS.autosize == true && size_increased == false) {
|
||||
var trim_info = IMAGE.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 == name){
|
||||
}
|
||||
|
||||
for (var i in _this.layers) {
|
||||
if (_this.layers[i].name == name) {
|
||||
layer_max_index++;
|
||||
name = 'Layer #'+(layer_max_index+1);
|
||||
}
|
||||
name = 'Layer #' + (layer_max_index + 1);
|
||||
}
|
||||
}
|
||||
LAYER.create_canvas(name);
|
||||
LAYERS.push({
|
||||
name: name,
|
||||
_this.layers.push({
|
||||
name: name,
|
||||
visible: true,
|
||||
opacity: 1
|
||||
});
|
||||
LAYER.layer_active = LAYERS.length-1;
|
||||
});
|
||||
LAYER.layer_active = _this.layers.length - 1;
|
||||
|
||||
document.getElementById(name).getContext("2d").globalAlpha = 1;
|
||||
document.getElementById(name).getContext('2d').drawImage(img, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
DRAW.zoom();
|
||||
};
|
||||
img.onerror = function(ex){
|
||||
GUI.zoom();
|
||||
};
|
||||
img.onerror = function (ex) {
|
||||
POP.add({html: '<b>The image could not be loaded.<br /><br /></b>'});
|
||||
if(data.substring(0,4) == 'http')
|
||||
if (data.substring(0, 4) == 'http')
|
||||
POP.add({title: "Reason:", value: 'Cross-origin resource sharing (CORS) not supported. Try to save image first.'});
|
||||
POP.show('Error', '.');
|
||||
};
|
||||
};
|
||||
img.src = data;
|
||||
}
|
||||
LAYER.layer_active = LAYERS.length-1;
|
||||
document.getElementById(LAYERS[LAYER.layer_active].name).getContext("2d").globalAlpha = 1;
|
||||
}
|
||||
LAYER.layer_active = this.layers.length - 1;
|
||||
document.getElementById(this.layers[LAYER.layer_active].name).getContext("2d").globalAlpha = 1;
|
||||
this.layer_renew();
|
||||
};
|
||||
this.create_canvas = function(canvas_id){
|
||||
};
|
||||
this.create_canvas = function (canvas_id) {
|
||||
var new_canvas = document.createElement('canvas');
|
||||
new_canvas.setAttribute('id', canvas_id);
|
||||
|
||||
|
||||
document.getElementById('canvas_more').appendChild(new_canvas);
|
||||
new_canvas.width = WIDTH;
|
||||
new_canvas.height = HEIGHT;
|
||||
@ -94,32 +329,37 @@ function LAYER_CLASS(){
|
||||
new_canvas.getContext("2d").webkitImageSmoothingEnabled = false;
|
||||
new_canvas.getContext("2d").ImageSmoothingEnabled = false;
|
||||
//sync zoom
|
||||
new_canvas.style.width = round(WIDTH * ZOOM / 100)+"px";
|
||||
new_canvas.style.height = round(HEIGHT * ZOOM / 100)+"px";
|
||||
};
|
||||
this.move_layer = function(direction){
|
||||
if(LAYERS.length < 2) return false;
|
||||
if(LAYERS[LAYER.layer_active].primary == 1) return false;
|
||||
new_canvas.style.width = Math.round(WIDTH * GUI.ZOOM / 100) + "px";
|
||||
new_canvas.style.height = Math.round(HEIGHT * GUI.ZOOM / 100) + "px";
|
||||
};
|
||||
this.move_layer = function (direction) {
|
||||
if (this.layers.length < 2)
|
||||
return false;
|
||||
if (this.layers[LAYER.layer_active].primary == 1)
|
||||
return false;
|
||||
LAYER.layer_active = parseInt(LAYER.layer_active);
|
||||
|
||||
var layer_from = LAYERS[LAYER.layer_active];
|
||||
var content = document.getElementById(LAYERS[LAYER.layer_active].name);
|
||||
|
||||
var layer_from = this.layers[LAYER.layer_active];
|
||||
var content = document.getElementById(this.layers[LAYER.layer_active].name);
|
||||
var parent = content.parentNode;
|
||||
|
||||
|
||||
if(direction == 'up'){
|
||||
if(LAYERS[LAYER.layer_active-1] == undefined) return false;
|
||||
if(LAYERS[LAYER.layer_active-1].primary == 1) return false;
|
||||
var layer_to = LAYERS[LAYER.layer_active-1];
|
||||
|
||||
|
||||
if (direction == 'up') {
|
||||
if (this.layers[LAYER.layer_active - 1] == undefined)
|
||||
return false;
|
||||
if (this.layers[LAYER.layer_active - 1].primary == 1)
|
||||
return false;
|
||||
var layer_to = this.layers[LAYER.layer_active - 1];
|
||||
parent.insertBefore(content, parent.firstChild);
|
||||
}
|
||||
else{
|
||||
if(LAYERS[LAYER.layer_active+1] == undefined) return false;
|
||||
var layer_to = LAYERS[LAYER.layer_active+1];
|
||||
var content = document.getElementById(LAYERS[LAYER.layer_active+1].name);
|
||||
}
|
||||
else {
|
||||
if (this.layers[LAYER.layer_active + 1] == undefined)
|
||||
return false;
|
||||
var layer_to = this.layers[LAYER.layer_active + 1];
|
||||
var content = document.getElementById(this.layers[LAYER.layer_active + 1].name);
|
||||
parent.insertBefore(content, parent.firstChild);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//switch name
|
||||
var tmp = layer_to.name;
|
||||
layer_to.name = layer_from.name;
|
||||
@ -132,229 +372,326 @@ function LAYER_CLASS(){
|
||||
var tmp = layer_to.opacity;
|
||||
layer_to.opacity = layer_from.opacity;
|
||||
layer_from.opacity = tmp;
|
||||
|
||||
LAYER.layer_active = LAYERS.length-1;
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS[i].name == layer_to.name){
|
||||
|
||||
LAYER.layer_active = this.layers.length - 1;
|
||||
for (var i in this.layers) {
|
||||
if (this.layers[i].name == layer_to.name) {
|
||||
LAYER.layer_active = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.layer_renew();
|
||||
DRAW.zoom();
|
||||
GUI.zoom();
|
||||
return true;
|
||||
};
|
||||
this.layer_visibility = function(i){
|
||||
if(LAYERS[i].visible == true){
|
||||
LAYERS[i].visible = false;
|
||||
document.getElementById(LAYERS[i].name).style.visibility = 'hidden';
|
||||
document.getElementById('layer_'+i).src = "img/yes-grey.png";
|
||||
}
|
||||
else{
|
||||
LAYERS[i].visible = true;
|
||||
document.getElementById(LAYERS[i].name).style.visibility = 'visible';
|
||||
document.getElementById('layer_'+i).src = "img/yes.png";
|
||||
}
|
||||
};
|
||||
this.layer_visibility = function (i) {
|
||||
if (this.layers[i].visible == true) {
|
||||
this.layers[i].visible = false;
|
||||
document.getElementById(this.layers[i].name).style.visibility = 'hidden';
|
||||
document.getElementById('layer_' + i).src = "img/yes-grey.png";
|
||||
}
|
||||
else {
|
||||
this.layers[i].visible = true;
|
||||
document.getElementById(this.layers[i].name).style.visibility = 'visible';
|
||||
document.getElementById('layer_' + i).src = "img/yes.png";
|
||||
}
|
||||
this.layer_renew();
|
||||
DRAW.redraw_preview();
|
||||
};
|
||||
this.layer_remove = function(i){
|
||||
if(LAYERS[i].primary == 1) return false;
|
||||
element = document.getElementById(LAYERS[i].name);
|
||||
GUI.redraw_preview();
|
||||
};
|
||||
this.layer_remove = function (i) {
|
||||
if (this.layers[i].primary == 1)
|
||||
return false;
|
||||
element = document.getElementById(this.layers[i].name);
|
||||
element.getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
element.parentNode.removeChild(element);
|
||||
|
||||
LAYERS.splice(i, 1);
|
||||
if(LAYER.layer_active >= LAYERS.length)
|
||||
LAYER.layer_active = LAYERS.length-1;
|
||||
|
||||
this.layers.splice(i, 1);
|
||||
if (LAYER.layer_active >= this.layers.length)
|
||||
LAYER.layer_active = this.layers.length - 1;
|
||||
this.layer_renew();
|
||||
DRAW.redraw_preview();
|
||||
};
|
||||
this.layer_move_active = function(x, y){
|
||||
GUI.redraw_preview();
|
||||
};
|
||||
this.layer_move_active = function (x, y) {
|
||||
var distance = 10;
|
||||
if(CON.ctrl_pressed == true)
|
||||
if (EVENTS.ctrl_pressed == true)
|
||||
distance = 50;
|
||||
if(CON.shift_pressed == true)
|
||||
if (EVENTS.shift_pressed == true)
|
||||
distance = 1;
|
||||
|
||||
//move
|
||||
dx = x*distance;
|
||||
dy = y*distance;
|
||||
dx = x * distance;
|
||||
dy = y * distance;
|
||||
var tmp = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().putImageData(tmp, dx, dy);
|
||||
};
|
||||
this.select_layer = function(i){
|
||||
if(LAYER.layer_active != i){
|
||||
};
|
||||
this.select_layer = function (i) {
|
||||
if (LAYER.layer_active != i) {
|
||||
LAYER.layer_active = i; //select
|
||||
this.layer_renew();
|
||||
}
|
||||
}
|
||||
LAYER.shake(i);
|
||||
};
|
||||
this.layer_renew = function(){
|
||||
};
|
||||
this.layer_renew = function () {
|
||||
var html = '';
|
||||
for(var i in LAYERS){
|
||||
for (var i in this.layers) {
|
||||
//create
|
||||
if(LAYER.layer_active==i)
|
||||
if (LAYER.layer_active == i)
|
||||
html += '<div class="layer active">';
|
||||
else
|
||||
html += '<div class="layer">';
|
||||
var title = LAYERS[i].name;
|
||||
html += '<span class="layer_title" onclick="LAYER.select_layer(\''+i+'\')">'+title+'</span>';
|
||||
if(LAYERS[i].primary != 1){
|
||||
html += '<a class="layer_visible" onclick="LAYER.layer_remove(\''+i+'\');return false;" title="delete" href="#"></a>';
|
||||
}
|
||||
var title = this.layers[i].name;
|
||||
html += '<span class="layer_title" onclick="LAYER.select_layer(\'' + i + '\')">' + title + '</span>';
|
||||
if (this.layers[i].primary != 1) {
|
||||
html += '<a class="layer_visible" onclick="LAYER.layer_remove(\'' + i + '\');return false;" title="delete" href="#"></a>';
|
||||
}
|
||||
else
|
||||
html += '<a style="visibility:hidden;" class="layer_visible" href="#"></a>';
|
||||
//hide
|
||||
if(LAYERS[i].visible == true)
|
||||
html += '<a class="layer_delete" id="layer_'+i+'" onclick="LAYER.layer_visibility(\''+i+'\');return false;" title="hide" href="#"></a>';
|
||||
if (this.layers[i].visible == true)
|
||||
html += '<a class="layer_delete" id="layer_' + i + '" onclick="LAYER.layer_visibility(\'' + i + '\');return false;" title="hide" href="#"></a>';
|
||||
else
|
||||
html += '<a class="layer_delete layer_unvisible" id="layer_'+i+'" onclick="LAYER.layer_visibility(\''+i+'\');return false;" title="show" href="#"></a>';
|
||||
|
||||
html += '<a class="layer_delete layer_unvisible" id="layer_' + i + '" onclick="LAYER.layer_visibility(\'' + i + '\');return false;" title="show" href="#"></a>';
|
||||
|
||||
html += '</div>';
|
||||
//show
|
||||
document.getElementById('layers').innerHTML = html;
|
||||
}
|
||||
};
|
||||
this.shake = function(i, nr){
|
||||
}
|
||||
};
|
||||
this.shake = function (i, nr) {
|
||||
var step = 3;
|
||||
var n = 10;
|
||||
|
||||
if(nr == undefined){
|
||||
|
||||
if (nr == undefined) {
|
||||
//begin
|
||||
nr = 0;
|
||||
canvas_front.drawImage(canvas_active(true), 0, 0);
|
||||
}
|
||||
var dx = step * (nr%2);
|
||||
if(dx == 0)
|
||||
}
|
||||
var dx = step * (nr % 2);
|
||||
if (dx == 0)
|
||||
dx = -step;
|
||||
|
||||
|
||||
var element = document.getElementById('canvas_front');
|
||||
element.style.marginLeft = dx+"px";
|
||||
if(nr < n)
|
||||
setTimeout(function(){LAYER.shake(i, nr + 1);}, 15);
|
||||
else{
|
||||
element.style.marginLeft = dx + "px";
|
||||
if (nr < n)
|
||||
setTimeout(function () {
|
||||
LAYER.shake(i, nr + 1);
|
||||
}, 15);
|
||||
else {
|
||||
//finish shaking
|
||||
element.style.marginLeft = "0px";
|
||||
element.style.marginLeft = "0px";
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
};
|
||||
this.update_info_block = function(){
|
||||
}
|
||||
};
|
||||
this.update_info_block = function () {
|
||||
var html = '';
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Size:</span> '+WIDTH+"x"+HEIGHT+"<br />";
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Size:</span> ' + WIDTH + "x" + HEIGHT + "<br />";
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
if(CON.mouse != undefined){
|
||||
x = CON.mouse.x;
|
||||
y = CON.mouse.y;
|
||||
}
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Mouse:</span> '+x+", "+y+"<br />";
|
||||
if(TOOLS.select_data != false){
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">XY:</span> '+TOOLS.select_data.x+", "+TOOLS.select_data.y+"<br />";
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Area:</span> '+TOOLS.select_data.w+", "+TOOLS.select_data.h+"<br />";
|
||||
}
|
||||
|
||||
if (EVENTS.mouse != undefined) {
|
||||
x = EVENTS.mouse.x;
|
||||
y = EVENTS.mouse.y;
|
||||
}
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Mouse:</span> ' + x + ", " + y + "<br />";
|
||||
if (DRAW.select_data != false) {
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">XY:</span> ' + DRAW.select_data.x + ", " + DRAW.select_data.y + "<br />";
|
||||
html += '<span style="font-weight:bold;min-width:45px;display:block;float:left;">Area:</span> ' + DRAW.select_data.w + ", " + DRAW.select_data.h + "<br />";
|
||||
}
|
||||
|
||||
document.getElementById('info').innerHTML = html;
|
||||
};
|
||||
this.set_canvas_size = function(repaint){
|
||||
var W = round(WIDTH);
|
||||
var H = round(W / RATIO);
|
||||
|
||||
};
|
||||
this.set_canvas_size = function (repaint) {
|
||||
var ratio = WIDTH/HEIGHT;
|
||||
var W = Math.round(WIDTH);
|
||||
var H = Math.round(W / ratio);
|
||||
|
||||
this.resize_canvas("canvas_back");
|
||||
DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
GUI.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
this.resize_canvas("canvas_front", false);
|
||||
this.resize_canvas("canvas_grid", true);
|
||||
for(var i in LAYERS){
|
||||
if(repaint === false)
|
||||
this.resize_canvas(LAYERS[i].name, false);
|
||||
for (var i in this.layers) {
|
||||
if (repaint === false)
|
||||
this.resize_canvas(this.layers[i].name, false);
|
||||
else
|
||||
this.resize_canvas(LAYERS[i].name, true);
|
||||
}
|
||||
|
||||
DRAW.draw_grid();
|
||||
|
||||
this.resize_canvas(this.layers[i].name, true);
|
||||
}
|
||||
|
||||
GUI.draw_grid();
|
||||
|
||||
document.getElementById('resize-w').style.marginLeft = W + "px";
|
||||
document.getElementById('resize-w').style.marginTop = Math.round(H/2) + "px";
|
||||
document.getElementById('resize-h').style.marginLeft = Math.round(W/2) + "px";
|
||||
document.getElementById('resize-w').style.marginTop = Math.round(H / 2) + "px";
|
||||
document.getElementById('resize-h').style.marginLeft = Math.round(W / 2) + "px";
|
||||
document.getElementById('resize-h').style.marginTop = H + "px";
|
||||
document.getElementById('resize-wh').style.marginLeft = W + "px";
|
||||
document.getElementById('resize-wh').style.marginTop = H + "px";
|
||||
|
||||
|
||||
this.update_info_block();
|
||||
CON.calc_preview_auto();
|
||||
DRAW.zoom();
|
||||
};
|
||||
this.resize_canvas = function(canvas_name, repaint){
|
||||
var W = round(WIDTH );
|
||||
var H = round(W / RATIO);
|
||||
EVENTS.calc_preview_auto();
|
||||
GUI.zoom();
|
||||
};
|
||||
this.resize_canvas = function (canvas_name, repaint) {
|
||||
var ratio = WIDTH/HEIGHT;
|
||||
var W = Math.round(WIDTH);
|
||||
var H = Math.round(W / ratio);
|
||||
var canvas = document.getElementById(canvas_name);
|
||||
var ctx = canvas.getContext("2d");
|
||||
|
||||
if(repaint==false){
|
||||
|
||||
if (repaint == false) {
|
||||
canvas.width = W;
|
||||
canvas.height = H;
|
||||
}
|
||||
else{
|
||||
}
|
||||
else {
|
||||
//save
|
||||
var buffer = document.createElement('canvas');
|
||||
buffer.width = WIDTH;
|
||||
buffer.height = HEIGHT;
|
||||
buffer.getContext('2d').drawImage(canvas, 0, 0);
|
||||
|
||||
|
||||
canvas.width = W;
|
||||
canvas.height = H;
|
||||
|
||||
|
||||
//restore
|
||||
ctx.drawImage(buffer, 0, 0);
|
||||
}
|
||||
};
|
||||
this.set_alpha = function(){
|
||||
if(LAYERS[LAYER.layer_active].opacity == undefined)
|
||||
LAYERS[LAYER.layer_active].opacity = 1;
|
||||
POP.add({name: "param1", title: "Alpha:", value: LAYERS[LAYER.layer_active].opacity, range: [0, 1], step: 0.01 });
|
||||
POP.show('Opacity', function(user_response){
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
LAYERS[LAYER.layer_active].opacity = param1;
|
||||
canvas_active().globalAlpha = param1;
|
||||
|
||||
var img = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var imgData = img.data;
|
||||
var new_alpha = 255*param1;
|
||||
if(new_alpha < 10)
|
||||
new_alpha = 10;
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
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+3] = new_alpha;
|
||||
}
|
||||
};
|
||||
this.set_alpha = function () {
|
||||
if (this.layers[LAYER.layer_active].opacity == undefined)
|
||||
this.layers[LAYER.layer_active].opacity = 1;
|
||||
POP.add({name: "param1", title: "Alpha:", value: this.layers[LAYER.layer_active].opacity, range: [0, 1], step: 0.01});
|
||||
POP.show(
|
||||
'Opacity',
|
||||
function (user_response) {
|
||||
var param1 = parseFloat(user_response.param1);
|
||||
this.layers[LAYER.layer_active].opacity = param1;
|
||||
canvas_active().globalAlpha = param1;
|
||||
|
||||
var img = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var imgData = img.data;
|
||||
var new_alpha = 255 * param1;
|
||||
if (new_alpha < 10)
|
||||
new_alpha = 10;
|
||||
canvas_active().clearRect(0, 0, WIDTH, HEIGHT);
|
||||
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 + 3] = new_alpha;
|
||||
}
|
||||
}
|
||||
canvas_active().putImageData(img, 0, 0);
|
||||
|
||||
DRAW.zoom();
|
||||
});
|
||||
};
|
||||
this.canvas_active = function(base){
|
||||
for(var i in LAYERS){
|
||||
if(LAYER.layer_active==i){
|
||||
if(base == undefined)
|
||||
return document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
else
|
||||
return document.getElementById(LAYERS[i].name);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
canvas_active().putImageData(img, 0, 0);
|
||||
|
||||
function canvas_active(base){
|
||||
for(var i in LAYERS){
|
||||
if(LAYER.layer_active==i){
|
||||
if(base == undefined)
|
||||
return document.getElementById(LAYERS[i].name).getContext("2d");
|
||||
else
|
||||
return document.getElementById(LAYERS[i].name);
|
||||
GUI.zoom();
|
||||
}
|
||||
);
|
||||
};
|
||||
this.canvas_active = function (base) {
|
||||
for (var i in this.layers) {
|
||||
if (LAYER.layer_active == i) {
|
||||
if (base == undefined)
|
||||
return document.getElementById(this.layers[i].name).getContext("2d");
|
||||
else
|
||||
return document.getElementById(this.layers[i].name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.add_layer = function () {
|
||||
EDIT.save_state();
|
||||
|
||||
var tmp = false;
|
||||
var last_layer = LAYER.layer_active;
|
||||
if (DRAW.select_data != false) {
|
||||
tmp = document.createElement("canvas");
|
||||
tmp.width = DRAW.select_data.w;
|
||||
tmp.height = DRAW.select_data.h;
|
||||
tmp.getContext("2d").drawImage(canvas_active(true), DRAW.select_data.x, DRAW.select_data.y, DRAW.select_data.w, DRAW.select_data.h, 0, 0, DRAW.select_data.w, DRAW.select_data.h);
|
||||
}
|
||||
|
||||
//crete layer
|
||||
LAYER.layer_add();
|
||||
|
||||
if (DRAW.select_data != false) {
|
||||
//copy user selected data to new layer
|
||||
canvas_active().drawImage(tmp, 0, 0);
|
||||
LAYER.layer_renew();
|
||||
|
||||
//clear selection
|
||||
DRAW.select_data = false;
|
||||
canvas_front.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
|
||||
//switch back to old layer
|
||||
LAYER.layer_active = last_layer;
|
||||
LAYER.layer_renew();
|
||||
}
|
||||
};
|
||||
|
||||
this.calc_differences = function (sensitivity, canvas_preview, w, h) {
|
||||
vlayer_active = parseInt(LAYER.layer_active);
|
||||
//first layer
|
||||
var img1 = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var imgData1 = img1.data;
|
||||
|
||||
//second layer
|
||||
var context2 = document.getElementById(this.layers[vlayer_active + 1].name).getContext("2d");
|
||||
var img2 = context2.getImageData(0, 0, WIDTH, HEIGHT);
|
||||
var imgData2 = img2.data;
|
||||
|
||||
//result layer
|
||||
if (canvas_preview == undefined) {
|
||||
//add differences layer
|
||||
LAYER.layer_add();
|
||||
canvas_active().rect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_active().fillStyle = "#ffffff";
|
||||
canvas_active().fill();
|
||||
var img3 = canvas_active().getImageData(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
else {
|
||||
//work on preview layer
|
||||
var canvas_tmp = document.createElement("canvas");
|
||||
canvas_tmp.width = WIDTH;
|
||||
canvas_tmp.height = HEIGHT;
|
||||
var img3 = canvas_tmp.getContext("2d").getImageData(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
var imgData3 = img3.data;
|
||||
for (var xx = 0; xx < WIDTH; xx++) {
|
||||
for (var yy = 0; yy < HEIGHT; yy++) {
|
||||
var x = (xx + yy * WIDTH) * 4;
|
||||
if (Math.abs(imgData1[x] - imgData2[x]) > sensitivity
|
||||
|| Math.abs(imgData1[x + 1] - imgData2[x + 1]) > sensitivity
|
||||
|| Math.abs(imgData1[x + 2] - imgData2[x + 2]) > sensitivity
|
||||
|| Math.abs(imgData1[x + 3] - imgData2[x + 3]) > sensitivity) {
|
||||
imgData3[x] = 255;
|
||||
imgData3[x + 1] = 0;
|
||||
imgData3[x + 2] = 0;
|
||||
imgData3[x + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canvas_preview == undefined)
|
||||
canvas_active().putImageData(img3, 0, 0);
|
||||
else {
|
||||
canvas_tmp.getContext("2d").rect(0, 0, WIDTH, HEIGHT);
|
||||
canvas_tmp.getContext("2d").fillStyle = "#ffffff";
|
||||
canvas_tmp.getContext("2d").fill();
|
||||
canvas_tmp.getContext("2d").putImageData(img3, 0, 0);
|
||||
canvas_preview.clearRect(0, 0, w, h);
|
||||
|
||||
canvas_preview.save();
|
||||
canvas_preview.scale(w / WIDTH, h / HEIGHT);
|
||||
canvas_preview.drawImage(canvas_tmp, 0, 0);
|
||||
canvas_preview.restore();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function canvas_active(base) {
|
||||
for (var i in LAYER.layers) {
|
||||
if (LAYER.layer_active == i) {
|
||||
if (base == undefined)
|
||||
return document.getElementById(LAYER.layers[i].name).getContext("2d");
|
||||
else
|
||||
return document.getElementById(LAYER.layers[i].name);
|
||||
}
|
||||
}
|
||||
console.log('Error, can not find active layer.');
|
||||
}
|
||||
|
||||
157
js/main.js
157
js/main.js
@ -1,143 +1,50 @@
|
||||
/* global HELPER, POP, MAIN, LAYERS, CON, LAYER, DRAW, MENU, TOOLS */
|
||||
/* global canvas_main, canvas_back, COLOUR, ALPHA, canvas_grid */
|
||||
/* global HELPER, EVENTS, LAYER, POP, FILE, GUI, DRAW */
|
||||
/* global WIDTH, HEIGHT, canvas_main, canvas_back, canvas_grid, COLOR, ALPHA */
|
||||
|
||||
var MAIN = new MAIN_CLASS();
|
||||
document.onload = MAIN.init(true);
|
||||
|
||||
function MAIN_CLASS(){
|
||||
this.grid = false;
|
||||
this.TRANSPARENCY = true;
|
||||
var LAYERS_ARCHIVE = [{}, {}, {}];
|
||||
var undo_level = 0;
|
||||
|
||||
this.init = function(first_load){
|
||||
if(first_load===true){
|
||||
TOOLS.draw_helpers();
|
||||
/**
|
||||
* main class - initialize app
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
function MAIN_CLASS() {
|
||||
|
||||
this.init = function (first_load) {
|
||||
if (first_load === true) {
|
||||
GUI.draw_helpers();
|
||||
POP.height_mini = Math.round(POP.width_mini * HEIGHT / WIDTH);
|
||||
}
|
||||
CON.autosize = true;
|
||||
TOOLS.EXIF = false;
|
||||
TOOLS.select_data = false;
|
||||
for(i=1; i<LAYERS.length; i++)
|
||||
}
|
||||
EVENTS.autosize = true;
|
||||
FILE.EXIF = false;
|
||||
DRAW.select_data = false;
|
||||
|
||||
for (i = 1; i < LAYER.layers.length; i++)
|
||||
LAYER.layer_remove(i);
|
||||
LAYERS = [];
|
||||
LAYER.layers = [];
|
||||
canvas_main.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
LAYER.layer_add("Background");
|
||||
LAYER.set_canvas_size();
|
||||
DRAW.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
document.getElementById("canvas_preview").width = DRAW.PREVIEW_SIZE.w;
|
||||
document.getElementById("canvas_preview").height = DRAW.PREVIEW_SIZE.h;
|
||||
var color_rgb = HELPER.hex2rgb(COLOUR);
|
||||
GUI.draw_background(canvas_back, WIDTH, HEIGHT);
|
||||
document.getElementById("canvas_preview").width = GUI.PREVIEW_SIZE.w;
|
||||
document.getElementById("canvas_preview").height = GUI.PREVIEW_SIZE.h;
|
||||
var color_rgb = HELPER.hex2rgb(COLOR);
|
||||
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();
|
||||
GUI.redraw_preview();
|
||||
|
||||
//detect color support
|
||||
if(HELPER.chech_input_color_support('main_colour') == true)
|
||||
document.getElementById("main_colour").value = COLOUR; //supported
|
||||
else{
|
||||
if (HELPER.chech_input_color_support('main_colour') == true)
|
||||
document.getElementById("main_colour").value = COLOR; //supported
|
||||
else {
|
||||
//not supported
|
||||
document.getElementById("main_colour").style.display = 'none';
|
||||
document.getElementById("main_colour_alt").style.display = '';
|
||||
document.getElementById("main_colour_alt").style.backgroundColor = COLOUR;
|
||||
}
|
||||
document.getElementById("main_colour_alt").style.backgroundColor = COLOR;
|
||||
}
|
||||
canvas_grid.globalAlpha = 0.8;
|
||||
};
|
||||
this.save_state = function(){
|
||||
undo_level = 0;
|
||||
j = 0;
|
||||
|
||||
//move previous
|
||||
LAYERS_ARCHIVE[2] = LAYERS_ARCHIVE[1];
|
||||
LAYERS_ARCHIVE[1] = LAYERS_ARCHIVE[0];
|
||||
|
||||
//save last state
|
||||
LAYERS_ARCHIVE[j] = {};
|
||||
LAYERS_ARCHIVE[j].width = WIDTH;
|
||||
LAYERS_ARCHIVE[j].height = HEIGHT;
|
||||
LAYERS_ARCHIVE[j].data = {};
|
||||
for(var i in LAYERS){
|
||||
LAYERS_ARCHIVE[j].data[LAYERS[i].name] = document.createElement('canvas');
|
||||
LAYERS_ARCHIVE[j].data[LAYERS[i].name].width = WIDTH;
|
||||
LAYERS_ARCHIVE[j].data[LAYERS[i].name].height = HEIGHT;
|
||||
LAYERS_ARCHIVE[j].data[LAYERS[i].name].getContext('2d').drawImage(document.getElementById(LAYERS[i].name), 0, 0);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
//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 || 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;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size(true);
|
||||
return true; //size changed, cant undo
|
||||
}
|
||||
|
||||
//undo
|
||||
for(var i in LAYERS){
|
||||
if(LAYERS_ARCHIVE[j].data[LAYERS[i].name] != undefined){
|
||||
document.getElementById(LAYERS[i].name).getContext("2d").clearRect(0, 0, WIDTH, HEIGHT);
|
||||
document.getElementById(LAYERS[i].name).getContext("2d").drawImage(LAYERS_ARCHIVE[j].data[LAYERS[i].name], 0, 0);
|
||||
}
|
||||
}
|
||||
DRAW.zoom();
|
||||
return true;
|
||||
};
|
||||
this.load_xml = function(data){
|
||||
var xml = $.parseXML(data);
|
||||
w = $(xml).find("width").text();
|
||||
h = $(xml).find("height").text();
|
||||
|
||||
//delete old layers
|
||||
for(var i in LAYERS)
|
||||
LAYER.layer_remove(i);
|
||||
|
||||
//init new file
|
||||
ZOOM = 100;
|
||||
MAIN.init();
|
||||
|
||||
//set attributes
|
||||
WIDTH = w;
|
||||
HEIGHT = h;
|
||||
RATIO = WIDTH/HEIGHT;
|
||||
LAYER.set_canvas_size();
|
||||
|
||||
//add layers
|
||||
$('layer', xml).each(function(i){
|
||||
var name = $(this).find("name").text();
|
||||
var visible = $(this).find("visible").text();
|
||||
var opacity = $(this).find("opacity").text();
|
||||
|
||||
if(i > 0){ //first layer exists by default - Background
|
||||
LAYER.layer_add(name);
|
||||
//update attributes
|
||||
LAYERS[LAYER.layer_active].name = name;
|
||||
if(visible == 0)
|
||||
LAYER.layer_visibility(LAYER.layer_active);
|
||||
LAYERS[LAYER.layer_active].opacity = opacity;
|
||||
}
|
||||
});
|
||||
LAYER.layer_renew();
|
||||
|
||||
//add data
|
||||
$('data', xml).each(function(i){
|
||||
var name = $(this).find("name").text();
|
||||
var data = $(this).find("data").text();
|
||||
|
||||
var img = new Image();
|
||||
img.src = data;
|
||||
img.onload = function(){
|
||||
document.getElementById(name).getContext('2d').drawImage(img, 0, 0);
|
||||
|
||||
LAYER.layer_renew();
|
||||
DRAW.zoom();
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
1878
js/menu_actions.js
1878
js/menu_actions.js
File diff suppressed because it is too large
Load Diff
430
js/popup.js
430
js/popup.js
@ -1,430 +0,0 @@
|
||||
/*
|
||||
Usage:
|
||||
var POP = new popup();
|
||||
POP.add({name: "param1", title: "Value1:" });
|
||||
POP.add(...);
|
||||
POP.show('title', main_handler, 'preview_handler', 'onload_handler');
|
||||
|
||||
POP.add() parameters:
|
||||
name type example
|
||||
---------------------------------------------------------------
|
||||
name string 'parameter1'
|
||||
title string 'Enter value:'
|
||||
type string 'select', 'textarea', 'color'
|
||||
value string '314'
|
||||
values array fo strings ['One', 'Two', 'Three']
|
||||
range numbers interval [0, 255]
|
||||
step int/float 1
|
||||
placeholder text 'Enter number here'
|
||||
html html text '<b>bold</b>'
|
||||
function function 'cutom_function'
|
||||
onchange function 'CLASS.onchange_function'
|
||||
*/
|
||||
|
||||
/* global HELPER, MENU, DRAW, POP, LAYER */
|
||||
/* global FILTERS_LIST, LAYERS, canvas_front, WIDTH, HEIGHT */
|
||||
|
||||
var POP = new popup();
|
||||
|
||||
function popup(){
|
||||
this.active = false;
|
||||
this.handler = '';
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
this.width_mini = 195;
|
||||
this.height_mini = 195;
|
||||
this.preview_in_main = false;
|
||||
this.effects = false;
|
||||
this.id = 0;
|
||||
var parameters = [];
|
||||
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){
|
||||
parameters.push(object);
|
||||
};
|
||||
//show popup window
|
||||
this.show = function(title, handler, preview_handler, onload_handler){
|
||||
POP.id = HELPER.getRandomInt(0, 999999999);
|
||||
if(this.active == true){
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
this.active = true;
|
||||
this.handler = handler;
|
||||
if(preview_handler != undefined)
|
||||
this.preview = preview_handler;
|
||||
if(onload_handler != undefined)
|
||||
this.onload = onload_handler;
|
||||
var html = '';
|
||||
|
||||
var dim = HELPER.get_dimensions();
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = 150+'px';
|
||||
popup.style.left = Math.round(dim[0]/2)+'px';
|
||||
|
||||
if(this.effects == true){
|
||||
var index;
|
||||
for(var i=0; i<FILTERS_LIST.length; i++){
|
||||
if(FILTERS_LIST[i].name == MENU.last_menu){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var prev_index = index-1;
|
||||
if(prev_index < 0){
|
||||
prev_index = 0;
|
||||
}
|
||||
var next_index = index+1;
|
||||
if(next_index > FILTERS_LIST.length-1){
|
||||
next_index = FILTERS_LIST.length-1;
|
||||
}
|
||||
html += '<span style="float:right;">';
|
||||
html += '<input id="previous_filter" type="button" value="<"> ';
|
||||
html += '<select id="effect_browser">';
|
||||
html += '<option value="">--- Select effect ---</option>';
|
||||
for(var i=0; i<FILTERS_LIST.length; i++){
|
||||
var selected = '';
|
||||
if(FILTERS_LIST[i].name == MENU.last_menu)
|
||||
var selected = 'selected';
|
||||
html += ' <option ' + selected +' value="' + i + '">' + FILTERS_LIST[i].title + '</option>';
|
||||
}
|
||||
html += '</select>';
|
||||
html += ' <input id="next_filter" onclick="" type="button" value=">"> ';
|
||||
html += '</span>';
|
||||
}
|
||||
html += '<h2 id="popup_drag">'+title+'</h2>';
|
||||
|
||||
//preview area
|
||||
if(this.preview !== false && this.preview_in_main == false){
|
||||
html += '<div style="margin-top:15px;margin-bottom:15px;">';
|
||||
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>';
|
||||
}
|
||||
|
||||
//settings
|
||||
html += '<table style="width:99%;">';
|
||||
for(var i in parameters){
|
||||
var parameter = parameters[i];
|
||||
html += '<tr>';
|
||||
if(title != 'Error')
|
||||
html += '<td style="font-weight:bold;padding-right:3px;width:130px;">'+parameter.title+'</td>';
|
||||
if(parameter.name != undefined){
|
||||
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){
|
||||
//input, range, textarea, color
|
||||
var step = 1;
|
||||
if(parameter.step != undefined)
|
||||
step = parameter.step;
|
||||
if(parameter.range != undefined){
|
||||
//range
|
||||
var preview_code = '';
|
||||
if(this.preview !== false)
|
||||
preview_code = 'POP.view();';
|
||||
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 if(parameter.type == 'color'){
|
||||
//color
|
||||
html += '<td><input type="color" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" /></td>';
|
||||
}
|
||||
else{
|
||||
//input or textarea
|
||||
if(parameter.placeholder == undefined)
|
||||
parameter.placeholder = '';
|
||||
if(parameter.type == 'textarea')
|
||||
html += '<td><textarea style="height:80px;" id="pop_data_'+parameter.name+'" placeholder="'+parameter.placeholder+'">'+parameter.value+'</textarea></td>';
|
||||
else
|
||||
html += '<td colspan="2"><input type="text" id="pop_data_'+parameter.name+'" value="'+parameter.value+'" placeholder="'+parameter.placeholder+'" 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 style="padding-bottom:3px;padding-top:3px;" 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="color:#393939;" 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>';
|
||||
|
||||
//action buttons
|
||||
html += '<div style="text-align:center;margin-top:20px;margin-bottom:15px;">';
|
||||
html += '<input type="button" onclick="POP.save();" class="button" value="OK" />';
|
||||
html += '<input type="button" onclick="POP.hide();" class="button" value="Cancel" />';
|
||||
if(this.preview_in_main !== false)
|
||||
html += '<input type="button" onclick="POP.view();" class="button" value="Preview" />';
|
||||
html += '</div>';
|
||||
|
||||
document.getElementById("popup").innerHTML = html;
|
||||
document.getElementById("popup").style.display="block";
|
||||
if(parameters.length > 15)
|
||||
document.getElementById("popup").style.overflowY="scroll";
|
||||
else
|
||||
document.getElementById("popup").style.overflowY='hidden';
|
||||
|
||||
//onload
|
||||
if(this.onload != ''){
|
||||
if(typeof this.onload == "string")
|
||||
window[this.onload]();
|
||||
else
|
||||
this.onload();
|
||||
}
|
||||
|
||||
//some events for effects browser
|
||||
if(this.effects == true){
|
||||
document.getElementById('previous_filter').disabled = false;
|
||||
document.getElementById('next_filter').disabled = false;
|
||||
if(index == 0){
|
||||
document.getElementById('previous_filter').disabled = true;
|
||||
}
|
||||
if(index == FILTERS_LIST.length-1){
|
||||
document.getElementById('next_filter').disabled = true;
|
||||
}
|
||||
//previous
|
||||
document.getElementById('previous_filter').addEventListener('click', function(event){
|
||||
POP.hide();
|
||||
MENU.last_menu = FILTERS_LIST[prev_index].name;
|
||||
MENU.do_menu([FILTERS_LIST[prev_index].name]);
|
||||
});
|
||||
//next
|
||||
document.getElementById('next_filter').addEventListener('click', function(event){
|
||||
POP.hide();
|
||||
MENU.last_menu = FILTERS_LIST[next_index].name;
|
||||
MENU.do_menu([FILTERS_LIST[next_index].name]);
|
||||
});
|
||||
//onchange
|
||||
var effect_browser = document.getElementById('effect_browser');
|
||||
effect_browser.addEventListener('change', function(event){
|
||||
var value = effect_browser.options[effect_browser.selectedIndex].value;
|
||||
POP.hide();
|
||||
MENU.last_menu = FILTERS_LIST[value].name;
|
||||
MENU.do_menu([FILTERS_LIST[value].name]);
|
||||
});
|
||||
}
|
||||
|
||||
//load preview?
|
||||
if(this.preview !== false && this.preview_in_main == false){
|
||||
//original
|
||||
var pop_pre = document.getElementById("pop_pre").getContext("2d");
|
||||
pop_pre.rect(0, 0, POP.width_mini, POP.height_mini);
|
||||
pop_pre.fillStyle = "#ffffff";
|
||||
pop_pre.fill();
|
||||
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, POP.width_mini, POP.height_mini);
|
||||
pop_post.fillStyle = "#ffffff";
|
||||
pop_post.fill();
|
||||
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 = 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
|
||||
this.hide = function(){
|
||||
document.getElementById('popup').style.display='none';
|
||||
parameters = [];
|
||||
this.handler = '';
|
||||
this.active = false;
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
this.preview_in_main = false;
|
||||
this.effects = 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){
|
||||
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++){
|
||||
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;
|
||||
if(inputs[i].type == 'radio'){
|
||||
if(inputs[i].checked==true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
for (i = 0; i<selects.length; i++) {
|
||||
if(selects[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = selects[i].id.substr(9);
|
||||
var value = selects[i].value;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
this.save = function(){
|
||||
this.active = false;
|
||||
document.getElementById("popup").style.display="none";
|
||||
var response={};
|
||||
inputs = document.getElementsByTagName('input');
|
||||
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;
|
||||
if(inputs[i].type == 'radio'){
|
||||
if(inputs[i].checked==true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
for (i = 0; i<selects.length; i++) {
|
||||
if(selects[i].id.substr(0,9)=='pop_data_'){
|
||||
var key = selects[i].id.substr(9);
|
||||
var value = selects[i].value;
|
||||
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;
|
||||
this.preview_in_main = false;
|
||||
this.effects = false;
|
||||
if(this.handler != ''){
|
||||
if(typeof this.handler == "string")
|
||||
window[this.handler](response);
|
||||
else
|
||||
this.handler(response);
|
||||
}
|
||||
this.handler = '';
|
||||
};
|
||||
//validate input field, unless browser supports input=range
|
||||
this.validate = function(field){
|
||||
for(var i in parameters){
|
||||
var parameter = parameters[i];
|
||||
if("pop_data_"+parameter.name == field.id && parameter.range != undefined){
|
||||
if(field.value == '-' || field.value == '') return true;
|
||||
|
||||
var value = parseFloat(field.value);
|
||||
if(isNaN(value) || value != field.value)
|
||||
field.value = parameter.value; //not number
|
||||
if(value < parameter.range[0])
|
||||
field.value = parameter.range[0]; //less then min
|
||||
else if(value > parameter.range[1])
|
||||
field.value = parameter.range[1]; //more then max
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
//canvas layers
|
||||
var canvas_back = document.getElementById("canvas_back").getContext("2d"); //layer for grid/transparency
|
||||
var canvas_main = document.getElementById("Background").getContext("2d"); //background
|
||||
//new layers insert convas here
|
||||
var canvas_front = document.getElementById("canvas_front").getContext("2d"); //tmp layer
|
||||
var canvas_grid = document.getElementById("canvas_grid").getContext("2d"); //grid layer
|
||||
var canvas_preview = document.getElementById("canvas_preview").getContext("2d"); //mini preview
|
||||
|
||||
//settings
|
||||
var AUTHOR = 'ViliusL';
|
||||
var EMAIL = 'www.viliusl@gmail.com';
|
||||
var VERSION = '2.4';
|
||||
var WIDTH = 800; //canvas midth
|
||||
var HEIGHT = 600; //canvas height
|
||||
var RATIO = WIDTH/HEIGHT; //width & height ratio
|
||||
var LAYERS = []; //layers data
|
||||
var ACTION = 'select_tool'; ///default action
|
||||
var COLOUR = '#0000ff'; //current color
|
||||
var ZOOM = 100; //zoom level 10 - infinity
|
||||
var ALPHA = 255; //default alpha
|
||||
var SAVE_NAME = 'example'; //default save name
|
||||
|
||||
var SAVE_TYPES = [
|
||||
"PNG - Portable Network Graphics", //default
|
||||
"JPG - JPG/JPEG Format", //autodetect on photos where png useless?
|
||||
"XML - Full layers data", //aka PSD
|
||||
"BMP - Windows Bitmap", //firefox only, useless?
|
||||
"WEBP - Weppy File Format", //chrome only
|
||||
];
|
||||
|
||||
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, anti_aliasing: 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, anti_aliasing: false} },
|
||||
{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, type_values: ['Simple', 'Multi-line', 'Arrow', 'Curve'] } },
|
||||
{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: {type: 'Brush', type_values: ['Brush', 'BezierCurve', 'Chrome', 'Fur', 'Grouped', 'Shaded', 'Sketchy'], size: 5, anti_alias: false }, on_update: 'update_brush', },
|
||||
{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: 0.5} },
|
||||
{name: 'burn_dodge_tool', title: 'Burn/Dodge tool', icon: ['all.png', -500+3, -50+4], attributes: {burn: true, size: 30, power: 50} },
|
||||
{name: 'desaturate_tool', title: 'Desaturate', icon: ['all.png', -550+3, -00+4], attributes: {size: 50, anti_alias: true} },
|
||||
{name: 'clone_tool', title: 'Clone tool', icon: ['all.png', -350+4, -50+3], attributes: {size: 30, anti_alias: true} },
|
||||
{name: 'gradient_tool', title: 'Gradient', icon: ['all.png', -400+3, -50+4], attributes: {radial: false, power: 50} },
|
||||
{name: 'crop_tool', title: 'Crop', icon: ['all.png', -450+2, -50+2], attributes: { } },
|
||||
];
|
||||
|
||||
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: 'Image filters', name: 'ImageFilters.js',link: 'https://github.com/arahaya/ImageFilters.js' },
|
||||
{title: 'KD-tree', name: 'kdtree.js', link: 'http://jsdo.it/peko/wKvk' },
|
||||
];
|
||||
|
||||
var FILTERS_LIST = [
|
||||
{title: 'Black and White', name: 'effects_bw' },
|
||||
{title: 'Blur-Box', name: 'effects_BoxBlur' },
|
||||
{title: 'Blur-Gaussian', name: 'effects_GaussianBlur' },
|
||||
{title: 'Blur-Stack', name: 'effects_StackBlur' },
|
||||
{title: 'Blur-Zoom', name: 'effects_zoomblur' },
|
||||
{title: 'Bulge/Pinch', name: 'effects_bulge_pinch' },
|
||||
{title: 'Colorize', name: 'effects_colorize' },
|
||||
{title: 'Denoise', name: 'effects_denoise' },
|
||||
{title: 'Desaturate', name: 'effects_Desaturate' },
|
||||
{title: 'Dither', name: 'effects_Dither' },
|
||||
{title: 'Dot Screen', name: 'effects_dot_screen' },
|
||||
{title: 'Edge', name: 'effects_Edge' },
|
||||
{title: 'Emboss', name: 'effects_Emboss' },
|
||||
{title: 'Enrich', name: 'effects_Enrich' },
|
||||
{title: 'Gamma', name: 'effects_Gamma' },
|
||||
{title: 'Grains', name: 'effects_Grains' },
|
||||
{title: 'Heatmap', name: 'effects_heatmap' },
|
||||
{title: 'HSL Adjustment', name: 'effects_HSLAdjustment' },
|
||||
{title: 'JPG Compression', name: 'effects_jpg_vintage' },
|
||||
{title: 'Mosaic', name: 'effects_Mosaic' },
|
||||
{title: 'Oil', name: 'effects_Oil' },
|
||||
{title: 'Posterize', name: 'effects_Posterize' },
|
||||
{title: 'Sepia', name: 'effects_Sepia' },
|
||||
{title: 'Sharpen', name: 'effects_Sharpen' },
|
||||
{title: 'Solarize', name: 'effects_Solarize' },
|
||||
{title: 'Tilt Shift', name: 'effects_tilt_shift' },
|
||||
{title: 'Vignette', name: 'effects_vignette' },
|
||||
{title: 'Vintage', name: 'effects_vintage' },
|
||||
];
|
||||
2272
js/tools.js
2272
js/tools.js
File diff suppressed because it is too large
Load Diff
@ -254,7 +254,6 @@ ImageFilters.utils = {
|
||||
};
|
||||
|
||||
|
||||
// TODO
|
||||
ImageFilters.Translate = function (srcImageData, x, y, interpolation) {
|
||||
|
||||
};
|
||||
@ -1181,15 +1180,11 @@ ImageFilters.Desaturate = function (srcImageData) {
|
||||
return dstImageData;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: use bilinear
|
||||
*/
|
||||
ImageFilters.DisplacementMapFilter = function (srcImageData, mapImageData, mapX, mapY, componentX, componentY, scaleX, scaleY, mode) {
|
||||
var srcPixels = srcImageData.data,
|
||||
srcWidth = srcImageData.width,
|
||||
srcHeight = srcImageData.height,
|
||||
srcLength = srcPixels.length,
|
||||
// dstImageData = this.utils.createImageData(srcWidth, srcHeight),
|
||||
dstImageData = ImageFilters.Clone(srcImageData),
|
||||
dstPixels = dstImageData.data;
|
||||
|
||||
@ -1993,7 +1988,6 @@ ImageFilters.Twril = function (srcImageData, centerX, centerY, radius, angle, ed
|
||||
} else {
|
||||
// nearest neighbor
|
||||
// round tx, ty
|
||||
// TODO edge actions!!
|
||||
srcIndex = ((ty + 0.5 | 0) * srcWidth + (tx + 0.5 | 0)) << 2;
|
||||
dstPixels[dstIndex] = srcPixels[srcIndex];
|
||||
dstPixels[dstIndex + 1] = srcPixels[srcIndex + 1];
|
||||
|
||||
9
libs/jquery.js
vendored
9
libs/jquery.js
vendored
File diff suppressed because one or more lines are too long
434
libs/popup.js
Normal file
434
libs/popup.js
Normal file
@ -0,0 +1,434 @@
|
||||
/* global MAIN, HELPER, POP, LAYER, EFFECTS, GUI */
|
||||
/* global canvas_front, WIDTH, HEIGHT */
|
||||
|
||||
var POP = new popup();
|
||||
|
||||
/**
|
||||
* user dialogs library
|
||||
*
|
||||
* @author ViliusL
|
||||
*
|
||||
* Usage:
|
||||
* var POP = new popup();
|
||||
* POP.add({name: "param1", title: "Value1:" });
|
||||
* POP.add(...);
|
||||
* POP.show('title', main_handler, preview_handler, onload_handler);
|
||||
*
|
||||
* POP.add() parameters:
|
||||
* - name type example
|
||||
* - ---------------------------------------------------------------
|
||||
* - name string 'parameter1'
|
||||
* - title string 'Enter value:'
|
||||
* - type string 'select', 'textarea', 'color'
|
||||
* - value string '314'
|
||||
* - values array fo strings ['One', 'Two', 'Three']
|
||||
* - range numbers interval [0, 255]
|
||||
* - step int/float 1
|
||||
* - placeholder text 'Enter number here'
|
||||
* - html html text '<b>bold</b>'
|
||||
* - function function 'cutom_function'
|
||||
* - onchange function 'CLASS.onchange_function'
|
||||
*/
|
||||
function popup() {
|
||||
this.active = false;
|
||||
this.handler = '';
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
this.width_mini = 184;
|
||||
this.height_mini = 195;
|
||||
this.preview_in_main = false;
|
||||
this.effects = false;
|
||||
this.id = 0;
|
||||
var parameters = [];
|
||||
var layer_active_small = document.createElement("canvas");
|
||||
var layer_active_small_ctx = layer_active_small.getContext("2d");
|
||||
|
||||
//add parameter
|
||||
this.add = function (object) {
|
||||
parameters.push(object);
|
||||
};
|
||||
//show popup window
|
||||
this.show = function (title, handler, preview_handler, onload_handler) {
|
||||
POP.id = HELPER.getRandomInt(0, 999999999);
|
||||
if (this.active == true) {
|
||||
this.hide();
|
||||
return false;
|
||||
}
|
||||
this.active = true;
|
||||
this.handler = handler;
|
||||
if (preview_handler != undefined)
|
||||
this.preview = preview_handler;
|
||||
if (onload_handler != undefined)
|
||||
this.onload = onload_handler;
|
||||
var html = '';
|
||||
|
||||
var dim = HELPER.get_dimensions();
|
||||
popup = document.getElementById('popup');
|
||||
popup.style.top = 150 + 'px';
|
||||
popup.style.left = Math.round(dim[0] / 2) + 'px';
|
||||
|
||||
if (this.effects == true) {
|
||||
var index;
|
||||
for (var i = 0; i < EFFECTS.FILTERS_LIST.length; i++) {
|
||||
if (EFFECTS.FILTERS_LIST[i].name == GUI.last_menu) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var prev_index = index - 1;
|
||||
if (prev_index < 0) {
|
||||
prev_index = 0;
|
||||
}
|
||||
var next_index = index + 1;
|
||||
if (next_index > EFFECTS.FILTERS_LIST.length - 1) {
|
||||
next_index = EFFECTS.FILTERS_LIST.length - 1;
|
||||
}
|
||||
html += '<span style="float:right;">';
|
||||
html += '<input id="previous_filter" type="button" value="<"> ';
|
||||
html += '<select id="effect_browser">';
|
||||
html += '<option value="">--- Select effect ---</option>';
|
||||
for (var i = 0; i < EFFECTS.FILTERS_LIST.length; i++) {
|
||||
var selected = '';
|
||||
if (EFFECTS.FILTERS_LIST[i].name == GUI.last_menu)
|
||||
var selected = 'selected';
|
||||
html += ' <option ' + selected + ' value="' + i + '">' + EFFECTS.FILTERS_LIST[i].title + '</option>';
|
||||
}
|
||||
html += '</select>';
|
||||
html += ' <input id="next_filter" onclick="" type="button" value=">"> ';
|
||||
html += '</span>';
|
||||
}
|
||||
html += '<h2 id="popup_drag">' + title + '</h2>';
|
||||
|
||||
//preview area
|
||||
if (this.preview !== false && this.preview_in_main == false) {
|
||||
html += '<div style="margin-top:15px;margin-bottom:15px;">';
|
||||
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>';
|
||||
}
|
||||
|
||||
//settings
|
||||
html += '<table style="width:99%;">';
|
||||
for (var i in parameters) {
|
||||
var parameter = parameters[i];
|
||||
html += '<tr>';
|
||||
if (title != 'Error')
|
||||
html += '<td style="font-weight:bold;padding-right:3px;width:130px;">' + parameter.title + '</td>';
|
||||
if (parameter.name != undefined) {
|
||||
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) {
|
||||
//input, range, textarea, color
|
||||
var step = 1;
|
||||
if (parameter.step != undefined)
|
||||
step = parameter.step;
|
||||
if (parameter.range != undefined) {
|
||||
//range
|
||||
var preview_code = '';
|
||||
if (this.preview !== false)
|
||||
preview_code = 'POP.view();';
|
||||
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 if (parameter.type == 'color') {
|
||||
//color
|
||||
html += '<td><input type="color" id="pop_data_' + parameter.name + '" value="' + parameter.value + '" /></td>';
|
||||
}
|
||||
else {
|
||||
//input or textarea
|
||||
if (parameter.placeholder == undefined)
|
||||
parameter.placeholder = '';
|
||||
if (parameter.type == 'textarea')
|
||||
html += '<td><textarea style="height:80px;" id="pop_data_' + parameter.name + '" placeholder="' + parameter.placeholder + '">' + parameter.value + '</textarea></td>';
|
||||
else
|
||||
html += '<td colspan="2"><input type="text" id="pop_data_' + parameter.name + '" value="' + parameter.value + '" placeholder="' + parameter.placeholder + '" 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 style="padding-bottom:3px;padding-top:3px;" 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="color:#393939;" 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>';
|
||||
|
||||
//action buttons
|
||||
html += '<div style="text-align:center;margin-top:20px;margin-bottom:15px;">';
|
||||
html += '<input type="button" onclick="POP.save();" class="button" value="OK" />';
|
||||
html += '<input type="button" onclick="POP.hide();" class="button" value="Cancel" />';
|
||||
if (this.preview_in_main !== false)
|
||||
html += '<input type="button" onclick="POP.view();" class="button" value="Preview" />';
|
||||
html += '</div>';
|
||||
|
||||
document.getElementById("popup").innerHTML = html;
|
||||
document.getElementById("popup").style.display = "block";
|
||||
if (parameters.length > 15)
|
||||
document.getElementById("popup").style.overflowY = "scroll";
|
||||
else
|
||||
document.getElementById("popup").style.overflowY = 'hidden';
|
||||
|
||||
//onload
|
||||
if (this.onload != '') {
|
||||
if (typeof this.onload == "string")
|
||||
window[this.onload]();
|
||||
else
|
||||
this.onload();
|
||||
}
|
||||
|
||||
//some events for effects browser
|
||||
if (this.effects == true) {
|
||||
document.getElementById('previous_filter').disabled = false;
|
||||
document.getElementById('next_filter').disabled = false;
|
||||
if (index == 0) {
|
||||
document.getElementById('previous_filter').disabled = true;
|
||||
}
|
||||
if (index == EFFECTS.FILTERS_LIST.length - 1) {
|
||||
document.getElementById('next_filter').disabled = true;
|
||||
}
|
||||
//previous
|
||||
document.getElementById('previous_filter').addEventListener('click', function (event) {
|
||||
POP.hide();
|
||||
GUI.last_menu = EFFECTS.FILTERS_LIST[prev_index].name;
|
||||
call_menu(EFFECTS, EFFECTS.FILTERS_LIST[prev_index].name);
|
||||
});
|
||||
//next
|
||||
document.getElementById('next_filter').addEventListener('click', function (event) {
|
||||
POP.hide();
|
||||
GUI.last_menu = EFFECTS.FILTERS_LIST[next_index].name;
|
||||
call_menu(EFFECTS, EFFECTS.FILTERS_LIST[next_index].name);
|
||||
});
|
||||
//onchange
|
||||
var effect_browser = document.getElementById('effect_browser');
|
||||
effect_browser.addEventListener('change', function (event) {
|
||||
var value = effect_browser.options[effect_browser.selectedIndex].value;
|
||||
POP.hide();
|
||||
GUI.last_menu = EFFECTS.FILTERS_LIST[value].name;
|
||||
call_menu(EFFECTS, EFFECTS.FILTERS_LIST[value].name);
|
||||
});
|
||||
}
|
||||
|
||||
//load preview?
|
||||
if (this.preview !== false && this.preview_in_main == false) {
|
||||
//original
|
||||
var pop_pre = document.getElementById("pop_pre").getContext("2d");
|
||||
pop_pre.rect(0, 0, POP.width_mini, POP.height_mini);
|
||||
pop_pre.fillStyle = "#ffffff";
|
||||
pop_pre.fill();
|
||||
GUI.draw_background(pop_pre, POP.width_mini, POP.height_mini, 5);
|
||||
pop_pre.drawImage(document.getElementById(LAYER.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, POP.width_mini, POP.height_mini);
|
||||
pop_post.fillStyle = "#ffffff";
|
||||
pop_post.fill();
|
||||
GUI.draw_background(pop_post, POP.width_mini, POP.height_mini, 5);
|
||||
pop_post.drawImage(document.getElementById(LAYER.layers[LAYER.layer_active].name), 0, 0, POP.width_mini, POP.height_mini);
|
||||
|
||||
//prepare temp canvas
|
||||
layer_active_small.width = POP.width_mini;
|
||||
layer_active_small.height = POP.height_mini;
|
||||
layer_active_small_ctx.drawImage(document.getElementById(LAYER.layers[LAYER.layer_active].name), 0, 0, POP.width_mini, POP.height_mini);
|
||||
POP.view();
|
||||
}
|
||||
};
|
||||
|
||||
//hide popup
|
||||
this.hide = function () {
|
||||
document.getElementById('popup').style.display = 'none';
|
||||
parameters = [];
|
||||
this.handler = '';
|
||||
this.active = false;
|
||||
this.preview = false;
|
||||
this.onload = false;
|
||||
this.preview_in_main = false;
|
||||
this.effects = 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) {
|
||||
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++) {
|
||||
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;
|
||||
if (inputs[i].type == 'radio') {
|
||||
if (inputs[i].checked == true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
for (i = 0; i < selects.length; i++) {
|
||||
if (selects[i].id.substr(0, 9) == 'pop_data_') {
|
||||
var key = selects[i].id.substr(9);
|
||||
var value = selects[i].value;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
this.save = function () {
|
||||
this.active = false;
|
||||
document.getElementById("popup").style.display = "none";
|
||||
var response = {};
|
||||
inputs = document.getElementsByTagName('input');
|
||||
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;
|
||||
if (inputs[i].type == 'radio') {
|
||||
if (inputs[i].checked == true)
|
||||
response[key] = value;
|
||||
}
|
||||
else
|
||||
response[key] = value;
|
||||
|
||||
}
|
||||
}
|
||||
selects = document.getElementsByTagName('select');
|
||||
for (i = 0; i < selects.length; i++) {
|
||||
if (selects[i].id.substr(0, 9) == 'pop_data_') {
|
||||
var key = selects[i].id.substr(9);
|
||||
var value = selects[i].value;
|
||||
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;
|
||||
this.preview_in_main = false;
|
||||
this.effects = false;
|
||||
if (this.handler != '') {
|
||||
if (typeof this.handler == "object")
|
||||
this.handler[0][this.handler[1]](response);
|
||||
else if (typeof this.handler == "function")
|
||||
this.handler(response);
|
||||
else
|
||||
console.log('Error: wrong function type: ' + this.handler);
|
||||
}
|
||||
this.handler = '';
|
||||
};
|
||||
|
||||
//validate input field, unless browser supports input=range
|
||||
this.validate = function (field) {
|
||||
for (var i in parameters) {
|
||||
var parameter = parameters[i];
|
||||
if ("pop_data_" + parameter.name == field.id && parameter.range != undefined) {
|
||||
if (field.value == '-' || field.value == '')
|
||||
return true;
|
||||
|
||||
var value = parseFloat(field.value);
|
||||
if (isNaN(value) || value != field.value)
|
||||
field.value = parameter.value; //not number
|
||||
if (value < parameter.range[0])
|
||||
field.value = parameter.range[0]; //less then min
|
||||
else if (value > parameter.range[1])
|
||||
field.value = parameter.range[1]; //more then max
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
194
libs/sift.js
194
libs/sift.js
@ -1,22 +1,32 @@
|
||||
//about: SIFT: scale-invariant-feature-transform, keypoints, panorama
|
||||
//author: ViliusL
|
||||
/**
|
||||
* SIFT: scale-invariant-feature-transform, keypoints, panorama
|
||||
*
|
||||
* @author ViliusL
|
||||
*/
|
||||
|
||||
/* global HELPER, DRAW, ImageFilters, LAYER, canvas_active */
|
||||
/* global HELPER, IMAGE, ImageFilters, LAYER, canvas_active */
|
||||
|
||||
var SIFT = new SIFT_CLASS();
|
||||
|
||||
function SIFT_CLASS(){
|
||||
var avg_offset = 50; //contrast check, smaller - more points, better accuracy, but slower
|
||||
var avg_step = 4; //how much pixels to check for each side to get average
|
||||
function SIFT_CLASS() {
|
||||
/**
|
||||
* contrast check, smaller - more points, better accuracy, but slower
|
||||
*/
|
||||
var avg_offset = 50;
|
||||
|
||||
/**
|
||||
* how much pixels to check for each side to get average
|
||||
*/
|
||||
var avg_step = 4;
|
||||
|
||||
//generate key points for image
|
||||
this.generate_keypoints = function(canvas, show_points){
|
||||
this.generate_keypoints = function (canvas, show_points) {
|
||||
var W = canvas.width;
|
||||
var H = canvas.height;
|
||||
HELPER.timer_init();
|
||||
|
||||
|
||||
//check whitespace
|
||||
var trim_details = DRAW.trim_info(canvas);
|
||||
var trim_details = IMAGE.trim_info(canvas);
|
||||
W = W - trim_details.left - trim_details.right;
|
||||
H = H - trim_details.top - trim_details.bottom;
|
||||
//make copy
|
||||
@ -25,85 +35,84 @@ function SIFT_CLASS(){
|
||||
clone.height = H;
|
||||
var ctx = clone.getContext("2d");
|
||||
ctx.drawImage(canvas, -trim_details.left, -trim_details.top, canvas.width, canvas.height);
|
||||
|
||||
//DRAW.auto_adjust(ctx, W, H); //normalize
|
||||
|
||||
|
||||
//greyscale
|
||||
var imageData = ctx.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.GrayScale(imageData); //add effect
|
||||
ctx.putImageData(filtered, 0, 0);
|
||||
|
||||
|
||||
//make few copies and blur each
|
||||
var n = 5;
|
||||
var copies = [];
|
||||
for(var i = 0; i < n; i++){
|
||||
for (var i = 0; i < n; i++) {
|
||||
var tmp_canvas = document.createElement("canvas");
|
||||
tmp_canvas.width = W;
|
||||
tmp_canvas.height = H;
|
||||
var ctx_i = tmp_canvas.getContext("2d");
|
||||
ctx_i.drawImage(clone, 0, 0);
|
||||
|
||||
|
||||
//gausian blur
|
||||
var imageData = ctx_i.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.GaussianBlur(imageData, i + 0.5); //add effect
|
||||
ctx_i.putImageData(filtered, 0, 0);
|
||||
|
||||
|
||||
copies.push(tmp_canvas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//find extreme points
|
||||
var points = [];
|
||||
var points = [];
|
||||
var n0 = avg_step * 2 + 1;
|
||||
for(var c = 1; c < copies.length - 1; c++){
|
||||
for (var c = 1; c < copies.length - 1; c++) {
|
||||
var imageData = copies[c].getContext("2d").getImageData(0, 0, W, H).data;
|
||||
var imageData0 = copies[c-1].getContext("2d").getImageData(0, 0, W, H).data;
|
||||
var imageData2 = copies[c+1].getContext("2d").getImageData(0, 0, W, H).data;
|
||||
for(var j = avg_step; j < H - avg_step; j++){
|
||||
for(var i = avg_step; i < W - avg_step; i++){
|
||||
var x = (i + j*W) * 4;
|
||||
if(imageData[x+3] == 0) continue; //transparent
|
||||
if(imageData[x] < imageData[x-4] || imageData[x] < imageData[x+4] || imageData[x] > imageData[x-4] || imageData[x] > imageData[x+4]){
|
||||
var x_pre = (i + (j-1)*W) * 4;
|
||||
var x_post = (i + (j+1)*W) * 4;
|
||||
var imageData0 = copies[c - 1].getContext("2d").getImageData(0, 0, W, H).data;
|
||||
var imageData2 = copies[c + 1].getContext("2d").getImageData(0, 0, W, H).data;
|
||||
for (var j = avg_step; j < H - avg_step; j++) {
|
||||
for (var i = avg_step; i < W - avg_step; i++) {
|
||||
var x = (i + j * W) * 4;
|
||||
if (imageData[x + 3] == 0)
|
||||
continue; //transparent
|
||||
if (imageData[x] < imageData[x - 4] || imageData[x] < imageData[x + 4] || imageData[x] > imageData[x - 4] || imageData[x] > imageData[x + 4]) {
|
||||
var x_pre = (i + (j - 1) * W) * 4;
|
||||
var x_post = (i + (j + 1) * W) * 4;
|
||||
//calc average
|
||||
var area_average = 0;
|
||||
for(var l = -avg_step; l <= avg_step; l++){
|
||||
var avgi = (i + (j-l)*W) * 4;
|
||||
for(var a = -avg_step; a <= avg_step; a++){
|
||||
area_average += imageData[avgi + 4*a];
|
||||
}
|
||||
for (var l = -avg_step; l <= avg_step; l++) {
|
||||
var avgi = (i + (j - l) * W) * 4;
|
||||
for (var a = -avg_step; a <= avg_step; a++) {
|
||||
area_average += imageData[avgi + 4 * a];
|
||||
}
|
||||
area_average = area_average / (n0*n0);
|
||||
}
|
||||
area_average = area_average / (n0 * n0);
|
||||
//max
|
||||
if(imageData[x] + avg_offset < area_average){
|
||||
var min = Math.min(imageData[x_pre-4], imageData[x_pre], imageData[x_pre+4], imageData[x-4], imageData[x+4], imageData[x_post-4], imageData[x_post], imageData[x_post+4]);
|
||||
if(imageData[x] <= min){
|
||||
var min0 = Math.min(imageData0[x_pre-4], imageData0[x_pre], imageData0[x_pre+4], imageData0[x-4], imageData0[x+4], imageData0[x_post-4], imageData0[x_post], imageData0[x_post+4]);
|
||||
if(imageData[x] <= min0){
|
||||
var min2 = Math.min(imageData2[x_pre-4], imageData2[x_pre], imageData2[x_pre+4], imageData2[x-4], imageData2[x+4], imageData2[x_post-4], imageData2[x_post], imageData2[x_post+4]);
|
||||
if(imageData[x] <= min2)
|
||||
if (imageData[x] + avg_offset < area_average) {
|
||||
var min = Math.min(imageData[x_pre - 4], imageData[x_pre], imageData[x_pre + 4], imageData[x - 4], imageData[x + 4], imageData[x_post - 4], imageData[x_post], imageData[x_post + 4]);
|
||||
if (imageData[x] <= min) {
|
||||
var min0 = Math.min(imageData0[x_pre - 4], imageData0[x_pre], imageData0[x_pre + 4], imageData0[x - 4], imageData0[x + 4], imageData0[x_post - 4], imageData0[x_post], imageData0[x_post + 4]);
|
||||
if (imageData[x] <= min0) {
|
||||
var min2 = Math.min(imageData2[x_pre - 4], imageData2[x_pre], imageData2[x_pre + 4], imageData2[x - 4], imageData2[x + 4], imageData2[x_post - 4], imageData2[x_post], imageData2[x_post + 4]);
|
||||
if (imageData[x] <= min2)
|
||||
points.push({
|
||||
x: i + trim_details.left,
|
||||
y: j + trim_details.top,
|
||||
w: round(area_average - imageData[x] - avg_offset)
|
||||
});
|
||||
}
|
||||
w: Math.round(area_average - imageData[x] - avg_offset)
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//min
|
||||
if(imageData[x] - avg_offset > area_average){
|
||||
var max = Math.max(imageData[x_pre-4], imageData[x_pre], imageData[x_pre+4], imageData[x-4], imageData[x+4], imageData[x_post-4], imageData[x_post], imageData[x_post+4]);
|
||||
if(imageData[x] >= max){
|
||||
var max0 = Math.max(imageData0[x_pre-4], imageData0[x_pre], imageData0[x_pre+4], imageData0[x-4], imageData0[x+4], imageData0[x_post-4], imageData0[x_post], imageData0[x_post+4]);
|
||||
if(imageData[x] >= max0){
|
||||
var max2 = Math.max(imageData2[x_pre-4], imageData2[x_pre], imageData2[x_pre+4], imageData2[x-4], imageData2[x+4], imageData2[x_post-4], imageData2[x_post], imageData2[x_post+4]);
|
||||
if(imageData[x] >= max2)
|
||||
if (imageData[x] - avg_offset > area_average) {
|
||||
var max = Math.max(imageData[x_pre - 4], imageData[x_pre], imageData[x_pre + 4], imageData[x - 4], imageData[x + 4], imageData[x_post - 4], imageData[x_post], imageData[x_post + 4]);
|
||||
if (imageData[x] >= max) {
|
||||
var max0 = Math.max(imageData0[x_pre - 4], imageData0[x_pre], imageData0[x_pre + 4], imageData0[x - 4], imageData0[x + 4], imageData0[x_post - 4], imageData0[x_post], imageData0[x_post + 4]);
|
||||
if (imageData[x] >= max0) {
|
||||
var max2 = Math.max(imageData2[x_pre - 4], imageData2[x_pre], imageData2[x_pre + 4], imageData2[x - 4], imageData2[x + 4], imageData2[x_post - 4], imageData2[x_post], imageData2[x_post + 4]);
|
||||
if (imageData[x] >= max2){
|
||||
points.push({
|
||||
x: i + trim_details.left,
|
||||
y: j + trim_details.top,
|
||||
w: round(imageData[x] - area_average - avg_offset)
|
||||
});
|
||||
w: Math.round(imageData[x] - area_average - avg_offset)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,59 +120,64 @@ function SIFT_CLASS(){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//make unique
|
||||
for(var i=0; i<points.length; i++){
|
||||
for(var j=0; j<points.length; j++){
|
||||
if(i != j && points[i].x == points[j].x && points[i].y == points[j].y){
|
||||
points.splice(i, 1); i--;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
for (var j = 0; j < points.length; j++) {
|
||||
if (i != j && points[i].x == points[j].x && points[i].y == points[j].y) {
|
||||
points.splice(i, 1);
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//show points?
|
||||
if(show_points === true){
|
||||
var time = HELPER.timer('', true);
|
||||
log('key points: '+points.length+", "+time);
|
||||
LAYER.layer_add();
|
||||
|
||||
var size = 3;
|
||||
canvas_active().fillStyle = "#ff0000";
|
||||
for(var i in points){
|
||||
var point = points[i];
|
||||
canvas_active().beginPath();
|
||||
canvas_active().rect(point.x - Math.floor(size/2) + 1, point.y - Math.floor(size/2) + 1, size, size);
|
||||
canvas_active().fill();
|
||||
}
|
||||
}
|
||||
else{
|
||||
}
|
||||
|
||||
//show points?
|
||||
if (show_points === true) {
|
||||
var time = HELPER.timer('', true);
|
||||
log('key points: ' + points.length + ", " + time);
|
||||
LAYER.layer_add();
|
||||
|
||||
var size = 3;
|
||||
canvas_active().fillStyle = "#ff0000";
|
||||
for (var i in points) {
|
||||
var point = points[i];
|
||||
canvas_active().beginPath();
|
||||
canvas_active().rect(point.x - Math.floor(size / 2) + 1, point.y - Math.floor(size / 2) + 1, size, size);
|
||||
canvas_active().fill();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//sort by weights
|
||||
points.sort(function(a,b) { return parseFloat(b.w) - parseFloat(a.w); } );
|
||||
points.sort(function (a, b) {
|
||||
return parseFloat(b.w) - parseFloat(a.w);
|
||||
});
|
||||
return {
|
||||
points: points,
|
||||
trim_details: trim_details
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//returns average value of requested area from greyscale image
|
||||
//area = {x, y, w, h}
|
||||
this.get_area_average = function(area, imageData, i, j, size){
|
||||
this.get_area_average = function (area, imageData, i, j, size) {
|
||||
var imgData = imageData.data;
|
||||
var sum = 0;
|
||||
var n = 0;
|
||||
size = size / 100; //prepare to use 1-100% values
|
||||
var stop_x = i + Math.round(size*area.x) + Math.round(size*area.w);
|
||||
var stop_y = j + Math.round(size*area.y) + Math.round(size*area.h);
|
||||
var stop_x = i + Math.round(size * area.x) + Math.round(size * area.w);
|
||||
var stop_y = j + Math.round(size * area.y) + Math.round(size * area.h);
|
||||
var img_width4 = imageData.width * 4;
|
||||
var k0, k;
|
||||
for(var y = j + Math.round(size*area.y); y < stop_y; y++){
|
||||
for (var y = j + Math.round(size * area.y); y < stop_y; y++) {
|
||||
k0 = y * img_width4;
|
||||
for(var x = i + Math.round(size*area.x); x < stop_x; x++){
|
||||
for (var x = i + Math.round(size * area.x); x < stop_x; x++) {
|
||||
k = k0 + (x * 4);
|
||||
sum = sum + imgData[k];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return Math.round(sum/n);
|
||||
};
|
||||
}
|
||||
}
|
||||
return Math.round(sum / n);
|
||||
};
|
||||
}
|
||||
|
||||
198
libs/vintage.js
198
libs/vintage.js
@ -1,162 +1,179 @@
|
||||
/*
|
||||
author: ViliusL
|
||||
version: 1.1
|
||||
about: adds vintage effect, functions:
|
||||
adjust_color
|
||||
lower_contrast
|
||||
blur
|
||||
light_leak
|
||||
chemicals
|
||||
exposure
|
||||
grains
|
||||
grains_big
|
||||
optics
|
||||
dusts
|
||||
usage: VINTAGE.___function___(canvas_ctx, width, height, param1, param2);
|
||||
theory: Ken, http://stackoverflow.com/questions/13355119/vintage-ing-image-with-javascript/18862003#18862003
|
||||
libs: imagefilters.js, url: https://github.com/arahaya/ImageFilters.js
|
||||
glfx.js url: http://evanw.github.com/glfx.js/
|
||||
*/
|
||||
|
||||
/* global fx, ImageFilters, canvas_active */
|
||||
|
||||
var VINTAGE = new VINTAGE_CLASS();
|
||||
|
||||
function VINTAGE_CLASS(){
|
||||
/**
|
||||
* adds vintage effect
|
||||
*
|
||||
* @author ViliusL
|
||||
*
|
||||
* Functions:
|
||||
* - adjust_color
|
||||
* - lower_contrast
|
||||
* - blur
|
||||
* - light_leak
|
||||
* - chemicals
|
||||
* - exposure
|
||||
* - grains
|
||||
* - grains_big
|
||||
* - optics
|
||||
* - dusts
|
||||
*
|
||||
* Usage: VINTAGE.___function___(canvas_ctx, width, height, param1, param2, ...);
|
||||
*
|
||||
* libs:
|
||||
* - imagefilters.js, url: https://github.com/arahaya/ImageFilters.js
|
||||
* - glfx.js url: http://evanw.github.com/glfx.js/
|
||||
*/
|
||||
function VINTAGE_CLASS() {
|
||||
var fx_filter = fx.canvas();
|
||||
|
||||
|
||||
//increasing red color
|
||||
this.adjust_color = function(context, W, H, level_red){ //level = [0, 200], default 70
|
||||
this.adjust_color = function (context, W, H, level_red) { //level = [0, 200], default 70
|
||||
var param_green = 0;
|
||||
var param_blue = 0;
|
||||
var imageData = context.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.ColorTransformFilter(imageData, 1, 1, 1, 1, level_red, param_green, param_blue, 1);
|
||||
context.putImageData(filtered, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//decreasing contrast
|
||||
this.lower_contrast = function(context, W, H, level){ //level = [0, 50], default 15
|
||||
this.lower_contrast = function (context, W, H, level) { //level = [0, 50], default 15
|
||||
var imageData = context.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.BrightnessContrastPhotoshop(imageData, 0, -level);
|
||||
context.putImageData(filtered, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//adding blur
|
||||
this.blur = function(context, W, H, level){ //level = [0, 2], default 0
|
||||
if(level < 1) return context;
|
||||
this.blur = function (context, W, H, level) { //level = [0, 2], default 0
|
||||
if (level < 1)
|
||||
return context;
|
||||
var imageData = context.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.GaussianBlur(imageData, level);
|
||||
context.putImageData(filtered, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//creating transparent #ffa500 radial gradients
|
||||
this.light_leak = function(context, W, H, level){ //level = [0, 150], default 90
|
||||
this.light_leak = function (context, W, H, level) { //level = [0, 150], default 90
|
||||
var click_x = this.getRandomInt(0, W);
|
||||
var click_y = this.getRandomInt(0, H);
|
||||
var distance = Math.min(W, H) * 0.6;
|
||||
var radgrad = canvas_active().createRadialGradient(
|
||||
click_x, click_y, distance*level/255,
|
||||
click_x, click_y, distance * level / 255,
|
||||
click_x, click_y, distance);
|
||||
radgrad.addColorStop(0, "rgba(255, 165, 0, "+level/255+")");
|
||||
radgrad.addColorStop(0, "rgba(255, 165, 0, " + level / 255 + ")");
|
||||
radgrad.addColorStop(1, "rgba(255, 255, 255, 0)");
|
||||
|
||||
|
||||
context.fillStyle = radgrad;
|
||||
context.fillRect(0, 0, W, H);
|
||||
};
|
||||
};
|
||||
|
||||
//de-saturate
|
||||
this.chemicals = function(context, W, H, level){ //level = [0, 100], default 40
|
||||
this.chemicals = function (context, W, H, level) { //level = [0, 100], default 40
|
||||
var imageData = context.getImageData(0, 0, W, H);
|
||||
var filtered = ImageFilters.HSLAdjustment(imageData, 0, -level, 0);
|
||||
context.putImageData(filtered, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//creating transparent vertical black-to-white gradients
|
||||
this.exposure = function(context, W, H, level){ //level = [0, 150], default 80
|
||||
this.exposure = function (context, W, H, level) { //level = [0, 150], default 80
|
||||
context.rect(0, 0, W, H);
|
||||
var grd = canvas_active().createLinearGradient(0, 0, 0, H);
|
||||
if(this.getRandomInt(1, 10) < 5){
|
||||
if (this.getRandomInt(1, 10) < 5) {
|
||||
//dark at top
|
||||
grd.addColorStop(0, "rgba(0, 0, 0, "+level/255+")");
|
||||
grd.addColorStop(1, "rgba(255, 255, 255, "+level/255+")");
|
||||
}
|
||||
else{
|
||||
grd.addColorStop(0, "rgba(0, 0, 0, " + level / 255 + ")");
|
||||
grd.addColorStop(1, "rgba(255, 255, 255, " + level / 255 + ")");
|
||||
}
|
||||
else {
|
||||
//bright at top
|
||||
grd.addColorStop(0, "rgba(255, 255, 255, "+level/255+")");
|
||||
grd.addColorStop(1, "rgba(0, 0, 0, "+level/255+")");
|
||||
}
|
||||
grd.addColorStop(0, "rgba(255, 255, 255, " + level / 255 + ")");
|
||||
grd.addColorStop(1, "rgba(0, 0, 0, " + level / 255 + ")");
|
||||
}
|
||||
context.fillStyle = grd;
|
||||
context.fill();
|
||||
};
|
||||
};
|
||||
|
||||
//add grains, noise
|
||||
this.grains = function(context, W, H, level){ //level = [0, 50], default 10
|
||||
if(level == 0) return context;
|
||||
this.grains = function (context, W, H, level) { //level = [0, 50], default 10
|
||||
if (level == 0)
|
||||
return context;
|
||||
var img = context.getImageData(0, 0, W, H);
|
||||
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 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
|
||||
//increase it's lightness
|
||||
var delta = this.getRandomInt(0, level);
|
||||
if(delta == 0) continue;
|
||||
|
||||
if(imgData[x] - delta < 0)
|
||||
if (delta == 0)
|
||||
continue;
|
||||
|
||||
if (imgData[x] - delta < 0)
|
||||
imgData[x] = -(imgData[x] - delta);
|
||||
else
|
||||
imgData[x] = imgData[x] - delta;
|
||||
if(imgData[x+1] - delta < 0)
|
||||
imgData[x+1] = -(imgData[x+1] - delta);
|
||||
if (imgData[x + 1] - delta < 0)
|
||||
imgData[x + 1] = -(imgData[x + 1] - delta);
|
||||
else
|
||||
imgData[x+1] = imgData[x+1] - delta;
|
||||
if(imgData[x+2] - delta < 0)
|
||||
imgData[x+2] = -(imgData[x+2] - delta);
|
||||
imgData[x + 1] = imgData[x + 1] - delta;
|
||||
if (imgData[x + 2] - delta < 0)
|
||||
imgData[x + 2] = -(imgData[x + 2] - delta);
|
||||
else
|
||||
imgData[x+2] = imgData[x+2] - delta;
|
||||
}
|
||||
}
|
||||
imgData[x + 2] = imgData[x + 2] - delta;
|
||||
}
|
||||
}
|
||||
context.putImageData(img, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//add big grains, noise
|
||||
this.grains_big = function(context, W, H, level){ //level = [0, 50], default 20
|
||||
if(level == 0) return context;
|
||||
var n = W*H/100*level; //density
|
||||
this.grains_big = function (context, W, H, level) { //level = [0, 50], default 20
|
||||
if (level == 0)
|
||||
return context;
|
||||
var n = W * H / 100 * level; //density
|
||||
var color = 200;
|
||||
for(var i = 0; i < n; i++){
|
||||
var power = this.getRandomInt(5, 10+level);
|
||||
for (var i = 0; i < n; i++) {
|
||||
var power = this.getRandomInt(5, 10 + level);
|
||||
var size = 2;
|
||||
var x = this.getRandomInt(0, W);
|
||||
var y = this.getRandomInt(0, H);
|
||||
context.fillStyle = "rgba("+color+", "+color+", "+color+", "+power/255+")";
|
||||
context.fillStyle = "rgba(" + color + ", " + color + ", " + color + ", " + power / 255 + ")";
|
||||
context.fillRect(x, y, size, size);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//adding vignette effect - blured dark borders
|
||||
this.optics = function(context, W, H, param1, param2){ //param1 [0, 0.5], param2 [0, 0.7], default 0.3, 0.5
|
||||
this.optics = function (context, W, H, param1, param2) { //param1 [0, 0.5], param2 [0, 0.7], default 0.3, 0.5
|
||||
var texture = fx_filter.texture(context.getImageData(0, 0, W, H));
|
||||
fx_filter.draw(texture).vignette(param1, param2).update();
|
||||
context.drawImage(fx_filter, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
//add dust and hairs
|
||||
this.dusts = function(context, W, H, level){ //level = [0, 100], default 70
|
||||
this.dusts = function (context, W, H, level) { //level = [0, 100], default 70
|
||||
var n = level / 100 * (W * H) / 1000;
|
||||
//add dust
|
||||
context.fillStyle = "rgba(200, 200, 200, 0.3)";
|
||||
for(var i=0; i<n; i++){
|
||||
for (var i = 0; i < n; i++) {
|
||||
var x = this.getRandomInt(0, W);
|
||||
var y = this.getRandomInt(0, H);
|
||||
var mode = this.getRandomInt(1, 2);
|
||||
if(mode == 1){
|
||||
if (mode == 1) {
|
||||
var w = 1;
|
||||
var h = this.getRandomInt(1, 3);
|
||||
}
|
||||
else if(mode == 2){
|
||||
}
|
||||
else if (mode == 2) {
|
||||
var w = this.getRandomInt(1, 3);
|
||||
var h = 1;
|
||||
}
|
||||
}
|
||||
context.beginPath();
|
||||
context.rect(x, y, w, h);
|
||||
context.fill();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//add hairs
|
||||
context.strokeStyle = "rgba(200, 200, 200, 0.2)";
|
||||
for(var i=0; i<n/3; i++){
|
||||
for (var i = 0; i < n / 3; i++) {
|
||||
var x = this.getRandomInt(0, W);
|
||||
var y = this.getRandomInt(0, H);
|
||||
var radius = this.getRandomInt(5, 15);
|
||||
@ -166,12 +183,13 @@ function VINTAGE_CLASS(){
|
||||
context.beginPath();
|
||||
context.arc(x, y, radius, start_angle, end_angle);
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
};
|
||||
|
||||
//random number generator
|
||||
this.getRandomInt = function(min, max) {
|
||||
this.getRandomInt = function (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
//https://github.com/viliusle/Hermite-resize
|
||||
|
||||
onmessage = function (event){
|
||||
var img = event.data[0];
|
||||
var data = img.data;
|
||||
var W = event.data[1];
|
||||
var H = event.data[2];
|
||||
var W2 = event.data[3];
|
||||
var H2 = event.data[4];
|
||||
var core = event.data[5];
|
||||
var max_cores = event.data[6];
|
||||
var data2 = [];
|
||||
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);
|
||||
var start_row = Math.ceil(H2*core/max_cores)-1;
|
||||
if(start_row < 0) start_row = 0;
|
||||
var offset = Math.floor(H2*core/max_cores) * W2 * 4;
|
||||
|
||||
for(var j = start_row; j < start_row + Math.ceil(H2/max_cores); 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var x2 = (i + j*W2) * 4 - offset;
|
||||
data2[x2] = gx_r / weights;
|
||||
data2[x2 + 1] = gx_g / weights;
|
||||
data2[x2 + 2] = gx_b / weights;
|
||||
data2[x2 + 3] = gx_a / weights;
|
||||
}
|
||||
}
|
||||
postMessage({offset: offset, data: data2});
|
||||
};
|
||||
@ -8,13 +8,12 @@ body {
|
||||
color: #000000;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
padding-top: 25px;
|
||||
padding-top: 30px;
|
||||
background-color:#727272;
|
||||
font-weight: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
canvas{
|
||||
border:1px solid #808080;
|
||||
position: absolute;
|
||||
outline: none;
|
||||
/* disable select canvas */
|
||||
@ -25,14 +24,14 @@ canvas{
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: rgba(255, 255, 255, 0); /* mobile webkit */
|
||||
|
||||
|
||||
/* disable antialiasing */
|
||||
image-rendering: -moz-crisp-edges; /* Firefox */
|
||||
image-rendering: -o-crisp-edges; /* Opera */
|
||||
image-rendering: -webkit-optimize-contrast;/* Webkit (non-standard naming) */
|
||||
image-rendering: crisp-edges;
|
||||
-ms-interpolation-mode: nearest-neighbor; /* IE (non-standard property) */
|
||||
}
|
||||
}
|
||||
img{
|
||||
border: none;
|
||||
}
|
||||
@ -51,14 +50,14 @@ table{
|
||||
input[type="text"], input[type="button"], select, input[type="number"]{
|
||||
border:1px solid #393939;
|
||||
padding:1px 3px;
|
||||
}
|
||||
}
|
||||
input[type="range"]{
|
||||
margin-left:0px;
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
input[type="button"]:disabled {
|
||||
visibility:hidden;
|
||||
}
|
||||
}
|
||||
input[type="button"]{
|
||||
background: #dddddd;
|
||||
}
|
||||
@ -66,28 +65,32 @@ input[type="button"]{
|
||||
/* ==== ID ================================================================== */
|
||||
|
||||
#wrapper{
|
||||
margin:10px 5px 5px 5px;
|
||||
margin: 5px;
|
||||
position:relative;
|
||||
min-height: 500px;
|
||||
}
|
||||
}
|
||||
#sidebar_left{
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
#sidebar_right{
|
||||
position: absolute;
|
||||
width: 152px;
|
||||
right:0;
|
||||
top:0;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
#canvas_wrapper{
|
||||
position:relative;
|
||||
margin: 0 157px 0 105px;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 35px);
|
||||
}
|
||||
}
|
||||
#canvas_wrapper canvas{
|
||||
border: 1px solid #393939;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
#logo{
|
||||
display: block;
|
||||
height: 30px;
|
||||
@ -99,10 +102,10 @@ input[type="button"]{
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
#logo:hover{
|
||||
animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
|
||||
}
|
||||
}
|
||||
@keyframes shake {
|
||||
10%, 90% {
|
||||
background-position: 2px 0px;
|
||||
@ -121,10 +124,12 @@ input[type="button"]{
|
||||
border:1px solid #808080;
|
||||
position: absolute;
|
||||
margin-left:105px;
|
||||
}
|
||||
}
|
||||
#canvas_back{
|
||||
position: absolute;
|
||||
background-color:#ffffff;
|
||||
}
|
||||
outline: none;
|
||||
}
|
||||
#main_colour{
|
||||
border:1px solid #393939;
|
||||
background-color:#727272;
|
||||
@ -133,41 +138,41 @@ input[type="button"]{
|
||||
height:40px;
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
}
|
||||
#main_colour_alt{
|
||||
border:1px solid #393939;
|
||||
margin-top:10px;
|
||||
width:100%;
|
||||
height:40px;
|
||||
}
|
||||
}
|
||||
#main_colour_rgb{
|
||||
margin-top:5px;
|
||||
width:100%;
|
||||
color:#000000;
|
||||
text-align:right;
|
||||
}
|
||||
}
|
||||
#main_colour_rgb input{
|
||||
width:35px;
|
||||
}
|
||||
}
|
||||
#preview{
|
||||
width:150px;
|
||||
height:150px;
|
||||
background-color:#989898;
|
||||
border:1px solid #393939;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
#preview canvas{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
#layers_base{
|
||||
background-color: #989898;
|
||||
border: 1px solid #393939;
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
#menu_left_container .active{
|
||||
background-color: #5680c1 !important;
|
||||
}
|
||||
}
|
||||
#menu_left_container a{
|
||||
float:left;
|
||||
border: 1px solid #393939;
|
||||
@ -177,20 +182,20 @@ input[type="button"]{
|
||||
margin:0px 1px 1px 0px;
|
||||
overflow:hidden;
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
#action_attributes{
|
||||
min-height:20px;
|
||||
font-size:11px;
|
||||
}
|
||||
}
|
||||
#info{
|
||||
padding:5px 3px 5px 2px;
|
||||
min-height:57px;
|
||||
font-size:11px;
|
||||
}
|
||||
}
|
||||
#action_attributes input{
|
||||
font-size:11px;
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
#popup{
|
||||
position:fixed;
|
||||
border:1px solid #000000;
|
||||
@ -206,29 +211,30 @@ input[type="button"]{
|
||||
padding:10px;
|
||||
font-size:12px;
|
||||
color: #333;
|
||||
}
|
||||
z-index: 100;
|
||||
}
|
||||
#popup h2{
|
||||
margin-top:0px;
|
||||
cursor:move;
|
||||
}
|
||||
}
|
||||
#popup td{
|
||||
height:20px;
|
||||
}
|
||||
}
|
||||
#popup textarea{
|
||||
color:#000000;
|
||||
width:100%;
|
||||
border:1px solid #393939;
|
||||
padding-left:5px;
|
||||
}
|
||||
}
|
||||
#popup .button{
|
||||
margin-right:5px;
|
||||
background-color:#5680c1;
|
||||
width:60px;
|
||||
height:25px;
|
||||
}
|
||||
}
|
||||
#popup input[type="text"], #popup input[type="number"], #popup textarea{
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
#resize-w, #resize-h, #resize-wh{
|
||||
background-color:#393939;
|
||||
width:5px;
|
||||
@ -236,22 +242,18 @@ input[type="button"]{
|
||||
margin-left:105px;
|
||||
position:absolute;
|
||||
top:0;
|
||||
}
|
||||
}
|
||||
#color_hex{
|
||||
width: 100%;
|
||||
border:1px solid #393939;
|
||||
}
|
||||
#canvas_grid{
|
||||
display:none;
|
||||
pointer-events:none;
|
||||
}
|
||||
#all_colors{
|
||||
margin-top:10px;
|
||||
padding:3px 0px 3px 3px;
|
||||
}
|
||||
#canvas_front{
|
||||
position:relative;
|
||||
}
|
||||
|
||||
/* ==== classes ============================================================= */
|
||||
|
||||
@ -260,7 +262,7 @@ input[type="button"]{
|
||||
padding:5px;
|
||||
margin-top:5px;
|
||||
background-color:#818181;
|
||||
}
|
||||
}
|
||||
.layer{
|
||||
margin-bottom:2px;
|
||||
border:1px solid #393939;
|
||||
@ -271,7 +273,7 @@ input[type="button"]{
|
||||
height:19px;
|
||||
overflow:hidden;
|
||||
color:#333333;
|
||||
}
|
||||
}
|
||||
.layers_arrow{
|
||||
text-decoration:none;
|
||||
color:#000000;
|
||||
@ -282,7 +284,7 @@ input[type="button"]{
|
||||
padding:0px 5px 0px 5px;
|
||||
border:1px solid #393939;
|
||||
font-size:11px;
|
||||
}
|
||||
}
|
||||
.layer_title{
|
||||
display:block;
|
||||
float:left;
|
||||
@ -290,10 +292,10 @@ input[type="button"]{
|
||||
min-width:85px;
|
||||
width:10px;
|
||||
overflow:hidden;
|
||||
}
|
||||
}
|
||||
#layers_base .active{
|
||||
background-color:#5680c1;
|
||||
}
|
||||
}
|
||||
.layer_delete{
|
||||
float:right;
|
||||
cursor:pointer;
|
||||
@ -301,7 +303,7 @@ input[type="button"]{
|
||||
width:12px;
|
||||
height:12px;
|
||||
background: url('../img/all.png') no-repeat 0px -50px;
|
||||
}
|
||||
}
|
||||
.layer_visible{
|
||||
float:right;
|
||||
cursor:pointer;
|
||||
@ -309,31 +311,31 @@ input[type="button"]{
|
||||
width:12px;
|
||||
height:12px;
|
||||
background: url('../img/all.png') no-repeat -100px -50px;
|
||||
}
|
||||
}
|
||||
.layer_unvisible{
|
||||
background: url('../img/all.png') no-repeat -50px -50px;
|
||||
}
|
||||
}
|
||||
.layer_add{
|
||||
border:1px solid #393939;
|
||||
padding:0px 4px 0px 4px;
|
||||
text-decoration:none;
|
||||
background-color:#5680c1;
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
.mini-color{
|
||||
width:16px;
|
||||
height:16px;
|
||||
margin:0px 3px 3px 0px;
|
||||
float:left;
|
||||
border:1px solid #393939;
|
||||
}
|
||||
}
|
||||
.mini-color:hover{
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
.attribute-title{
|
||||
text-align:center;
|
||||
font-weight:bold;
|
||||
}
|
||||
}
|
||||
.attribute-area{
|
||||
border:1px solid #393939;
|
||||
background-color:#989898;
|
||||
@ -344,7 +346,7 @@ input[type="button"]{
|
||||
/* disable select */
|
||||
-webkit-user-select:none;
|
||||
-moz-user-select:none;
|
||||
}
|
||||
}
|
||||
.error{
|
||||
padding:20px;
|
||||
margin:10px;
|
||||
@ -352,12 +354,12 @@ input[type="button"]{
|
||||
background-color:#ffffff;
|
||||
width:400px;
|
||||
font-weight:bold;
|
||||
}
|
||||
}
|
||||
.group{
|
||||
border:1px solid #888888;
|
||||
margin:5px 0px 5px 0px;
|
||||
padding:5px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== menu ================================================================ */
|
||||
|
||||
@ -371,43 +373,44 @@ input[type="button"]{
|
||||
background: #2D2D2D;
|
||||
width: 100%;
|
||||
padding-left:10px;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul{
|
||||
z-index:100;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li{
|
||||
position: relative;
|
||||
display: inline;
|
||||
float: left;
|
||||
color: #2d2b2b;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li .rightarrowclass{
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li ul li .rightarrowclass{
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li a{
|
||||
display: block;
|
||||
color: #2D2D2D;
|
||||
padding: 8px 10px;
|
||||
padding: 7px 10px 0 10px;
|
||||
text-decoration: none;
|
||||
color: #cccccc;
|
||||
}
|
||||
height:30px;
|
||||
}
|
||||
.ddsmoothmenu ul li a.selected {
|
||||
background: #FFFFFF !important;
|
||||
color: #2d2b2b;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li ul li a.selected {
|
||||
background-color:#E4EBF8 !important;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li a:hover{
|
||||
background: #E4EBF8;
|
||||
color: #2D2D2D;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu .hide_ul{
|
||||
position: absolute;
|
||||
left: -3000px;
|
||||
@ -415,7 +418,7 @@ input[type="button"]{
|
||||
visibility: hidden;
|
||||
border:1px solid #5680C1;
|
||||
border-top:0px;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li ul{
|
||||
position: absolute;
|
||||
left: -3000px;
|
||||
@ -423,32 +426,34 @@ input[type="button"]{
|
||||
visibility: hidden;
|
||||
border:1px solid #5680C1;
|
||||
border-top:0px;
|
||||
}
|
||||
margin-left: -1px;
|
||||
}
|
||||
.ddsmoothmenu ul li ul li{
|
||||
display: list-item;
|
||||
background: #ffffff;
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li ul li ul{
|
||||
top: 0;
|
||||
border-top:1px solid #5680C1;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu ul li ul li a{
|
||||
padding: 4px 5px 4px 5px;
|
||||
padding-left: 5px;
|
||||
padding-right:5px;
|
||||
margin: 0;
|
||||
color: #2D2D2D;
|
||||
}
|
||||
}
|
||||
* html .ddsmoothmenu{height: 1%;} /*Hack for IE7 and below*/
|
||||
.downarrowclass{
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 7px;
|
||||
}
|
||||
}
|
||||
.rightarrowclass{
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 5px;
|
||||
}
|
||||
}
|
||||
.ddshadow{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@ -456,13 +461,13 @@ input[type="button"]{
|
||||
width: 0;
|
||||
height: 0;
|
||||
background-color: #ccc;
|
||||
}
|
||||
}
|
||||
.ddsmoothmenu .mid-line{
|
||||
background-color:#ff0000;
|
||||
border-top:1px solid #e5e5e5;
|
||||
font-size:0;
|
||||
padding:0 8px 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==== print =============================================================== */
|
||||
|
||||
@ -490,11 +495,11 @@ input[type="button"]{
|
||||
#canvas_wrapper{
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
}
|
||||
}
|
||||
canvas{
|
||||
border:0px;
|
||||
position: absolute;
|
||||
top:0px;
|
||||
left:0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user