diff --git a/index.html b/index.html index 1f3e0fa..a1abe68 100644 --- a/index.html +++ b/index.html @@ -39,16 +39,23 @@ - -
-
-
-
- -
- Your browser does not support canvas or JavaScript is not enabled. -
-
+ + +
+ + + + +
+
+
+
+ +
+ Your browser does not support canvas or JavaScript is not enabled. +
+
+
diff --git a/src/css/layout.css b/src/css/layout.css index 198ca81..28f7bd0 100644 --- a/src/css/layout.css +++ b/src/css/layout.css @@ -527,15 +527,41 @@ body .sp-preview{ /* ========== content ======================================================= */ -.main_wrapper{ +.ruler_left{ + display: none; + position: absolute; + left:0; + top: 20px; + background-color: #ccc; +} +.ruler_top{ + display: none; + position: absolute; + left: 20px; + top:0; + background-color: #ccc; +} +.middle_area{ + position: relative; -ms-grid-row: 2; -ms-grid-column: 2; grid-area: main; +} +.main_wrapper{ + position:absolute; + top:0; + right:0; + bottom:0; + left:0; overflow: hidden; display: flex; justify-content: center; align-items: center; } +.middle_area.has-ruler .main_wrapper{ + top: 20px; + left: 20px; +} .canvas_wrapper{ position:relative; } diff --git a/src/js/config-menu.js b/src/js/config-menu.js index 1094064..56b0536 100644 --- a/src/js/config-menu.js +++ b/src/js/config-menu.js @@ -183,6 +183,10 @@ const menuDefinition = [ } ] }, + { + name: 'Ruler', + target: 'view/ruler.ruler' + }, { divider: true }, diff --git a/src/js/config.js b/src/js/config.js index 127d606..f99f5b9 100644 --- a/src/js/config.js +++ b/src/js/config.js @@ -24,6 +24,7 @@ config.swatches = { }; config.guides_enabled = true; config.guides = []; +config.ruler_active = false; //requires styles in reset.css config.themes = [ diff --git a/src/js/core/base-layers.js b/src/js/core/base-layers.js index bc67e73..0869ba8 100644 --- a/src/js/core/base-layers.js +++ b/src/js/core/base-layers.js @@ -8,6 +8,7 @@ import config from './../config.js'; import Base_gui_class from './base-gui.js'; import Base_selection_class from './base-selection.js'; import Image_trim_class from './../modules/image/trim.js'; +import View_ruler_class from './../modules/view/ruler.js'; import zoomView from './../libs/zoomView.js'; import Helper_class from './../libs/helpers.js'; import alertify from './../../../node_modules/alertifyjs/build/alertify.min.js'; @@ -53,6 +54,7 @@ class Base_layers_class { this.Base_gui = new Base_gui_class(); this.Helper = new Helper_class(); this.Image_trim = new Image_trim_class(); + this.View_ruler = new View_ruler_class(); this.canvas = document.getElementById('canvas_minipaint'); this.ctx = document.getElementById('canvas_minipaint').getContext("2d"); @@ -185,6 +187,7 @@ class Base_layers_class { this.last_zoom = config.ZOOM; this.Base_gui.GUI_details.render_details(); + this.View_ruler.render_ruler(); if(this.render_success === false){ alertify.error('Rendered with errors.'); diff --git a/src/js/modules/help/shortcuts.js b/src/js/modules/help/shortcuts.js index 3bcd6ff..b2f7aac 100644 --- a/src/js/modules/help/shortcuts.js +++ b/src/js/modules/help/shortcuts.js @@ -22,6 +22,7 @@ class Help_shortcuts_class { {title: "N", value: 'New layer'}, {title: "R", value: 'Resize'}, {title: "I", value: 'Information'}, + {title: "U", value: 'Ruler'}, {title: "Scroll up", value: 'Zoom in'}, {title: "Scroll down", value: 'Zoom out'}, {title: "CTRL + Z", value: 'Undo'}, diff --git a/src/js/modules/view/ruler.js b/src/js/modules/view/ruler.js new file mode 100644 index 0000000..94baae5 --- /dev/null +++ b/src/js/modules/view/ruler.js @@ -0,0 +1,183 @@ +import config from './../../config.js'; +import Helper_class from './../../libs/helpers.js'; +import Base_gui_class from './../../core/base-gui.js'; +import Base_layers_class from './../../core/base-layers.js'; + +var instance = null; + +class View_ruler_class { + + constructor() { + //singleton + if (instance) { + return instance; + } + instance = this; + + this.GUI = new Base_gui_class(); + this.Base_layers = new Base_layers_class(); + this.Helper = new Helper_class(); + + this.set_events(); + } + + set_events() { + var _this = this; + + window.addEventListener('resize', function (event) { + //resize + _this.prepare_ruler(); + _this.render_ruler(); + }, false); + document.addEventListener('keydown', (event) => { + var code = event.code; + if (this.Helper.is_input(event.target)) + return; + + if (event.code == "KeyU" && event.ctrlKey != true && event.metaKey != true) { + //G - grid + _this.ruler(); + event.preventDefault(); + } + }, false); + } + + ruler() { + var ruler_left = document.getElementById('ruler_left'); + var ruler_top = document.getElementById('ruler_top'); + var middle_area = document.getElementById('middle_area'); + + if(config.ruler_active == false){ + //activate + config.ruler_active = true; + document.getElementById('middle_area').classList.add('has-ruler'); + ruler_left.style.display = 'block'; + ruler_top.style.display = 'block'; + + this.prepare_ruler(); + this.render_ruler(); + } + else{ + //deactivate + config.ruler_active = false; + document.getElementById('middle_area').classList.remove('has-ruler'); + ruler_left.style.display = 'none'; + ruler_top.style.display = 'none'; + } + + this.GUI.prepare_canvas(); + + config.need_render = true; + } + + prepare_ruler(){ + if(config.ruler_active == false) + return; + + var ruler_left = document.getElementById('ruler_left'); + var ruler_top = document.getElementById('ruler_top'); + var middle_area = document.getElementById('middle_area'); + + var middle_area_width = middle_area.clientWidth; + var middle_area_height = middle_area.clientHeight; + + ruler_left.width = 15; + ruler_left.height = middle_area_height - 20; + + ruler_top.width = middle_area_width - 20; + ruler_top.height = 15; + } + + render_ruler(){ + if(config.ruler_active == false) + return; + + var ruler_left = document.getElementById('ruler_left'); + var ruler_top = document.getElementById('ruler_top'); + + var ctx_left = ruler_left.getContext("2d"); + var ctx_top = ruler_top.getContext("2d"); + + var color = '#111'; + var size = 15; + + //calc step + var step = Math.ceil(10 * config.ZOOM); + while (step < 5) { + step = step * 2; + } + while (step > 10) { + step = Math.ceil(step / 2); + } + var step_big = step * 10; + + //calc begin/end point + var begin_x = Math.max(0, ruler_top.width / 2 - config.WIDTH * config.ZOOM / 2); + var begin_y = Math.max(0, ruler_left.height / 2 - config.HEIGHT * config.ZOOM / 2); + + var end_x = Math.min(ruler_top.width, ruler_top.width / 2 + config.WIDTH * config.ZOOM / 2); + var end_y = Math.min(ruler_left.height, ruler_left.height / 2 + config.HEIGHT * config.ZOOM / 2); + + //left + ctx_left.strokeStyle = color; + ctx_left.lineWidth = 1; + ctx_left.font = "11px Arial"; + + ctx_left.clearRect(0, 0, ruler_left.width, ruler_left.height); + + ctx_left.beginPath(); + for (var i = begin_y; i < end_y; i += step) { + ctx_left.moveTo(10, i + 0.5); + ctx_left.lineTo(size, i + 0.5); + } + ctx_left.stroke(); + + ctx_left.beginPath(); + for (var i = begin_y; i <= end_y; i += step_big) { + ctx_left.moveTo(0, i + 0.5); + ctx_left.lineTo(size, i + 0.5); + + var global_pos = this.Base_layers.get_world_coords(0, i - begin_y); + var text = Math.ceil(global_pos.y).toString(); + + //text + for (var j = 0; j < text.length; j++) { + var letter = text.charAt(j); + var line_height = 10; + ctx_left.fillText(letter, 1, i + 11 + j * line_height); + } + } + ctx_left.stroke(); + + //top + ctx_top.strokeStyle = color; + ctx_top.lineWidth = 1; + ctx_top.font = "11px Arial"; + + ctx_top.clearRect(0, 0, ruler_top.width, ruler_top.height); + + ctx_top.beginPath(); + for (var i = begin_x; i < end_x; i += step) { + var y = (i / step_big == parseInt(i / step_big)) ? 0 : step; + ctx_top.moveTo(i + 0.5, 10); + ctx_top.lineTo(i + 0.5, size); + } + ctx_top.stroke(); + + ctx_top.beginPath(); + for (var i = begin_x; i <= end_x; i += step_big) { + ctx_top.moveTo(i + 0.5, 0); + ctx_top.lineTo(i + 0.5, size); + + var global_pos = this.Base_layers.get_world_coords(i - begin_x, 0); + var text = Math.ceil(global_pos.x).toString(); + + //text + ctx_top.fillText(text, i + 3, 9); + } + ctx_top.stroke(); + } + +} + +export default View_ruler_class;