diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..132a69b --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +Kanvas.apache2.conf +PHP/Kanvas.Secrets.php +Public/es +Public/dev +Public/index.html +Public/data +Data \ No newline at end of file diff --git a/Artbook/Kanvas.svg b/Artbook/Kanvas.svg new file mode 100755 index 0000000..1141f2a --- /dev/null +++ b/Artbook/Kanvas.svg @@ -0,0 +1,72 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/Artbook/Kanvas.xcf b/Artbook/Kanvas.xcf new file mode 100755 index 0000000..85d5f58 Binary files /dev/null and b/Artbook/Kanvas.xcf differ diff --git a/HTML/base.kanvas.html b/HTML/base.kanvas.html new file mode 100755 index 0000000..8f5161c --- /dev/null +++ b/HTML/base.kanvas.html @@ -0,0 +1,175 @@ + + + + {title} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

+ + + + Kanvas + + Kanvas + +

+ +
+
+
+ Menu + + +
+
+ Content +
{content}
+
+
+ Files + + +
+
+ + + diff --git a/JSON/html.files.json b/JSON/html.files.json new file mode 100755 index 0000000..ba6b588 --- /dev/null +++ b/JSON/html.files.json @@ -0,0 +1 @@ +{"files":["\/mnt\/d\/git\/Kanvas\/Public\/dev\/ECMAScript\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/PHP\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/Kanvas.ecma.js.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/wmd.php.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/Public\/wmd_scripts.php.html","\/mnt\/d\/git\/Kanvas\/Public\/dev\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.idea.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.quality.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.settings.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.starting.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.targets.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/index.html"],"directories":["\/JSON","\/dev","\/dev\/ECMAScript","\/dev\/PHP","\/dev\/Public","\/es","\/es\/doc"]} \ No newline at end of file diff --git a/Public/.htaccess b/Public/.htaccess new file mode 100755 index 0000000..81d9bac --- /dev/null +++ b/Public/.htaccess @@ -0,0 +1 @@ +Header set Access-Control-Allow-Origin "*" diff --git a/Public/ecma/version/20230707/Kanvas.ecma.js b/Public/ecma/version/20230707/Kanvas.ecma.js new file mode 100644 index 0000000..144f9e9 --- /dev/null +++ b/Public/ecma/version/20230707/Kanvas.ecma.js @@ -0,0 +1,747 @@ +Kanvas = function(settings){ + + const self = this, + default_settings = { + nulls : false, + default_value : null, + position : ".kanvas", + preload_timeout : 2000, + frames_per_second : 60, + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 40, + swap_and_drop_timer : 5000, + font_size : 1, + font_family : "Arial", + settings_overwrite : false, + autostart : true, + autobuild : true, + font_minimum_size : 12, + events_cache_timer : 100 + }, + custom = {}, + cache = {}, + frames_times = [], + id_length = 11, + id_alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + ids = [], + threads = [], + number_of_cells = {x : 0, y : 0}, + events_cache = []; + let thread = null, + frames_per_second = null, + canvas, context, + last_frame_time = 0, frames_times_summatory = 0, + swap_and_drop_timer, + cache_box, + default_font_size, default_font_family, + settings_overwrite, + built = false, + started = false, + font_minimum_size, + events_cache_timer; + + this.map = []; + let cells = this.cells; + let cell_size = this.cell_size; + let quality = this.quality; + let quality_x = this.quality_x; + let quality_y = this.quality_y; + this.cells_x = 0; + this.cells_y = 0; + this.delta_time = 0; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + + this.Event = function(){ + + const self = this, + events = [], + properties = []; + + const construct = () => { + + events_cache.push(autoclean); + + }; + + this.execute = (callback, ...arguments) => events.forEach((event, i) => ( + event && + (typeof callback == "function" ? callback(properties[i]) : true) && + event(...arguments) + )); + + this.add = (callback, own_properties) => { + + let i = 0; + const l = events.length; + + for(; i < l; i ++) + if(!events[i]) + break; + + events[i] = callback; + properties[i] = own_properties; + + return i; + }; + + this.remove = i => events[i] = null; + + const autoclean = () => { + + const date = Date.now(); + + properties.forEach((own_properties, i) => { + if(own_properties && own_properties.last_used && date - own_properties.last_used > events_cache_timer){ + events[i] = null; + properties[i] = null; + }; + }); + + }; + + this.update = (i, date) => events[i] && (properties[i].last_used = date); + + construct(); + + }; + + this.on_screen_change = new this.Event(); + this.on_ready = new this.Event(); + this.on_click = new this.Event(); + this.on_click_down = new this.Event(); + this.on_click_up = new this.Event(); + this.on_key_down = new this.Event(); + this.on_key_up = new this.Event(); + + const construct = () => { + + settings = ( + settings instanceof Array ? settings : + typeof settings == "object" ? [settings] : + []).filter(inputs => typeof inputs == "object" && !(inputs instanceof Array)); + + self.settings("autostart") && self.start(); + + }; + + this.start = callback => { + + const end = status => typeof callback == "function" && callback(status); + + if(started){ + end(false); + return false; + }; + started = true; + + settings_overwrite = self.settings(["settings_overwrite", "overwrite"]); + frames_per_second = self.settings(["frames_per_second", "fps"]); + events_cache_timer = self.settings("events_cache_timer"); + object_name = self.object_name = self.settings("object_name"); + + thread = setInterval(execute, 1000 / frames_per_second); + + if(self.settings("autobuild")) + self.build(callback); + else + end(true); + + return true; + }; + + this.build = callback => { + + const position = self.settings("position"), + end = status => typeof callback == "function" && callback(status); + + if(built){ + end(false); + return false; + }; + built = true; + + if(position){ + + if(position.tagName || position.nodeName){ + end_build(position); + end(true); + return; + }; + + if(typeof position != "string"){ + console.error("position_not_string"); + end(false); + return; + }; + + if(!position.trim()){ + console.error("position_selector_empty"); + end(false); + return; + }; + + let html_object; + + try{ + if(html_object = document.querySelector(position)){ + end_build(html_object); + end(true); + return; + }; + }catch(exception){ + console.error(exception); + console.error("position_bad_selector"); + end(false); + return; + }; + + const date = Date.now(), + timeout = self.settings("preload_timeout"); + let interval = setInterval(() => { + if(html_object = document.querySelector(position)){ + clearInterval(interval); + end_build(html_object); + end(true); + }else if(Date.now() - date > timeout){ + clearInterval(interval); + console.error("position_timeout"); + end(false); + }; + }, frames_per_second); + + }else{ + console.error("no_position"); + end(false); + }; + + return true; + }; + + const end_build = position => { + + quality = self.quality = self.settings("quality"); + quality_x = self.quality_x = self.settings("quality_x"); + quality_y = self.quality_y = self.settings("quality_y"); + cells = self.cells = self.settings("cells"); + default_font_size = self.settings("font_size"); + default_font_family = self.settings("font_family"); + + cache.quality = 0; + cache.quality_x = 0; + cache.quality_y = 0; + + cache.screen = {x : 0, y : 0}; + cache.origin = {x : 0, y : 0}; + + item_self = self.item_self = (position || document.querySelector("body")).appendChild(document.createElement("div")); + cache_box = item_self.appendChild(document.createElement("div")); + canvas = item_self.appendChild(document.createElement("canvas")); + hash_self = self.hash_self = self.settings(["id", "hash"]) || self.create_id(); + + item_self.setAttribute("id", hash_self); + item_self.setAttribute("class", ["kanvas", hash_self].concat((self.settings("class") || "").split(/\s+/)).filter((key, i, array) => array.indexOf(key) == i).join(" ")); + item_self.setAttribute("data-hash", hash_self); + item_self.setAttribute("data-cells", cells); + item_self.setAttribute("data-minimum-font-size", font_minimum_size = self.settings("font_minimum_size")); + + cache_box.setAttribute("class", "kanvas-cache-box"); + cache_box.setAttribute("style", ` + position : absolute; + top : 0%; + left : 0%; + width : 100%; + height : 100%; + visibility : hidden; + z-index : 10; + opacity : 0; + `.replace(/[\r\n\s]+/g, "")); + + canvas.setAttribute("class", "kanvas-ui"); + canvas.setAttribute("style", ` + position : absolute; + top : 0%; + left : 0%; + width : 100%; + height : 100%; + z-index : 20; + `.replace(/[\r\n\s]+/g, "")); + canvas.onclick = event => on_click(canvas, event, "click"); + canvas.onmousedown = event => on_click(canvas, event, "down"); + canvas.onmouseup = event => on_click(canvas, event, "up"); + canvas.onkeydown = event => on_key(canvas, event, "down"); + canvas.onkeyup = event => on_key(canvas, event, "up"); + + context = canvas.getContext("2d"); + + context.id = self.create_id(); + + swap_and_drop_timer = self.settings("swap_and_drop_timer"); + + self.on_ready.execute(); + + }; + + this.nulls = nulls => typeof nulls == "boolean" ? nulls : self.settings("nulls", null, false, false); + + this.default_value = (_default, nulls) => _default !== undefined && (self.nulls(nulls) || _default !== null) ? _default : self.settings("default_value", null, null, true); + + this.settings = (names, inputs, _default, nulls) => { + + const l = (names = ( + names instanceof Array ? names : + typeof names == "string" ? [names] : + [] + ).filter((name, i, array) => name && typeof name == "string" && array.indexOf(name) == i)).length; + + if(l){ + + const m = (inputs = ( + inputs instanceof Array ? inputs : + typeof inputs == "object" ? [inputs] : + []).concat(settings, custom, [default_settings])).length; + + nulls = self.nulls(nulls); + + for(let j = 0; j < m; j ++) + if(inputs[j] && typeof inputs[j] == "object" && !(inputs[j] instanceof Array)) + for(let i = 0; i < l; i ++) + if(inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + }; + return self.default_value(_default, nulls); + }; + + this.settings_add = (inputs, overwrite) => { + if(!inputs) + return; + + if(typeof inputs == "string"){ + try{ + inputs = JSON.parse(inputs); + }catch(exception){}; + }; + + if(typeof inputs == "object"){ + if(inputs instanceof Array) + inputs.forEach(inputs, overwrite); + else{ + typeof overwrite != "boolean" && (overwrite = settings_overwrite); + for(const key in inputs) + if(overwrite || custom[key] === undefined) + custom[key] = inputs[key]; + }; + }; + + }; + + this.create_id = () => { + + let id; + const l = id_alphabet.length; + + do{ + id = ""; + while((id += id_alphabet[l * Math.random() >> 0]).length < id_length); + }while( + ids.includes(id) || + !/^[a-z]/i.test(id) || + document.querySelector("." + id + ",#" + id + ",[name=" + id + "]") + ); + ids.push(id); + + return id; + }; + + const execute = () => { + + const date = Date.now(); + let screen_changed = false; + + if(item_self && (cache.screen.x != item_self.offsetWidth || cache.screen.y != item_self.offsetHeight)){ + screen_changed = true; + + cache.screen.x = item_self.offsetWidth; + cache.screen.y = item_self.offsetHeight; + + const font_size = cache.screen[cache.screen.x < cache.screen.y ? "x" : "y"] / cells; + + item_self.style.fontSize = (font_size < font_minimum_size ? font_minimum_size : font_size) + "px"; + + }; + + if(canvas){ + + if(last_frame_time){ + + const frame_time = date - last_frame_time; + + frames_times.push(frame_time); + frames_times_summatory += frame_time; + + self.delta_time = frame_time / 1000; + + while(frames_times.length > frames_per_second) + frames_times_summatory -= frames_times.shift(); + + }; + + last_frame_time = date; + + if(screen_changed || cache.quality != quality){ + + const width = cache.screen.x * quality, + height = cache.screen.y * quality; + + cache.quality = quality; + canvas.setAttribute("width", width); + canvas.setAttribute("height", height); + cache.origin.x = width / 2; + cache.origin.y = height / 2; + + cell_size = self.cell_size = (width > height ? height : width) / cells; + + number_of_cells.x = width / cell_size; + number_of_cells.y = height / cell_size; + + this.cells_x = number_of_cells.x / 2; + this.cells_y = number_of_cells.y / 2; + + for(const key in cache) + if(cache[key] && cache[key].data) + cache[key].data = null; + + self.on_screen_change.execute(); + + }; + + }; + + threads.forEach(thread => thread && thread()); + + if(canvas){ + + context.beginPath(); + context.clearRect(0, 0, cache.screen.x * quality, cache.screen.y * quality); + context.translate(cache.origin.x, cache.origin.y); + + draw(context, self.map, 0, 0); + + context.translate(-cache.origin.x, -cache.origin.y); + + for(const key in cache) + if(cache[key] && cache[key].last_used && date - cache[key].last_used > swap_and_drop_timer) + delete cache[key]; + + }; + + events_cache.forEach(autoclean => autoclean()); + + }; + + this.set_quality = new_quality => quality = self.quality = new_quality; + this.set_quality_x = new_quality => quality_x = self.quality_x = new_quality; + this.set_quality_y = new_quality => quality_y = self.quality_y = new_quality; + + const _x = x => x * cell_size; + const _y = y => y * cell_size; + const size = size => size * cell_size; + + const set_cache = (context, status) => { + + !status && cache[context.id] && cache[context.id].ok && (cache[context.id].ok = false); + + return status; + }; + + const set_border = (context, inputs) => { + + const has_border = !!(inputs.border_color || !isNaN(inputs.border_width)); + + inputs.border_color && (context.strokeStyle = inputs.border_color); + !isNaN(inputs.border_width) && (context.lineWidth = size(inputs.border_width)); + + return has_border; + }; + + const set_background = (context, inputs) => { + + const has_background = !!(inputs.background || (!inputs.border_color && isNaN(inputs.border_width))); + + if(inputs.background){ + if(inputs.background instanceof Array){ + + const v = inputs.background, + is_linear = v.length == 5, + gradient = ( + is_linear ? context.createLinearGradient(_x(v[0]), _y(v[1]), _x(v[2]), _y(v[3])) : + context.createRadialGradient(_x(v[0]), _y(v[1]), _x(v[2]), _y(v[3]), size(v[4]), size(v[5])) + ); + + inputs.background[is_linear ? 4 : 6].forEach(color => gradient.addColorStop(color[0], color[1])); + + context.fillStyle = gradient; + + }else + context.fillStyle = inputs.background; + }; + + return has_background; + }; + + const set_shadow = (context, inputs, shape_callback) => { + + const shadows = inputs.shadow || inputs.shadows; + + (shadows && shadows.length ? shadows[0] instanceof Array ? shadows : [shadows] : []).forEach(shadow => { + [context.shadowOffsetX, context.shadowOffsetY, context.shadowBlur, context.shadowColor] = shadow; + context.shadowOffsetX = size(shadow[0]); + context.shadowOffsetY = size(shadow[1]); + context.shadowBlur = size(shadow[2]); + context.shadowColor = size(shadow[3]); + shape_callback(); + }); + + }; + + const shapes = { + rectangle : (context, inputs) => { + + const x = _x(inputs.x), + y = _y(inputs.y), + width = size(inputs.width), + height = size(inputs.height), + has_border = set_border(context, inputs), + has_background = set_background(context, inputs); + + set_shadow(context, inputs, () => context.rect(x, y, width, height)); + has_background && context.fillRect(x, y, width, height); + has_border && context.strokeRect(x, y, width, height); + + return set_cache(context, true); + }, + image : (context, inputs) => { + + const url = inputs.url; + + if(url){ + + const cached = cache[url]; + + if(!cached){ + (cache[url] = { + image : new Image(), + loaded : false, + last_used : Date.now() + }).image.src = url; + cache[url].image.crossOrigin = "anonymous"; + cache[url].image.onload = () => cache[url].loaded = true; + return set_cache(context, false); + }; + + if(cached.loaded){ + + let width = inputs.width, + height = inputs.height; + const cut_x = inputs.cut_x || 0, + cut_y = inputs.cut_y || 0, + cut_width = inputs.cut_width || 0, + cut_height = inputs.cut_height || 0, + position_x = inputs.x || 0, + position_y = inputs.y || 0, + x = _x(position_x), + y = _y(position_y), + end_width = size(width), + end_height = size(height); + + !width && (width = cache.quality * (cut_width || cache[url].image.width - cut_x) / cell_size); + !height && (height = cache.quality * (cut_height || cache[url].image.height - cut_y) / cell_size); + + set_shadow(context, inputs, () => context.rect(x, y, end_width, end_height)); + set_border(context, inputs); + context.drawImage( + cache[url].image, + cut_x, cut_y, cut_width || cache[url].image.width - cut_x, cut_height || cache[url].image.height - cut_y, + x, y, end_width, end_height + ); + cache[url].last_used = Date.now(); + + return set_cache(context, true); + }; + + }; + + return set_cache(context, false); + }, + cache : (context, inputs) => { + + const width = inputs.width ? inputs.width * cell_size : canvas.getAttribute("width"), + height = inputs.height ? inputs.height * cell_size : canvas.getAttribute("height"); + let status = false; + + if(!cache[inputs.name]){ + + const subcanvas = cache_box.appendChild(document.createElement("canvas")); + + cache[inputs.name] = { + canvas : subcanvas, + data : null + }; + cache[inputs.name].context = subcanvas.getContext("2d"); + + cache[inputs.name].context.id = inputs.name; + + subcanvas.setAttribute("data-id", cache[inputs.name].context.id); + + cache[inputs.name].context.translate(inputs.x || 0, inputs.y || 0); + + }; + + if(cache[inputs.name].data){ + if(cache[inputs.name].image_loaded){ + context.drawImage(cache[inputs.name].image, _x(inputs.x || 0), _y(inputs.y || 0), cache[inputs.name].image.width, cache[inputs.name].image.height); + status = true; + }else if(!cache[inputs.name].image){ + + cache[inputs.name].image = new Image(); + + cache[inputs.name].image.src = cache[inputs.name].data; + cache[inputs.name].image.onload = () => { + // cache[inputs.name].canvas.remove(); + cache[inputs.name].image_loaded = true; + }; + // cache[inputs.name].image.onerror = () => cache[inputs.name].canvas.remove(); + + }; + }else{ + + cache[inputs.name].canvas.setAttribute("width", width); + cache[inputs.name].canvas.setAttribute("height", height); + + cache[inputs.name].context.beginPath(); + cache[inputs.name].context.clearRect(0, 0, width, height); + cache[inputs.name].context.translate(width / 2, height / 2); + + cache[inputs.name].image = null; + cache[inputs.name].image_loaded = false; + cache[inputs.name].ok = true; + + draw(cache[inputs.name].context, inputs.childs, 0, 0); + + cache[inputs.name].context.closePath(); + + cache[inputs.name].ok && + (cache[inputs.name].data = cache[inputs.name].canvas.toDataURL("image/png", 1.0)); + + }; + + cache[inputs.name].last_used = Date.now(); + + return set_cache(context, status); + }, + text : (context, inputs) => { + + const x = _x(inputs.x), + y = _y(inputs.y), + has_border = set_border(context, inputs), + has_background = set_background(context, inputs); + + inputs.align && (context.textAlign = inputs.align); + inputs.baseline && (context.textBaseline = inputs.baseline); + !isNaN(inputs.border_width) && (context.lineWidth = size(inputs.border_width)); + context.font = (inputs.style ? inputs.style + " " : "") + size(inputs.size || default_font_size) + "px " + (inputs.family || default_font_family); + + set_shadow(context, inputs, () => context.fillText(inputs.text, x, y)); + has_background && context.fillText(inputs.text, x, y); + has_border && context.strokeText(inputs.text, x, y); + + return true; + } + }; + + this.string_variables = (string, variables) => string.replace(/\{([^\{\}]+)\}/g, (...arguments) => variables[arguments[1]] !== undefined ? variables[arguments[1]] : arguments[0]); + + const draw = (context, level, x, y) => level.forEach(values => { + if(values && (shapes[values.type] || ["block"].includes(values.type))){ + + const sub_x = _x(x + (values.margin_x || 0)), + sub_y = _y(y + (values.margin_y || 0)), + date = Date.now(); + + context.save(); + context.translate(sub_x, sub_y); + + const transform = context.getTransform(); + + values.rotate && context.rotate(2 * Math.PI * values.rotate / 360); + !isNaN(values.alpha) && (context.globalAlpha = values.alpha); + + if(values.on_click){ + values.context_x = transform.e / quality; + values.context_y = transform.f / quality; + if(!values.last_used || date - values.last_used > events_cache_timer) + values.i = self.on_click.add(eval(self.string_variables(values.on_click, {object_name : object_name})), values); + else + self.on_click.update(values.i, date); + values.last_used = date; + }; + + values.type != "block" && shapes[values.type](context, values); + + values.type != "cache" && values.childs && draw(context, values.childs, values.x, values.y); + + context.translate(-sub_x, -sub_y); + context.restore(); + + }; + }); + + this.get_real_fps = this.get_real_frames_per_second = () => frames_times_summatory ? 1000 / (frames_times_summatory / frames_times.length) : 0; + + this.threads_add = callback => { + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + this.threads_remove = i => threads[i] = null; + + this.get_cells_x = () => number_of_cells.x; + this.get_cells_y = () => number_of_cells.y; + + this.extends = object => { + for(const key in self) + if(object[key] === undefined) + object[key] = self[key]; + }; + + const on_click = (canvas, event, action) => { + + switch(action){ + case "click": + self.on_click.execute(properties => ( + event.clientX >= properties.context_x + (properties.x * cell_size) && + event.clientY >= properties.context_y + (properties.y * cell_size) && + event.clientX <= properties.context_x + ((properties.x + properties.width) * cell_size) && + event.clientY <= properties.context_y + ((properties.y + properties.height) * cell_size) + ), canvas, event); + break; + }; + + }; + + construct(); + +}; \ No newline at end of file diff --git a/Public/ecma/version/221106/Kanvas.ecma.js b/Public/ecma/version/221106/Kanvas.ecma.js new file mode 100755 index 0000000..38dcfa5 --- /dev/null +++ b/Public/ecma/version/221106/Kanvas.ecma.js @@ -0,0 +1,936 @@ +Kanvas = function(input){ + + const self = this, + default_settings = { + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 100, + origin : 5, // Posición origen. Mirar teclado numérico para ver los diferentes valores para cada posición. + frames_per_second : 60, + ratio : null, // Expone la proporción de tamaño del Canvas (16/9 para pantallas WideScreen por ejemplo). Si es equivalente a falso cubrirá todo el área de la capa donde se encuentre. + overwrite : false, + position : "body", + autostart : true, + object_name : "kanvas", + class : "kanvas", + application : "Kanvas", + x : 0, + y : 0, + width : 0, + height : 0, + color : "#000", + blur : 0, + italic : false, + bold : false, + size : 1, + font : "Arial", + align : "left", + alpha : 1, + degrees : 0, + baseline : "Alphabetic", + shadow_x : 0, + shadow_y : 0, + shadow_color : "#000", + shadow_blur : 0, + border_color : "#000", + border_width : 0, + text_italic : false, + text_bold : false, + text_size : 1, + font_family : "Arial", + text_color : "#000", + text_align : "left", + text_alpha : 1, + rotate_x : 0, + rotate_y : 0, + rotate_degrees : 0, + image_x : 0, + image_y : 0, + image_alpha : 1, + rectangle_color : "#000", + rectangle_alpha : 1, + rectangle_x : 0, + rectangle_y : 0, + text_baseline : "Alphabetic", + default_value : null, + hash_alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + hash_length : 7, + frames_per_second_samples : 20, + settings_overwrite : false, + ajax_timeout : 2000 + }, + custom = {}, + // cache = [], + _screen = {x : 0, y : 0}, + position = {x : 0, y : 0}, + events = {}, + threads = [], + hashes = [], + attributes = { + natives : ["id", "class", "onmousemove", "tabindex", "onkeydown", "onkeyup"] + }, + cache = {}, + frames_per_second_samples = [], + delta_time = 0; + let q, qx, qy, // Calidad porcentual. + c, // Número de celdas en el lado más corto de la pantalla o área de trabajo rectangular. + fx, fy, // Posición contra el foco. + dx, dy, // Distancia desde los laterales hasta el cuadrado de trabajo. + s, // Tamaño de la celda. Solo se mide un lado pues será cuadrada. + mx, my, // Posición origen del lienzo. + thread = null, + timeout = 0, + last_time = 0, + started = false, + cache_container, context, canvas, + // cache_l = 0, + thread_object = null, + frames_per_second_samples_number, + last_frame_per_second_sample = Date.now(), + real_frames_per_seconds = 0, + ajax_timeout; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + let mouse = this.mouse = {x : 0, y : 0}; + + this.LOADING = 1 << 0; + this.LOADED = 1 << 1; + this.ERROR = 1 << 2; + + this.map = []; + + const null_or_undefined = this.null_or_undefined = value => value === undefined || value === null; + + this.get = (url, callback) => { + + let ended = false; + const ajax = new XMLHttpRequest(), + end = status => { + if(ended) + return; + ended = true; + typeof callback == "function" && callback(ajax.response, ajax.status, ajax.readyState, status, status == "OK"); + }, + date = Date.now(); + + ajax.open("get", url, true); + ajax.timeout = ajax_timeout; + ajax.onreadystatechange = () => { + if(ended) + return; + if(ajax.readyState == 4) + end((ajax.status >= 200 && ajax.status < 300) || [301, 302, 304].includes(ajax.status) ? "OK" : "HTTP_ERROR"); + else if(Date.now() - date > ajax_timeout) + end("FORCED_TIMEOUT"); + }; + ajax.send(null); + + ajax.ontimeout = () => end("TIMEOUT"); + ajax.onabort = () => end("ABORTED"); + ajax.onerror = () => end("ERROR"); + + return ajax; + }; + + const allow_nulls = this.allow_nulls = nulls => typeof nulls == "boolean" ? nulls : settings(["nulls", "allow_nulls"], null, false, false); + + const default_value = this.default_value = (_default, nulls) => _default !== undefined && (nulls || _default !== null) ? _default : settings(["default_value", "default", "by_default"], null, null, true); + + this.settings_add = (inputs, overwrite, callback) => { + + if(inputs instanceof Array){ + + let loaded = 0; + const end = () => ++ loaded == inputs.length && typeof callback == "function" && callback(); + + inputs.forEach(input => self.settings_add(input, overwrite, end)); + + return; + }; + + if(typeof inputs == "object"){ + typeof overwrite != "boolean" && (overwrite = settings(["settings_overwrite", "overwrite"])); + for(const key in inputs) + (overwrite || custom[key] === undefined) && (custom[key] = inputs[key]); + inputs.autostart !== undefined && (input.autostart = inputs.autostart); + typeof callback == "function" && callback(); + return; + }; + + if(typeof inputs == "string"){ + + let json; + + try{ + if(json = JSON.parse(inputs)){ + self.settings_add(json, overwrite, callback); + return; + }; + }catch(exception){}; + + self.get(inputs, response => { + try{ + if(json = JSON.parse(response)){ + self.settings_add(json, overwrite, callback); + return; + }; + }catch(exception){}; + typeof callback == "function" && callback(); + }); + + return; + }; + + typeof callback == "function" && callback(); + + }; + + const settings = this.settings = (names, inputs, _default, nulls) => { + if(!names) + return default_value(_default, nulls); + + nulls = allow_nulls(nulls); + + const l = (names.push ? names : names = [names]).length, + m = (inputs = (inputs ? inputs.push ? inputs : [inputs] : []).concat([input, custom, default_settings])).length; + + for(let j = 0; j < m; j ++) + if(typeof inputs[j] == "object") + for(let i = 0; i < l; i ++) + if(names[i] && inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + return default_value(_default, nulls); + }; + + const threads_function = () => threads.forEach(thread => thread && thread()); + + const threads_start = this.threads_start = frames_per_second => thread_object === null && (thread_object = setInterval(threads_function, 1000 / (isNaN(frames_per_second) || frames_per_second < 1 ? settings(["frames_per_second", "fps"]) : frames_per_second))); + + const threads_stop = this.threads_stop = () => { + + if(thread_object === null) + return; + + clearInterval(thread_object); + thread_object = null; + + }; + + const threads_add = this.threads_add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + const threads_remove = this.threads_remove = i => !isNaN(i) && threads[i] && (threads[i] = null); + + const is_html_object = this.is_html_object = variable => typeof variable == "object" && (variable.tagName || variable.nodeName); + + const preload = this.preload = (selector, callback) => { + if(typeof callback != "function") + return; + + if(!selector){ + callback(null, false, "NO_SELECTOR"); + return; + }; + if(is_html_object(selector)){ + callback(selector, false, "OK"); + return; + }; + if(!selector.substr){ + callback(null, false, "BAD_TYPE"); + return; + }; + + let item; + + try{ + if(item = document.querySelector(selector)){ + callback(item, false, "OK"); + return; + }; + }catch(exception){ + callback(null, false, "BAD_SELECTOR"); + return; + }; + + const timeout = settings(["preload_timeout", "timeout"]), + date = Date.now(); + let preload = threads_add(() => { + if(item = document.querySelector(selector)){ + threads_remove(preload); + callback(item, true, "OK"); + }else if(Date.now() - date > timeout){ + threads_remove(preload); + callback(null, true, "TIMEOUT"); + }; + }); + + }; + + const hash = this.hash = () => { + + let hash, alphabet = settings(["hash_alphabet", "alphabet"]); + const length = settings(["hash_length", "length"]), + l = (alphabet.push ? alphabet : alphabet = alphabet.split("")).length; + + do{ + hash = ""; + while((hash += alphabet[Math.random() * l >> 0]).length < length); + }while( + hashes.includes(hash) || + /^\d/.test(hash) || + document.querySelector("." + hash + ",#" + hash + ",[name=" + hash + "]") + ); + hashes.push(hash); + + return hash; + }; + + const set_attribute = this.set_attribute = (item, custom_attributes) => { + if(!is_html_object(item) || typeof custom_attributes != "object") + return; + + for(const name in custom_attributes) + item.setAttribute((attributes.natives.includes(name) ? "" : "data-") + name.replace(/[^a-z\d-]+/g, "-"), custom_attributes[name]); + + }; + + const construct = () => { + + const custom_attributes = { + natives : settings("attributes_natives") + }; + + for(const key in custom_attributes){ + !attributes[key] && (attributes[key] = []); + (custom_attributes ? custom_attributes.push ? custom_attributes : [custom_attributes] : []).forEach(new_attribute => attributes[key].push(new_attribute)); + }; + + object_name = self.object_name = settings("object_name"); + + settings("autostart") && self.start(); + + }; + + const Events = this.Events = function(){ + + const events = []; + + this.add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = events.length; + + while(i < l){ + if(events[i] === null) + break; + i ++; + }; + + events[i] = callback; + + return i; + }; + + this.remove = i => !isNaN(i) && i >= 0 && events[i] && (events[i] = null); + + this.execute = (...inputs) => events.forEach(event => event && event(...inputs)); + + }; + + const range_analyze = range => !range || ( + mouse.x >= range.x && mouse.x <= range.x + range.width && + mouse.y >= range.y && mouse.y <= range.y + range.height + ); + + const on_resize_method = screen => { + + if(_screen.x == item_self.offsetWidth && _screen.y == item_self.offsetHeight) + return; + + const width = canvas.width = (_screen.x = item_self.offsetWidth) * q * qx, + height = canvas.height = (_screen.y = item_self.offsetHeight) * q * qy; + + if(width < height){ + s = width / c; + dx = 0; + dy = -(c - (c * height / width)) / 2; + mx = position.x; + my = position.y + dy; + }else{ + s = height / c; + dx = -(c - (c * width / height)) / 2; + dy = 0; + mx = position.x + dx; + my = position.y; + }; + + //resize_methods.forEach((method) => {if(method)method();}); + execute_event("resize"); + + }; + + const position_set = () => { + + const origin = settings("origin"); + + position.x = c * (.5 * ((origin - 1) % 3)); + position.y = c * (1 - (.5 * ((origin - 1) / 3 >> 0))); + + }; + + const calculate_real_frames_per_seconds = () => { + + const now = Date.now(), + time = now - last_frame_per_second_sample; + + frames_per_second_samples.push(time); + last_frame_per_second_sample = now; + + while(frames_per_second_samples.length > frames_per_second_samples_number) + frames_per_second_samples.shift(); + + real_frames_per_seconds = 1000 / (frames_per_second_samples.reduce((a, b) => a + b) / frames_per_second_samples.length); + delta_time = time / 1000; + + }; + + this.start = callback => { + + const end = status => typeof callback == "function" && callback(status); + + if(started){ + end(false); + return false; + }; + started = true; + + q = settings(["quality", "q"]); + qx = settings(["quality_x", "qx"]); + qy = settings(["quality_y", "qy"]); + timeout = 1000 / settings("frames_per_second"); + c = settings("cells"); + position_set(); + threads_start(); + ajax_timeout = settings("ajax_timeout"); + + preload(settings("position"), (position, asynchronous, error) => { + + if(!position){ + console.error("ERROR. Position HTML for install GUI CANVAS is bad. [" + error + "]"); + return; + }; + + const _class = (hash_self = self.hash_self = hash()) + " " + settings("class"); + + !new RegExp("\\b" + default_settings.class + "\\b").test(_class) && (_class += " " + default_settings.class); + + set_attribute(item_self = self.item_self = position.appendChild(document.createElement("div")), { + id : hash_self, + hash : hash_self, + class : _class, + application : default_settings.application, + onmousemove : object_name + ".check_mouse(this, event);", + tabindex : 0, + onkeydown : object_name + ".key_down(this, event);", + onkeyup : object_name + ".key_up(this, event);", + cells : c, + mouse_x : 0, + mouse_y : 0 + }); + set_attribute(cache_container = item_self.appendChild(document.createElement("div")), { + class : "cache" + }); + set_attribute(canvas = item_self.appendChild(document.createElement("canvas")), { + class : "canvas" + }); + context = canvas.getContext("2d"); + + thread = threads_add(thread_method); + on_resize_thread = threads_add(on_resize_method); + item_self.onclick = () => execute_event("click"); + + frames_per_second_samples_number = self.settings("frames_per_second_samples"); + threads_add(calculate_real_frames_per_seconds); + + end(true); + + }); + + return true; + }; + + // o = Origin {mx, my} + const draw = this.draw = (map, context, o) => map && map.forEach((level, i) => level && (level.push && draw(level, context, o || {mx : mx, my : my}) || (level.type && components[level.type] && components[level.type](level, context, self, o || {mx : mx, my : my})))); + + const refresh_draw = () => { + + if(!context) + return; + + context.clearRect(0, 0, canvas.width, canvas.height); + draw(self.map, context); + + }; + + const thread_method = () => { + + const date = Date.now(); + + if(date - last_time < timeout) + return; + last_time = date; + + refresh_draw(); + + }; + + // Establecer posición sobre el foco de origen. + // Establecer posición sobre los laterales del recuadro o área de trabajo. + const value = this.value = (value, quality) => q * value * (quality || 1); + // const _x = this._x = value => q * qx * value * s; + // const _y = this._y = value => q * qy * value * s; + const _x = this._x = value => value * s; + const _y = this._y = value => value * s; + + this.preload_cache_items = (items, callback_per_item, callback) => { + + const end = status => typeof callback == "function" && callback(status); + + typeof items == "string" && (items = [items]); + + if(!(items instanceof Array)){ + end(false); + return; + }; + + let fully = true, + loaded = 0; + const has_callback_per_item = typeof callback_per_item == "function", + on_item_loaded = (url, ok) => { + ok !== undefined && (cache[url].status = ok ? self.LOADED : self.ERROR); + cache[url].on_load.execute(url, ok); + has_callback_per_item && callback_per_item(url, ok); + ok === false && fully && (fully = false); + ++ loaded == items.length && end(fully); + }; + + items.forEach(url => { + + if(cache[url]){ + if(cache[url].status == self.LOADING) + cache[url].on_load.add(has_callback_per_item); + else + on_item_loaded(url); + return; + }; + + const extension = ((url.match(/\.([^\.]+)/) || [])[1] || "").toLowerCase(); + + cache[url] = { + status : self.LOADING, + on_load : new Events() + }; + + switch(extension){ + case "jpg": + case "jpeg": + case "jpge": + case "png": + case "webp": + case "gif": + case "tif": + case "tiff": + case "pcx": + case "bmp": + + const image = new Image(); + + cache[url].type = "image"; + cache[url].image = image; + + image.src = url; + image.onload = () => on_item_loaded(url, true); + image.onerror = () => on_item_loaded(url, false); + + break; + default: + + cache[url].type = "unknown"; + cache[url].status = self.ERROR; + on_item_loaded(url, false); + + break; + }; + + }); + + }; + + const angle = this.angle = (x, y, randians) => { + + if(typeof x == "object"){ + + const line = x.push ? { + x : x[0] - y[0], + y : x[1] - y[1] + } : { + x : x.x - y.x, + y : x.y - y.y + }; + + x = line.x; + y = line.y; + + }; + + let angle = Math.asin(y / ((x ** 2) + (y ** 2)) ** .5); + + // if(x >= 0) + // angle += Math.PI / 2; + // else + // angle = (1.5 * Math.PI) - angle; + + return (x >= 0 ? angle + (Math.PI / 2) : ((1.5 * Math.PI) - angle)) * (randians ? 1 : 180 / Math.PI); + }; + + const shadow = (data, context) => { + + const z = dx < dy ? _x : _y; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["shadow_x", "x"])); + isNaN(data.y) && (data.y = settings(["shadow_y", "y"])); + !data.color && (data.color = settings(["shadow_color", "color"])); + isNaN(data.blur) && (data.blur = settings(["shadow_blur", "blur"])); + data.ok = true; + }; + + context.shadowOffsetX = z(data.x); + context.shadowOffsetY = z(data.y); + context.shadowColor = data.color; + context.shadowBlur = z(data.blur); + + }; + + const border = (data, context) => { + + if(!data.ok){ + !data.color && (data.color = settings(["border_color", "color"])); + isNaN(data.width) && (data.width = settings(["border_width", "width"])); + data.ok = true; + }; + + context.strokeStyle = data.color; + context.lineWidth = (dx < dy ? _x : _y)(data.width); + + }; + + const components = { + rotate : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["rotate_x", "x"])); + isNaN(data.y) && (data.y = settings(["rotate_y", "y"])); + isNaN(data.degrees) && (data.degrees = settings(["rotate_degrees", "degrees"])); + data.ok = true; + }; + + // console.log(JSON.stringify(data)); + // console.log(JSON.stringify([_x(data.x + mx), _y(data.y + my)])); + + context.save(); + context.translate(_x(data.x + o.mx), _y(data.y + o.my)); + context.rotate(data.degrees * Math.PI / 180); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + image : (data, context, kanvas, o) => { + if(data.ignore) + return; + + !data.ok && !data.source && (data.source = data.src || data.url); + + if(cache[data.source]){ + + if(!data.ok){ + if(cache[data.source] && cache[data.source].status == self.LOADED){ + isNaN(data.swidth) && (data.swidth = cache[data.source].image.width); + isNaN(data.sheight) && (data.sheight = cache[data.source].image.height); + isNaN(data.width) && (data.width = data.swidth); + isNaN(data.height) && (data.height = data.sheight); + }; + isNaN(data.x) && (data.x = settings(["image_x", "x"])); + isNaN(data.y) && (data.y = settings(["image_y", "y"])); + isNaN(data.alpha) && (data.alpha = settings(["image_alpha", "alpha"])); + isNaN(data.sx) && (data.sx = 0); + isNaN(data.sy) && (data.sy = 0); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + if(cache[data.source].status != self.LOADED) + return; + + const half_width = data.width / 2, + half_height = data.height / 2; + + context.save(); + context.globalAlpha = data.alpha; + context.translate(_x(o.mx + data.x + data.mx + half_width), _y(o.my + data.y + data.my + half_height)); + context.rotate(data.rotate * Math.PI / 180); + context.drawImage( + cache[data.source].image, + data.sx, data.sy, data.swidth, data.sheight, + _x(-half_width), _y(-half_height), _x(data.width), _y(data.height) + ); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }else + self.preload_cache_items([data.source]); + + }, + // cache : (data, context, kanvas, o) => { + // if(data.ignore) + // return; + + // context.save(); + + // if(isNaN(data.cache_i)){ + + // const cache_canvas = cache_container.appendChild(document.createElement("canvas")), + // cache_context = cache_canvas.getContext("2d"), + // width = data.width || canvas.width, + // height = data.height || canvas.height; + // image = new Image(); + + // cache_canvas.width = width; + // cache_canvas.height = height; + + // get_new_cache_i(data); + // cache_context.save(); + // // cache_context.translate(_x(-o.mx), _y(-o.my)); + // draw(data.childs, cache_context, {mx : 0, my : 0}); + // image.src = cache_canvas.toDataURL("image/png"); + // cache[data.cache_i] = image; + // cache_context.restore(); + + // cache_canvas.remove(); + + // }; + + // context.drawImage(cache[data.cache_i], 0, 0); + // context.restore(); + + // }, + rectangle : (data, context, kanvas, o) => { + if(data.ignore)return; + + const proportion = canvas.width > canvas.height ? canvas.width / canvas.height : canvas.height / canvas.width; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["rectangle_alpha", "alpha"])); + !data.color && (data.color = settings(["rectangle_color", "color"])); + isNaN(data.x) && (data.x = settings(["rectangle_x", "x"])); + isNaN(data.y) && (data.y = settings(["rectangle_y", "y"])); + isNaN(data.width) && (data.width = proportion * c); + isNaN(data.height) && (data.height = proportion * c); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.fillStyle = data.color; + context.translate(_x(o.mx + data.x + data.mx), _y(o.my + data.y + data.my)); + context.rotate(data.rotate * Math.PI / 180); + context.translate(_x(-data.mx), _y(-data.my)); + context.fillRect(_x(data.x), _y(data.y), _x(data.width), _y(data.height)); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + text : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + typeof data.italic != "boolean" && (data.italic = settings(["text_italic", "italic"])); + isNaN(data.bold) && typeof data.bold != "boolean" && (data.bold = settings(["text_bold", "bold"])); + isNaN(data.size) && (data.size = settings(["text_size", "size"])); + data.font && (data.font_family = data.font); + !data.font_family && (data.font_family = settings(["text_font_family", "text_font", "font"])); + !data.align && (data.align = settings(["text_align", "align"])); + isNaN(data.x) && (data.x = settings(["text_x", "x"])); + isNaN(data.y) && (data.y = settings(["text_y", "y"])); + !data.text && (data.text = ""); + isNaN(data.alpha) && (data.alpha = settings(["text_alpha", "alpha"])); + !data.baseline && (data.baseline = settings(["text_baseline", "baseline"])); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.textAlign = data.align; + context.textBaseline = data.baseline; + context.font = ( + (data.italic ? "italic " : "") + + (data.bold ? isNaN(data.bold) ? "bold " : data.bold + " " : "") + + (dx < dy ? _x : _y)(data.size) + "px " + + data.font_family + ); + if(data.color){ + context.fillStyle = data.color; + context.fillText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + if(data.border){ + border(data.border, context); + context.strokeText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + context.restore(); + + }, + block : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["block_alpha", "alpha"])); + data.ok = true; + }; + + context.save(); + context.globalAlpha = data.alpha; + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + } + }; + + this.add_components = (json, overwrite) => { + if(!json) + return; + + !json.push && (json = [json]); + typeof overwrite != "bool" && (overwrite = settings("overwrite")); + + json.forEach((items) => { + if(!items) + return; + if(items.push) + self.add_components(items, overwrite); + else if(typeof items == "object") + for(let key in items) + (overwrite || !components[key]) && (components[key] = items[key]); + }); + + }; + + this.extends = (object, overwrite) => { + for(const key in self) + (overwrite || object[key] === undefined) && (object[key] = self[key]); + }; + + this.check_mouse = (item, event) => { + + item_self.setAttribute("data-mouse-x", mouse.x = (event.clientX * q * qx / s) - mx); + item_self.setAttribute("data-mouse-y", mouse.y = (event.clientY * q * qy / s) - my); + + execute_event("mouse_move"); + + }; + + const on_event = this.on_event = (name, method, range) => { + + if(typeof method != "function") + return null; + + !events[name] && (events[name] = { + methods : [], + l : 0, + ranges : [] + }); + + let i = 0; + + for(; i < events[name].l; i ++) + if(!events[name].methods[i]) + break; + + events[name].methods[i] = method; + events[name].ranges[i] = range; + events[name].l = events[name].methods.length; + + return i; + }; + + const remove_event = this.remove_event = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l && events[name].methods[i] && (events[name].methods[i] = null); + + const execute_event = this.execute_event = (name, input) => { + + if(events[name] && events[name].l) + for(let i = 0; i < events[name].l; i ++) + events[name].methods[i] && events[name].methods[i](range_analyze(events[name].ranges[i]), input); + + }; + + const event_range = this.event_range = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l ? events[name].ranges[i] : null; + + this.on_mouse_move = (method, range) => on_event("mouse_move", method, range); + this.on_resize = (method, range) => on_event("resize", method, range); + this.on_click = (method, range) => on_event("click", method, range); + this.on_key_down = (method, range) => on_event("key_down", method, range); + this.on_key_up = (method, range) => on_event("key_up", method, range); + + this.remove_mouse_move = i => {remove_event("mouse_move", i);}; + this.remove_resize = i => {remove_event("resize", i);}; + this.remove_click = i => {remove_event("click", i);}; + this.remove_key_down = i => {remove_event("key_down", i);}; + this.remove_key_up = i => {remove_event("key_up", i);}; + + this.range_mouse_move = i => event_range("mouse_move", i); + this.range_resize = i => event_range("resize", i); + this.range_click = i => event_range("click", i); + this.range_key_down = i => event_range("key_down", i); + this.range_key_up = i => event_range("key_up", i); + + this.key_down = (item, event) => execute_event("key_down", {code : event.keyCode}); + this.key_up = (item, event) => execute_event("key_up", {code : event.keyCode}); + + this.get_margins = () => ({x : mx, y : my}); + this.get_position = () => ({x : position.x, y : position.y}); + this.get_cells = () => c; + this.get_canvas_distance = () => ({x : dx, y : dy}); + this.get_cell_size = () => s; + + this.get_real_frames_per_second = () => real_frames_per_seconds; + this.delta_time = () => delta_time; + + construct(); + +}; diff --git a/Public/ecma/version/30311230/Kanvas.ecma.js b/Public/ecma/version/30311230/Kanvas.ecma.js new file mode 100755 index 0000000..7c89766 --- /dev/null +++ b/Public/ecma/version/30311230/Kanvas.ecma.js @@ -0,0 +1,782 @@ +Kanvas = function(input){ + + const self = this, + default_settings = { + quality : 1, + quality_x : 1, + quality_y : 1, + cells : 100, + origin : 5, // Posición origen. Mirar teclado numérico para ver los diferentes valores para cada posición. + frames_per_second : 60, + ratio : null, // Expone la proporción de tamaño del Canvas (16/9 para pantallas WideScreen por ejemplo). Si es equivalente a falso cubrirá todo el área de la capa donde se encuentre. + overwrite : false, + position : "body", + autostart : true, + object_name : "kanvas", + class : "kanvas", + application : "Kanvas", + x : 0, + y : 0, + width : 0, + height : 0, + color : "#000", + blur : 0, + italic : false, + bold : false, + size : 1, + font : "Arial", + align : "left", + alpha : 1, + degrees : 0, + baseline : "Alphabetic", + shadow_x : 0, + shadow_y : 0, + shadow_color : "#000", + shadow_blur : 0, + border_color : "#000", + border_width : 0, + text_italic : false, + text_bold : false, + text_size : 1, + font_family : "Arial", + text_color : "#000", + text_align : "left", + text_alpha : 1, + rotate_x : 0, + rotate_y : 0, + rotate_degrees : 0, + image_x : 0, + image_y : 0, + image_alpha : 1, + rectangle_color : "#000", + rectangle_alpha : 1, + rectangle_x : 0, + rectangle_y : 0, + text_baseline : "Alphabetic", + default_value : null, + hash_alphabet : "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", + hash_length : 7 + }, + cache = [], + _screen = {x : 0, y : 0}, + position = {x : 0, y : 0}, + events = {}, + threads = [], + hashes = [], + attributes = { + natives : ["id", "class", "onmousemove", "tabindex", "onkeydown", "onkeyup"] + }; + let q, qx, qy, // Calidad porcentual. + c, // Número de celdas en el lado más corto de la pantalla o área de trabajo rectangular. + fx, fy, // Posición contra el foco. + dx, dy, // Distancia desde los laterales hasta el cuadrado de trabajo. + s, // Tamaño de la celda. Solo se mide un lado pues será cuadrada. + mx, my, // Posición origen del lienzo. + thread = null, + timeout = 0, + last_time = 0, + started = false, + cache_container, context, canvas, + cache_l = 0, + thread_object = null; + + let item_self = this.item_self; + let hash_self = this.hash_self; + let object_name = this.object_name; + let mouse = this.mouse = {x : 0, y : 0}; + + this.map = []; + + const null_or_undefined = this.null_or_undefined = value => value === undefined || value === null; + + const allow_nulls = this.allow_nulls = nulls => typeof nulls == "boolean" ? nulls : settings(["nulls", "allow_nulls"], null, false, false); + + const default_value = this.default_value = (_default, nulls) => _default !== undefined && (nulls || _default !== null) ? _default : settings(["default_value", "default", "by_default"], null, null, true); + + const settings = this.settings = (names, inputs, _default, nulls) => { + if(!names) + return default_value(_default, nulls); + + nulls = allow_nulls(nulls); + + const l = (names.push ? names : names = [names]).length, + m = (inputs = (inputs ? inputs.push ? inputs : [inputs] : []).concat([input, default_settings])).length; + + for(let j = 0; j < m; j ++) + if(typeof inputs[j] == "object") + for(let i = 0; i < l; i ++) + if(names[i] && inputs[j][names[i]] !== undefined && (nulls || inputs[j][names[i]] !== null)) + return inputs[j][names[i]]; + return default_value(_default, nulls); + }; + + const threads_function = () => threads.forEach(thread => thread && thread()); + + const threads_start = this.threads_start = frames_per_second => thread_object === null && (thread_object = setInterval(threads_function, 1000 / (isNaN(frames_per_second) || frames_per_second < 1 ? settings(["frames_per_second", "fps"]) : frames_per_second))); + + const threads_stop = this.threads_stop = () => { + + if(thread_object === null) + return; + + clearInterval(thread_object); + thread_object = null; + + }; + + const threads_add = this.threads_add = callback => { + if(typeof callback != "function") + return null; + + let i = 0; + const l = threads.length; + + for(; i < l; i ++) + if(!threads[i]) + break; + + threads[i] = callback; + + return i; + }; + + const threads_remove = this.threads_remove = i => !isNaN(i) && threads[i] && (threads[i] = null); + + const is_html_object = this.is_html_object = variable => typeof variable == "object" && (variable.tagName || variable.nodeName); + + const preload = this.preload = (selector, callback) => { + if(typeof callback != "function") + return; + + if(!selector){ + callback(null, false, "NO_SELECTOR"); + return; + }; + if(is_html_object(selector)){ + callback(selector, false, "OK"); + return; + }; + if(!selector.substr){ + callback(null, false, "BAD_TYPE"); + return; + }; + + let item; + + try{ + if(item = document.querySelector(selector)){ + callback(item, false, "OK"); + return; + }; + }catch(exception){ + callback(null, false, "BAD_SELECTOR"); + return; + }; + + const timeout = settings(["preload_timeout", "timeout"]), + date = Date.now(); + let preload = threads_add(() => { + if(item = document.querySelector(selector)){ + threads_remove(preload); + callback(item, true, "OK"); + }else if(Date.now() - date > timeout){ + threads_remove(preload); + callback(null, true, "TIMEOUT"); + }; + }); + + }; + + const hash = this.hash = () => { + + let hash, alphabet = settings(["hash_alphabet", "alphabet"]); + const length = settings(["hash_length", "length"]), + l = (alphabet.push ? alphabet : alphabet = alphabet.split("")).length; + + do{ + hash = ""; + while((hash += alphabet[Math.random() * l >> 0]).length < length); + }while( + hashes.includes(hash) || + /^\d/.test(hash) || + document.querySelector("." + hash + ",#" + hash + ",[name=" + hash + "]") + ); + hashes.push(hash); + + return hash; + }; + + const set_attribute = this.set_attribute = (item, custom_attributes) => { + if(!is_html_object(item) || typeof custom_attributes != "object") + return; + + for(const name in custom_attributes) + item.setAttribute((attributes.natives.includes(name) ? "" : "data-") + name.replace(/[^a-z\d-]+/g, "-"), custom_attributes[name]); + + }; + + const construct = () => { + + const custom_attributes = { + natives : settings("attributes_natives") + }; + + for(const key in custom_attributes){ + !attributes[key] && (attributes[key] = []); + (custom_attributes ? custom_attributes.push ? custom_attributes : [custom_attributes] : []).forEach(new_attribute => attributes[key].push(new_attribute)); + }; + + object_name = self.object_name = settings("object_name"); + + settings("autostart") && self.start(); + + }; + + const range_analyze = range => !range || ( + mouse.x >= range.x && mouse.x <= range.x + range.width && + mouse.y >= range.y && mouse.y <= range.y + range.height + ); + + const on_resize_method = screen => { + + if(_screen.x == item_self.offsetWidth && _screen.y == item_self.offsetHeight) + return; + + const width = canvas.width = (_screen.x = item_self.offsetWidth) * q * qx, + height = canvas.height = (_screen.y = item_self.offsetHeight) * q * qy; + + if(width < height){ + s = width / c; + dx = 0; + dy = -(c - (c * height / width)) / 2; + mx = position.x; + my = position.y + dy; + }else{ + s = height / c; + dx = -(c - (c * width / height)) / 2; + dy = 0; + mx = position.x + dx; + my = position.y; + }; + + //resize_methods.forEach((method) => {if(method)method();}); + execute_event("resize"); + + }; + + const position_set = () => { + + const origin = settings("origin"); + + position.x = c * (.5 * ((origin - 1) % 3)); + position.y = c * (1 - (.5 * ((origin - 1) / 3 >> 0))); + + }; + + this.start = () => { + + if(started) + return; + started = true; + + q = settings(["quality", "q"]); + qx = settings(["quality_x", "qx"]); + qy = settings(["quality_y", "qy"]); + timeout = 1000 / settings("frames_per_second"); + c = settings("cells"); + position_set(); + threads_start(); + + preload(settings("position"), (position, asynchronous, error) => { + + if(!position){ + console.error("ERROR. Position HTML for install GUI CANVAS is bad. [" + error + "]"); + return; + }; + + const _class = (hash_self = self.hash_self = hash()) + " " + settings("class"); + + !new RegExp("\\b" + default_settings.class + "\\b").test(_class) && (_class += " " + default_settings.class); + + set_attribute(item_self = self.item_self = position.appendChild(document.createElement("div")), { + id : hash_self, + hash : hash_self, + class : _class, + application : default_settings.application, + onmousemove : object_name + ".check_mouse(this, event);", + tabindex : 0, + onkeydown : object_name + ".key_down(this, event);", + onkeyup : object_name + ".key_up(this, event);" + }); + set_attribute(cache_container = item_self.appendChild(document.createElement("div")), { + class : "cache" + }); + set_attribute(canvas = item_self.appendChild(document.createElement("canvas")), { + class : "canvas" + }); + context = canvas.getContext("2d"); + + thread = threads_add(thread_method); + on_resize_thread = threads_add(on_resize_method); + item_self.onclick = () => execute_event("click"); + + }); + + }; + + // o = Origin {mx, my} + const draw = this.draw = (map, context, o) => map && map.forEach((level, i) => level && (level.push && draw(level, context, o || {mx : mx, my : my}) || (level.type && components[level.type] && components[level.type](level, context, self, o || {mx : mx, my : my})))); + + const refresh_draw = () => { + + if(!context) + return; + + context.clearRect(0, 0, canvas.width, canvas.height); + draw(self.map, context); + + }; + + const thread_method = () => { + + const date = Date.now(); + + if(date - last_time < timeout) + return; + last_time = date; + + refresh_draw(); + + }; + + // Establecer posición sobre el foco de origen. + // Establecer posición sobre los laterales del recuadro o área de trabajo. + const value = this.value = (value, quality) => q * value * (quality || 1); + // const _x = this._x = value => q * qx * value * s; + // const _y = this._y = value => q * qy * value * s; + const _x = this._x = value => value * s; + const _y = this._y = value => value * s; + + this.cache_set = item => { + + let i = 0; + + for(; i < cache_l; i ++) + if(cache[i] === null) + break; + + cache[i] = item; + cache_l = cache.length; + + return i; + }; + + const get_new_cache_i = item => item.cache_i = self.cache_set(true); + + this.cache_clean = i => !isNaN(i) && i >= 0 && i < cache.length && cache[i] !== null && (cache[i] = null); + + const preload_cache_items = (items, callback_per_item, callback, i) => { + + if(i >= items.length){ + typeof callback == "function" && callback(); + return; + }; + + const end = () => { + typeof callback_per_item == "function" && callback_per_item(i, items[i]); + preload_cache_items(items, callback_per_item, callback, i + 1); + }; + + if(!items[i]){ + end(); + return; + }; + + switch(items[i].type){ + case "image": + + const source = items[i].source || items[i].value; + + if(!source){ + end(); + return; + }; + + const image = new Image(); + + image.src = source; + image.crossOrigin = "anonymous"; + image.onload = () => { + items[i].cache_i = self.cache_set(image); + // console.log([items[i], items[i].source || items[i].value, cache[items[i].cache_i]]); + end(); + }; + image.onerror = end; + + break; + default: + items[i].cache_i = self.cache_set(image); + end(); + break; + }; + + }; + + this.preload_cache_items = (items, callback_per_item, callback) => { + + if(!items){ + typeof callback == "function" && callback(); + return; + }; + !items.pus && (items = [items]); + + preload_cache_items(items, callback_per_item, callback, 0); + + }; + + const angle = this.angle = (x, y, randians) => { + + if(typeof x == "object"){ + + const line = x.push ? { + x : x[0] - y[0], + y : x[1] - y[1] + } : { + x : x.x - y.x, + y : x.y - y.y + }; + + x = line.x; + y = line.y; + + }; + + let angle = Math.asin(y / ((x ** 2) + (y ** 2)) ** .5); + + // if(x >= 0) + // angle += Math.PI / 2; + // else + // angle = (1.5 * Math.PI) - angle; + + return (x >= 0 ? angle + (Math.PI / 2) : ((1.5 * Math.PI) - angle)) * (randians ? 1 : 180 / Math.PI); + }; + + const shadow = (data, context) => { + + const z = dx < dy ? _x : _y; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["shadow_x", "x"])); + isNaN(data.y) && (data.y = settings(["shadow_y", "y"])); + !data.color && (data.color = settings(["shadow_color", "color"])); + isNaN(data.blur) && (data.blur = settings(["shadow_blur", "blur"])); + data.ok = true; + }; + + context.shadowOffsetX = z(data.x); + context.shadowOffsetY = z(data.y); + context.shadowColor = data.color; + context.shadowBlur = z(data.blur); + + }; + + const border = (data, context) => { + + if(!data.ok){ + !data.color && (data.color = settings(["border_color", "color"])); + isNaN(data.width) && (data.width = settings(["border_width", "width"])); + data.ok = true; + }; + + context.strokeStyle = data.color; + context.lineWidth = (dx < dy ? _x : _y)(data.width); + + }; + + const components = { + rotate : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.x) && (data.x = settings(["rotate_x", "x"])); + isNaN(data.y) && (data.y = settings(["rotate_y", "y"])); + isNaN(data.degrees) && (data.degrees = settings(["rotate_degrees", "degrees"])); + data.ok = true; + }; + + // console.log(JSON.stringify(data)); + // console.log(JSON.stringify([_x(data.x + mx), _y(data.y + my)])); + + context.save(); + context.translate(_x(data.x + o.mx), _y(data.y + o.my)); + context.rotate(data.degrees * Math.PI / 180); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + image : (data, context, kanvas, o) => { + if(data.ignore) + return; + + const draw_image = () => { + + if(!data.ok){ + isNaN(data.swidth) && (data.swidth = cache[data.cache_i].width); + isNaN(data.sheight) && (data.sheight = cache[data.cache_i].height); + isNaN(data.width) && (data.width = data.swidth); + isNaN(data.height) && (data.height = data.sheight); + isNaN(data.x) && (data.x = settings(["image_x", "x"])); + isNaN(data.y) && (data.y = settings(["image_y", "y"])); + isNaN(data.alpha) && (data.alpha = settings(["image_alpha", "alpha"])); + isNaN(data.sx) && (data.sx = 0); + isNaN(data.sy) && (data.sy = 0); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + const half_width = data.width / 2, + half_height = data.height / 2; + + context.save(); + context.globalAlpha = data.alpha; + context.translate(_x(o.mx + data.x + data.mx + half_width), _y(o.my + data.y + data.my + half_height)); + context.rotate(data.rotate * Math.PI / 180); + context.drawImage( + cache[data.cache_i], + data.sx, data.sy, data.swidth, data.sheight, + _x(-half_width), _y(-half_height), _x(data.width), _y(data.height) + ); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }; + + if(isNaN(data.cache_i)){ + + const i = get_new_cache_i(data); + + cache[i] = new Image(); + cache[i].src = data.source || data.image; + cache[i].crossOrigin = "anonymous"; + cache[i].onload = draw_image; + + }else + draw_image(); + + }, + cache : (data, context, kanvas, o) => { + if(data.ignore) + return; + + context.save(); + + if(isNaN(data.cache_i)){ + + const cache_canvas = cache_container.appendChild(document.createElement("canvas")), + cache_context = cache_canvas.getContext("2d"), + width = data.width || canvas.width, + height = data.height || canvas.height; + image = new Image(); + + cache_canvas.width = width; + cache_canvas.height = height; + + get_new_cache_i(data); + cache_context.save(); + // cache_context.translate(_x(-o.mx), _y(-o.my)); + draw(data.childs, cache_context, {mx : 0, my : 0}); + image.src = cache_canvas.toDataURL("image/png"); + cache[data.cache_i] = image; + cache_context.restore(); + + cache_canvas.remove(); + + }; + + context.drawImage(cache[data.cache_i], 0, 0); + context.restore(); + + }, + rectangle : (data, context, kanvas, o) => { + if(data.ignore)return; + + const proportion = canvas.width > canvas.height ? canvas.width / canvas.height : canvas.height / canvas.width; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["rectangle_alpha", "alpha"])); + !data.color && (data.color = settings(["rectangle_color", "color"])); + isNaN(data.x) && (data.x = settings(["rectangle_x", "x"])); + isNaN(data.y) && (data.y = settings(["rectangle_y", "y"])); + isNaN(data.width) && (data.width = proportion * c); + isNaN(data.height) && (data.height = proportion * c); + isNaN(data.mx) && (data.mx = 0); + isNaN(data.my) && (data.my = 0); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.fillStyle = data.color; + context.translate(_x(o.mx + data.x + data.mx), _y(o.my + data.y + data.my)); + context.rotate(data.rotate * Math.PI / 180); + context.translate(_x(-data.mx), _y(-data.my)); + context.fillRect(_x(data.x), _y(data.y), _x(data.width), _y(data.height)); + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + }, + text : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + typeof data.italic != "boolean" && (data.italic = settings(["text_italic", "italic"])); + isNaN(data.bold) && typeof data.bold != "boolean" && (data.bold = settings(["text_bold", "bold"])); + isNaN(data.size) && (data.size = settings(["text_size", "size"])); + data.font && (data.font_family = data.font); + !data.font_family && (data.font_family = settings(["text_font_family", "text_font", "font"])); + !data.align && (data.align = settings(["text_align", "align"])); + isNaN(data.x) && (data.x = settings(["text_x", "x"])); + isNaN(data.y) && (data.y = settings(["text_y", "y"])); + !data.text && (data.text = ""); + isNaN(data.alpha) && (data.alpha = settings(["text_alpha", "alpha"])); + !data.baseline && (data.baseline = settings(["text_baseline", "baseline"])); + data.ok = true; + }; + + context.save(); + data.shadow && (shadow(data.shadow, context)); + context.globalAlpha = data.alpha; + context.textAlign = data.align; + context.textBaseline = data.baseline; + context.font = ( + (data.italic ? "italic " : "") + + (data.bold ? isNaN(data.bold) ? "bold " : data.bold + " " : "") + + (dx < dy ? _x : _y)(data.size) + "px " + + data.font_family + ); + if(data.color){ + context.fillStyle = data.color; + context.fillText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + if(data.border){ + border(data.border, context); + context.strokeText(data.text, _x(data.x + mx), _y(data.y + my)); + }; + context.restore(); + + }, + block : (data, context, kanvas, o) => { + if(data.ignore) + return; + + if(!data.ok){ + isNaN(data.alpha) && (data.alpha = settings(["block_alpha", "alpha"])); + data.ok = true; + }; + + context.save(); + context.globalAlpha = data.alpha; + draw(data.childs, context, {mx : 0, my : 0}); + context.restore(); + + } + }; + + this.add_components = (json, overwrite) => { + if(!json) + return; + + !json.push && (json = [json]); + typeof overwrite != "bool" && (overwrite = settings("overwrite")); + + json.forEach((items) => { + if(!items) + return; + if(items.push) + self.add_components(items, overwrite); + else if(typeof items == "object") + for(let key in items) + (overwrite || !components[key]) && (components[key] = items[key]); + }); + + }; + + this.check_mouse = (item, event) => { + + item_self.setAttribute("data-mouse-x", mouse.x = (event.clientX * q * qx / s) - mx); + item_self.setAttribute("data-mouse-y", mouse.y = (event.clientY * q * qy / s) - my); + + execute_event("mouse_move"); + + }; + + const on_event = this.on_event = (name, method, range) => { + + if(typeof method != "function") + return null; + + !events[name] && (events[name] = { + methods : [], + l : 0, + ranges : [] + }); + + let i = 0; + + for(; i < events[name].l; i ++) + if(!events[name].methods[i]) + break; + + events[name].methods[i] = method; + events[name].ranges[i] = range; + events[name].l = events[name].methods.length; + + return i; + }; + + const remove_event = this.remove_event = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l && events[name].methods[i] && (events[name].methods[i] = null); + + const execute_event = this.execute_event = (name, input) => { + + if(events[name] && events[name].l) + for(let i = 0; i < events[name].l; i ++) + events[name].methods[i] && events[name].methods[i](range_analyze(events[name].ranges[i]), input); + + }; + + const event_range = this.event_range = (name, i) => events[name] && !isNaN(i) && i >= 0 && i < events[name].l ? events[name].ranges[i] : null; + + this.on_mouse_move = (method, range) => on_event("mouse_move", method, range); + this.on_resize = (method, range) => on_event("resize", method, range); + this.on_click = (method, range) => on_event("click", method, range); + this.on_key_down = (method, range) => on_event("key_down", method, range); + this.on_key_up = (method, range) => on_event("key_up", method, range); + + this.remove_mouse_move = i => {remove_event("mouse_move", i);}; + this.remove_resize = i => {remove_event("resize", i);}; + this.remove_click = i => {remove_event("click", i);}; + this.remove_key_down = i => {remove_event("key_down", i);}; + this.remove_key_up = i => {remove_event("key_up", i);}; + + this.range_mouse_move = i => event_range("mouse_move", i); + this.range_resize = i => event_range("resize", i); + this.range_click = i => event_range("click", i); + this.range_key_down = i => event_range("key_down", i); + this.range_key_up = i => event_range("key_up", i); + + this.key_down = (item, event) => execute_event("key_down", {code : event.keyCode}); + this.key_up = (item, event) => execute_event("key_up", {code : event.keyCode}); + + this.get_margins = () => {return {x : mx, y : my};}; + this.get_position = () => {return {x : position.x, y : position.y};}; + this.get_cells = () => c; + this.get_canvas_distance = () => {return {x : dx, y : dy};}; + this.get_cell_size = () => s; + + construct(); + +}; diff --git a/Public/git_update.php b/Public/git_update.php new file mode 100755 index 0000000..0879a28 --- /dev/null +++ b/Public/git_update.php @@ -0,0 +1,4 @@ +&1"); diff --git a/Public/images/kanvas-180.png b/Public/images/kanvas-180.png new file mode 100755 index 0000000..986d9ce Binary files /dev/null and b/Public/images/kanvas-180.png differ diff --git a/Public/images/kanvas-192.png b/Public/images/kanvas-192.png new file mode 100755 index 0000000..8e84259 Binary files /dev/null and b/Public/images/kanvas-192.png differ diff --git a/Public/images/kanvas-270.png b/Public/images/kanvas-270.png new file mode 100755 index 0000000..e909003 Binary files /dev/null and b/Public/images/kanvas-270.png differ diff --git a/Public/images/kanvas-32.png b/Public/images/kanvas-32.png new file mode 100755 index 0000000..ab4a327 Binary files /dev/null and b/Public/images/kanvas-32.png differ diff --git a/Public/images/kanvas-512.png b/Public/images/kanvas-512.png new file mode 100755 index 0000000..749136d Binary files /dev/null and b/Public/images/kanvas-512.png differ diff --git a/Public/images/kanvas.png b/Public/images/kanvas.png new file mode 100755 index 0000000..749136d Binary files /dev/null and b/Public/images/kanvas.png differ diff --git a/Public/test/index.html b/Public/test/index.html new file mode 100755 index 0000000..5955ddd --- /dev/null +++ b/Public/test/index.html @@ -0,0 +1,85 @@ + + + + Kanvas - Test + + + + + + + + + + + + diff --git a/Public/wmd.php b/Public/wmd.php new file mode 100755 index 0000000..1ad86a0 --- /dev/null +++ b/Public/wmd.php @@ -0,0 +1,6 @@ + "update_scripts", + "author" => "KyMAN", + "project" => "Kanvas", + "class" => "Kanvas", + "object" => "kanvas", + "url" => "https://kanvas.k3y.pw", + "project_author" => "KyMAN", + "key_words" => "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library", + "logo" => "/images/kanvas.png", + "language" => "es", + "wmd_file" => "/../WMarkDown/HTML/script.w.md", + "wmd_file_empty" => "/../WMarkDown/HTML/file.w.md", + "ignore_script_paths" => [], + "only" => "/Public" + ], Kanvas\Secrets::wmarkdown)); diff --git a/WMD/JSON/html.files.json b/WMD/JSON/html.files.json new file mode 100755 index 0000000..6dbcddc --- /dev/null +++ b/WMD/JSON/html.files.json @@ -0,0 +1 @@ +{"files":["\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.quality.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.settings.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.starting.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/doc\/kanvas.targets.html","\/mnt\/d\/git\/Kanvas\/Public\/es\/index.html","\/mnt\/d\/git\/Kanvas\/Public\/index.html"],"directories":["\/JSON","\/es","\/es\/doc"]} \ No newline at end of file diff --git a/WMD/dev/ECMAScript/index.w.md b/WMD/dev/ECMAScript/index.w.md new file mode 100755 index 0000000..8fa6e89 --- /dev/null +++ b/WMD/dev/ECMAScript/index.w.md @@ -0,0 +1,24 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# ECMAScript + +[[header_level 0]] +[[include /WMD/dev/Public/Kanvas.ecma.js.w.md]] + + + +[[html_data { + "title" : "ECMAScript - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/ECMAScript/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,ecmascript", + "description" : "Parte ECMAScript del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/PHP/index.w.md b/WMD/dev/PHP/index.w.md new file mode 100755 index 0000000..e720aa1 --- /dev/null +++ b/WMD/dev/PHP/index.w.md @@ -0,0 +1,27 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# PHP + +[[header_level 0]] +[[include /WMD/dev/Public/wmd.php.w.md]] + +[[header_level 0]] +[[include /WMD/dev/Public/wmd_scripts.php.w.md]] + + + +[[html_data { + "title" : "PHP - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/PHP/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,php", + "description" : "Parte PHP del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/Kanvas.ecma.js.w.md b/WMD/dev/Public/Kanvas.ecma.js.w.md new file mode 100755 index 0000000..bc4dcf5 --- /dev/null +++ b/WMD/dev/Public/Kanvas.ecma.js.w.md @@ -0,0 +1,958 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# Kanvas.ecma.js + +```txt +/Public/Kanvas.ecma.js +``` + +## [[plain Kanvas.null_or_undefined]] + +[[wdoc +Método object. +@name Kanvas.null_or_undefined +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 719d9b7663b42ce8e70a4b651eb27d92 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas.allow_nulls]] + +[[wdoc +Método object. +@name Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a1c98a84d6d8b0b8f14fedd400bb007d +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.default_value]] + +[[wdoc +Método object. +@name Kanvas.default_value +@see Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 6699f3c074ebd26160e6b3a8794c6493 +#_default - optional Parámetro _default +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.settings]] + +[[wdoc +Método object. +@name Kanvas.settings +@see Kanvas.default_value +@see Kanvas.allow_nulls +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c05780df830b296ef8a270d7fcadeb98 +#names - optional Parámetro names +#inputs - optional Parámetro inputs +#_default - optional Parámetro _default +#nulls - optional Parámetro nulls +#return - - Retorno. +]] + +## [[plain Kanvas.threads_function]] + +[[wdoc +Método object. +@name Kanvas.threads_function +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 30f4ba8b76dce56fc41434dd6465f058 +#return - - Retorno. +]] + +## [[plain Kanvas.threads_start]] + +[[wdoc +Método object. +@name Kanvas.threads_start +@see Kanvas.settings +@see Kanvas.threads_function +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash cce23b880e33d3e85679d59e082812d8 +#frames_per_second - optional Parámetro frames_per_second +]] + +## [[plain Kanvas.threads_stop]] + +[[wdoc +Método object. +@name Kanvas.threads_stop +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 628fab132ecb593ed3accbec9427a6ea +]] + +## [[plain Kanvas.threads_add]] + +[[wdoc +Método object. +@name Kanvas.threads_add +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 98547e004e14d60c8577718368ffe69e +#callback - optional Parámetro callback +#return - - Retorno. +]] + +## [[plain Kanvas.threads_remove]] + +[[wdoc +Método object. +@name Kanvas.threads_remove +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a73d5bb9c37dd290aef7f312f8fa2c81 +#i - optional Parámetro i +]] + +## [[plain Kanvas.is_html_object]] + +[[wdoc +Método object. +@name Kanvas.is_html_object +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f8cca6ce9a87f4ddf2c68884218d1c12 +#variable - optional Parámetro variable +#return - - Retorno. +]] + +## [[plain Kanvas.preload]] + +[[wdoc +Método object. +@name Kanvas.preload +@see Kanvas.is_html_object +@see Kanvas.settings +@see Kanvas.threads_add +@see Kanvas.threads_remove +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b6298d139217967603995bbc155fa81b +#selector - optional Parámetro selector +#callback - optional Parámetro callback +]] + +## [[plain Kanvas.hash]] + +[[wdoc +Método object. +@name Kanvas.hash +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash cbd619e186a3b4cc88e42b48092e138a +#return - - Retorno. +]] + +## [[plain Kanvas.set_attribute]] + +[[wdoc +Método object. +@name Kanvas.set_attribute +@see Kanvas.is_html_object +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 66c62f05275a277af2cae6fa0ce15bec +#item - optional Parámetro item +#custom_attributes - optional Parámetro custom_attributes +]] + +## [[plain Kanvas.construct]] + +[[wdoc +Método object. +@name Kanvas.construct +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 37628051533825ee303450db783c043e +]] + +## [[plain Kanvas.range_analyze]] + +[[wdoc +Método object. +@name Kanvas.range_analyze +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash b70d0d7c55cff052650f923dfff238cf +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_resize_method]] + +[[wdoc +Método object. +@name Kanvas.on_resize_method +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash a76d2493ecfc4e769f416dbf0b6512b3 +#screen - optional Parámetro screen +]] + +## [[plain Kanvas.position_set]] + +[[wdoc +Método object. +@name Kanvas.position_set +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash a5797156cb2c84f1be97d89806ec8ea8 +]] + +## [[plain Kanvas.start]] + +[[wdoc +Método object. +@name Kanvas.start +@see Kanvas.settings +@see Kanvas.position_set +@see Kanvas.threads_start +@see Kanvas.preload +@see Kanvas.hash +@see Kanvas.set_attribute +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c5c42914486aa98c690dfee43cf0022b +]] + +## [[plain Kanvas.draw]] + +[[wdoc +Método object. +@name Kanvas.draw +@see Kanvas.draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 3e0658a54766de9a8b226dff8e290b09 +#map - optional Parámetro map +#context - optional Parámetro context +]] + +## [[plain Kanvas.refresh_draw]] + +[[wdoc +Método object. +@name Kanvas.refresh_draw +@see Kanvas.draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 13eb2f6574df5ab6d8a4b042ad90f347 +]] + +## [[plain Kanvas.thread_method]] + +[[wdoc +Método object. +@name Kanvas.thread_method +@see Kanvas.refresh_draw +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash af433469fec83091580ca5ada20b6bb9 +]] + +## [[plain Kanvas.value]] + +[[wdoc +Método object. +@name Kanvas.value +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f5494430f37abdc8690b52732565c629 +#value - optional Parámetro value +#quality - optional Parámetro quality +#return - - Retorno. +]] + +## [[plain Kanvas._x]] + +[[wdoc +Método object. +@name Kanvas._x +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 559ab3da3b95bf8d10a31f3d719b2ea1 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas._y]] + +[[wdoc +Método object. +@name Kanvas._y +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 559ab3da3b95bf8d10a31f3d719b2ea1 +#value - optional Parámetro value +#return - - Retorno. +]] + +## [[plain Kanvas.cache_set]] + +[[wdoc +Método object. +@name Kanvas.cache_set +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 603f76ca5fda76d86b5be256077b25e9 +#item - optional Parámetro item +#return - - Retorno. +]] + +## [[plain Kanvas.get_new_cache_i]] + +[[wdoc +Método object. +@name Kanvas.get_new_cache_i +@see Kanvas.cache_set +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash b0d2a1389083540a4357d495c5f0d08c +#item - optional Parámetro item +#return - - Retorno. +]] + +## [[plain Kanvas.cache_clean]] + +[[wdoc +Método object. +@name Kanvas.cache_clean +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash a2b63581e6003dd7d145d86349ed146c +#i - optional Parámetro i +]] + +## [[plain Kanvas.preload_cache_items]] + +[[wdoc +Método object. +@name Kanvas.preload_cache_items +@see Kanvas.preload_cache_items +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 9828faf1c71dd7d96543e60c7b9b9aea +#items - optional Parámetro items +#callback_per_item - optional Parámetro callback_per_item +#callback - optional Parámetro callback +]] + +## [[plain Kanvas.angle]] + +[[wdoc +Método object. +@name Kanvas.angle +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f80170728f63e977a7b75020e9a2efb1 +#x - optional Parámetro x +#y - optional Parámetro y +#randians - optional Parámetro randians +#return - - Retorno. +]] + +## [[plain Kanvas.shadow]] + +[[wdoc +Método object. +@name Kanvas.shadow +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 3e5838dd96848e07e9ec73496e08c62f +#data - optional Parámetro data +#context - optional Parámetro context +]] + +## [[plain Kanvas.border]] + +[[wdoc +Método object. +@name Kanvas.border +@see Kanvas.settings +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash fab5ac8f9418215b319a17e166843729 +#data - optional Parámetro data +#context - optional Parámetro context +]] + +## [[plain Kanvas.draw_image]] + +[[wdoc +Método object. +@name Kanvas.draw_image +@see Kanvas.settings +@see Kanvas._x +@see Kanvas._y +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access private +@hash 109a8296cc4383971af7cc4bd13b46b5 +]] + +## [[plain Kanvas.add_components]] + +[[wdoc +Método object. +@name Kanvas.add_components +@see Kanvas.settings +@see Kanvas.add_components +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f55803884eb16241230454adbefa6c6b +#json - optional Parámetro json +#overwrite - optional Parámetro overwrite +]] + +## [[plain Kanvas.check_mouse]] + +[[wdoc +Método object. +@name Kanvas.check_mouse +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 876b893e02510899ca548c73f0adfe56 +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.on_event]] + +[[wdoc +Método object. +@name Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 686ebb7d44d117801dc85b8a30b0bf57 +#name - optional Parámetro name +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.remove_event]] + +[[wdoc +Método object. +@name Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash ca7e3e68240c00374b401e488407f8d6 +#name - optional Parámetro name +#i - optional Parámetro i +]] + +## [[plain Kanvas.execute_event]] + +[[wdoc +Método object. +@name Kanvas.execute_event +@see Kanvas.range_analyze +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 33c8ba6d8e6f32c4c4da1dd60db07513 +#name - optional Parámetro name +#input - optional Parámetro input +]] + +## [[plain Kanvas.event_range]] + +[[wdoc +Método object. +@name Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e4b8585c6a74d2b41538b1774d2fee40 +#name - optional Parámetro name +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.on_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.on_mouse_move +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e40de2381f36b3c9d8312d6ef8a762f2 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_resize]] + +[[wdoc +Método object. +@name Kanvas.on_resize +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b006e249f4d5adf74d0f7ec45978c1f2 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_click]] + +[[wdoc +Método object. +@name Kanvas.on_click +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 85d6ad332ff2ceb5cbca13e4546ed361 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_key_down]] + +[[wdoc +Método object. +@name Kanvas.on_key_down +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 79025f1cdcb67186db97d1132bb43e62 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.on_key_up]] + +[[wdoc +Método object. +@name Kanvas.on_key_up +@see Kanvas.on_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 73067b92317dc0f59adbd3eab025ca50 +#method - optional Parámetro method +#range - optional Parámetro range +#return - - Retorno. +]] + +## [[plain Kanvas.remove_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.remove_mouse_move +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 2adc625bafbab06d1d6385aab844693c +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_resize]] + +[[wdoc +Método object. +@name Kanvas.remove_resize +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash f0192c53117c1b3e57ec834096136ad2 +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_click]] + +[[wdoc +Método object. +@name Kanvas.remove_click +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 696c4277e38f06fae1fd0781622bad53 +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_key_down]] + +[[wdoc +Método object. +@name Kanvas.remove_key_down +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 63b0a8449fb2a64a6c272aaca90c429b +#i - optional Parámetro i +]] + +## [[plain Kanvas.remove_key_up]] + +[[wdoc +Método object. +@name Kanvas.remove_key_up +@see Kanvas.remove_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 8b8f69cc65cec69309d7bbee875c877b +#i - optional Parámetro i +]] + +## [[plain Kanvas.range_mouse_move]] + +[[wdoc +Método object. +@name Kanvas.range_mouse_move +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 7496d8ac7ff8f0b4f0a406317732b4a4 +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_resize]] + +[[wdoc +Método object. +@name Kanvas.range_resize +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 5f48d71ce7258c7d8f9c35a6ff24ce9c +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_click]] + +[[wdoc +Método object. +@name Kanvas.range_click +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 4dcfaba4ec9eb40c29226dd21f2b3fbc +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_key_down]] + +[[wdoc +Método object. +@name Kanvas.range_key_down +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 8da99fdb35bb1906c7f00a41ad9ad26d +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.range_key_up]] + +[[wdoc +Método object. +@name Kanvas.range_key_up +@see Kanvas.event_range +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash c628c7bef3b981fb42437f6de0e44ab8 +#i - optional Parámetro i +#return - - Retorno. +]] + +## [[plain Kanvas.key_down]] + +[[wdoc +Método object. +@name Kanvas.key_down +@see Kanvas.execute_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 15ee3af73279aa7b18e41c157a0acdea +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.key_up]] + +[[wdoc +Método object. +@name Kanvas.key_up +@see Kanvas.execute_event +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 426a68043d1c42008c39defe498dfe0e +#item - optional Parámetro item +#event - optional Parámetro event +]] + +## [[plain Kanvas.get_margins]] + +[[wdoc +Método object. +@name Kanvas.get_margins +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash e5aa5d927b4260ab1e6a8a4616b7cc8e +#return - - Retorno. +]] + +## [[plain Kanvas.get_position]] + +[[wdoc +Método object. +@name Kanvas.get_position +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 041721aebc4ba3428c96418025f07272 +#return - - Retorno. +]] + +## [[plain Kanvas.get_cells]] + +[[wdoc +Método object. +@name Kanvas.get_cells +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash d6b5083d8473799c6af510fdc459245d +#return - - Retorno. +]] + +## [[plain Kanvas.get_canvas_distance]] + +[[wdoc +Método object. +@name Kanvas.get_canvas_distance +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash 22d705933b1771eed6a395154a1cff24 +#return - - Retorno. +]] + +## [[plain Kanvas.get_cell_size]] + +[[wdoc +Método object. +@name Kanvas.get_cell_size +@lang ECMAScript +@author KyMAN +@since 20211225 +@version 20211225 +@access public +@hash b63b90521c2f76ea0c361fea33c23769 +#return - - Retorno. +]] + +[[html_data { + "title" : "Kanvas.ecma.js - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/Kanvas.ecma.js.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,cma", + "description" : "Kanvas.ecma.js del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/wmd.php.w.md b/WMD/dev/Public/wmd.php.w.md new file mode 100755 index 0000000..705c3e3 --- /dev/null +++ b/WMD/dev/Public/wmd.php.w.md @@ -0,0 +1,23 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# wmd.php + +```txt +/Public/wmd.php +``` + +[[html_data { + "title" : "wmd.php - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/wmd.php.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,main", + "description" : "wmd.php del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/Public/wmd_scripts.php.w.md b/WMD/dev/Public/wmd_scripts.php.w.md new file mode 100755 index 0000000..fa8a374 --- /dev/null +++ b/WMD/dev/Public/wmd_scripts.php.w.md @@ -0,0 +1,23 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] +# wmd_scripts.php + +```txt +/Public/wmd_scripts.php +``` + +[[html_data { + "title" : "wmd_scripts.php - Kanvas", + "url" : "https://kanvas.k3y.pw/Public/wmd_scripts.php.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,main", + "description" : "wmd_scripts.php del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/dev/index.w.md b/WMD/dev/index.w.md new file mode 100755 index 0000000..1eab0c9 --- /dev/null +++ b/WMD/dev/index.w.md @@ -0,0 +1,89 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225 +}]] + +# ECMAScript + +- [/dev/ECMAScript#Kanvas-ecma-js-2 /Public/Kanvas.ecma.js] + - [/dev/ECMAScript#Kanvas-null-or-undefined-2 Kanvas.null\_or\_undefined] + - [/dev/ECMAScript#Kanvas-allow-nulls-2 Kanvas.allow\_nulls] + - [/dev/ECMAScript#Kanvas-default-value-2 Kanvas.default\_value] + - [/dev/ECMAScript#Kanvas-settings-2 Kanvas.settings] + - [/dev/ECMAScript#Kanvas-threads-function-2 Kanvas.threads\_function] + - [/dev/ECMAScript#Kanvas-threads-start-2 Kanvas.threads\_start] + - [/dev/ECMAScript#Kanvas-threads-stop-2 Kanvas.threads\_stop] + - [/dev/ECMAScript#Kanvas-threads-add-2 Kanvas.threads\_add] + - [/dev/ECMAScript#Kanvas-threads-remove-2 Kanvas.threads\_remove] + - [/dev/ECMAScript#Kanvas-is-html-object-2 Kanvas.is\_html\_object] + - [/dev/ECMAScript#Kanvas-preload-2 Kanvas.preload] + - [/dev/ECMAScript#Kanvas-hash-2 Kanvas.hash] + - [/dev/ECMAScript#Kanvas-set-attribute-2 Kanvas.set\_attribute] + - [/dev/ECMAScript#Kanvas-construct-2 Kanvas.construct] + - [/dev/ECMAScript#Kanvas-range-analyze-2 Kanvas.range\_analyze] + - [/dev/ECMAScript#Kanvas-on-resize-method-2 Kanvas.on\_resize\_method] + - [/dev/ECMAScript#Kanvas-position-set-2 Kanvas.position\_set] + - [/dev/ECMAScript#Kanvas-start-2 Kanvas.start] + - [/dev/ECMAScript#Kanvas-draw-2 Kanvas.draw] + - [/dev/ECMAScript#Kanvas-refresh-draw-2 Kanvas.refresh\_draw] + - [/dev/ECMAScript#Kanvas-thread-method-2 Kanvas.thread\_method] + - [/dev/ECMAScript#Kanvas-value-2 Kanvas.value] + - [/dev/ECMAScript#Kanvas-x-2 Kanvas.\_x] + - [/dev/ECMAScript#Kanvas-y-2 Kanvas.\_y] + - [/dev/ECMAScript#Kanvas-cache-set-2 Kanvas.cache\_set] + - [/dev/ECMAScript#Kanvas-get-new-cache-i-2 Kanvas.get\_new\_cache\_i] + - [/dev/ECMAScript#Kanvas-cache-clean-2 Kanvas.cache\_clean] + - [/dev/ECMAScript#Kanvas-preload-cache-items-2 Kanvas.preload\_cache\_items] + - [/dev/ECMAScript#Kanvas-preload-cache-items-2 Kanvas.preload\_cache\_items] + - [/dev/ECMAScript#Kanvas-angle-2 Kanvas.angle] + - [/dev/ECMAScript#Kanvas-shadow-2 Kanvas.shadow] + - [/dev/ECMAScript#Kanvas-border-2 Kanvas.border] + - [/dev/ECMAScript#Kanvas-draw-image-2 Kanvas.draw\_image] + - [/dev/ECMAScript#Kanvas-add-components-2 Kanvas.add\_components] + - [/dev/ECMAScript#Kanvas-check-mouse-2 Kanvas.check\_mouse] + - [/dev/ECMAScript#Kanvas-on-event-2 Kanvas.on\_event] + - [/dev/ECMAScript#Kanvas-remove-event-2 Kanvas.remove\_event] + - [/dev/ECMAScript#Kanvas-execute-event-2 Kanvas.execute\_event] + - [/dev/ECMAScript#Kanvas-event-range-2 Kanvas.event\_range] + - [/dev/ECMAScript#Kanvas-on-mouse-move-2 Kanvas.on\_mouse\_move] + - [/dev/ECMAScript#Kanvas-on-resize-2 Kanvas.on\_resize] + - [/dev/ECMAScript#Kanvas-on-click-2 Kanvas.on\_click] + - [/dev/ECMAScript#Kanvas-on-key-down-2 Kanvas.on\_key\_down] + - [/dev/ECMAScript#Kanvas-on-key-up-2 Kanvas.on\_key\_up] + - [/dev/ECMAScript#Kanvas-remove-mouse-move-2 Kanvas.remove\_mouse\_move] + - [/dev/ECMAScript#Kanvas-remove-resize-2 Kanvas.remove\_resize] + - [/dev/ECMAScript#Kanvas-remove-click-2 Kanvas.remove\_click] + - [/dev/ECMAScript#Kanvas-remove-key-down-2 Kanvas.remove\_key\_down] + - [/dev/ECMAScript#Kanvas-remove-key-up-2 Kanvas.remove\_key\_up] + - [/dev/ECMAScript#Kanvas-range-mouse-move-2 Kanvas.range\_mouse\_move] + - [/dev/ECMAScript#Kanvas-range-resize-2 Kanvas.range\_resize] + - [/dev/ECMAScript#Kanvas-range-click-2 Kanvas.range\_click] + - [/dev/ECMAScript#Kanvas-range-key-down-2 Kanvas.range\_key\_down] + - [/dev/ECMAScript#Kanvas-range-key-up-2 Kanvas.range\_key\_up] + - [/dev/ECMAScript#Kanvas-key-down-2 Kanvas.key\_down] + - [/dev/ECMAScript#Kanvas-key-up-2 Kanvas.key\_up] + - [/dev/ECMAScript#Kanvas-get-margins-2 Kanvas.get\_margins] + - [/dev/ECMAScript#Kanvas-get-position-2 Kanvas.get\_position] + - [/dev/ECMAScript#Kanvas-get-cells-2 Kanvas.get\_cells] + - [/dev/ECMAScript#Kanvas-get-canvas-distance-2 Kanvas.get\_canvas\_distance] + - [/dev/ECMAScript#Kanvas-get-cell-size-2 Kanvas.get\_cell\_size] + +# PHP + +- [/dev/PHP#wmd-php-2 /Public/wmd.php] +- [/dev/PHP#wmd-scripts-php-2 /Public/wmd_scripts.php] + + +[[html_data { + "title" : "Código - Kanvas", + "url" : "https://kanvas.k3y.pw/dev/index.html", + "author" : "KyMAN", + "since" : 20211225, + "version" : 20211225, + "key_words" : "kanvas,canvas,html,js,ecma,script,ecmascript,graphic,engine,library,developt,desarrollo,programación,todo,all", + "description" : "Parte Todo del Kanvas.", + "project" : "Kanvas", + "logo" : "/images/kanvas.png", + "language" : "es" +}]] diff --git a/WMD/es/20230707/index.w.md b/WMD/es/20230707/index.w.md new file mode 100755 index 0000000..2372ab5 --- /dev/null +++ b/WMD/es/20230707/index.w.md @@ -0,0 +1,32 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20230707, + "version" : 20230707 +}]] +# Kanvas + +El proyecto Kanvas no es más que un pequeño motor gráfico basado en CANVAS para gestionar gráficos en 2D, basado en el sistema que usa JavaScript y CSS para interpretar los mismos: un mapeado de parámetros que determinan el GUI. En este caso se unifican los diferentes tipos de gráficos que se puedan establecer como básicos, y sobre éstos, éste trabaja. + +La idea es compactar todos los gráficos sobre un simple JSON, y mediante la accesibilidad de los elementos, irlos variando, siendo más libiano modificar parámetros sobre unn entorno de interpretación que ejecutar cambios sobre el mismo. + +A nivel de HTML se trata de un DIV que contiene un DIV para elementos cacheados y un elemento CANVAS el cual será el GUI. + +A la hora de gestionar los gráficos, Kanvas puede hacer uso de bloques que se cachean en otros componentes CANVAS, los cuales se almacenarán en el DIV caché. + +Por otro lado, en caso de quererse añadir cosas al bloque HTML Kanvas, éstos pueden ser agregados sin problema. + +El objeto Kanvas viene siendo un objeto JavaScript basado en función y no en clase. Puede ser extendido mediante la función "extends" sobre otros objetos. El objeto Kanvas consta de 3 fases iniciales las cuales: + +1. **Constructor**: + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/20230707/", + "author" : "KyMAN", + "since" : 20230707, + "version" : 20230707, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.idea.w.md b/WMD/es/doc/kanvas.idea.w.md new file mode 100755 index 0000000..5de3b78 --- /dev/null +++ b/WMD/es/doc/kanvas.idea.w.md @@ -0,0 +1,76 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20211230, + "version" : 20211230 +}]] +# Idea + +La idea del proyecto es hacer un motor que se encargue de crear imágenes a partir de un Array de +diccionarios con anidamiento que contiene las formas, gráficos, bloques y grupos que dan en sí la +imagen final. Las imágenes se refrescarán cada X tiempo según configuración o según rendimiento del +equipo o navegador donde se esté ejecutando. Con ello facilitará a nivel de proceso iteraciones y +dinamismos con la imagen final, que será lo que vea el usuario, haciendo que con una simple +variación de uno o más valores dentro del Array de diccionarios se permita visualizar este cambio, +permitiendo con ello, movimientos y cualquier otro tipo de interactuación con el entorno. + +El motor constará de un gestor de formas, objetos, etc. Unos serán por defecto y otros pueden ser +añadidos por el usuario, de esta forma permitimos un sistema simplificado de formas y objetos, así +como conjuntos que se repiten y así poder hacer reciclaje de objetos y elementos sin que el usuario +tenga que hacer un sistema en esprofeso para ello. También constará de los eventos que permitan no +solo interactuar al programador o a los elementos entre sí, sino también a los usuarios que consuman +el producto final. + +Todo ello se moverá en JSON con Arrays que contengan diccionarios u objetos. Los Arrays pueden tener +anidados Arrays para hacer capas o bloques, y los objetos pueden tener hijos, por lo general es el +atributo "childs". El orden de las capas se otorga al orden en que se encuentren en los Arrays, +siendo los índices más bajos los que estén al fondo y los que tengan el índica más alto los que +estén más al frente. + +También ha de mencionarse el posicionamiento, que en el plano principal constará de 9 posiciones de +inicio por el hecho de que estamos hablando de un entorno dinámico que muy posiblemente no tenga un +tamaño preestablecido y que se adapte a la pantalla, variando si ésta varía, no siendo igual empezar +a dibujar desde el centro que desde un lado u otro. Las posiciones se basan en el teclado numérico +de un teclado normal de PC de 105 teclas, con los valores del 1 al 9. Es importante destacar que +esto es para empezar el dibujado, a partir de ahí, todo se iniciará en el punto 0x0 desde el objeto, +es decir, si un objeto se pone en la posición 3x5, el punto 0x0 de un elemento hijo será el punto +3x5 del padre, y si se anida otro objeto en el hijo, siendo el nieto del objeto maestro sería la +suma de la posición del hijo y la del padre, y así sucesivamente. Por lo que hay que tener especial +cuidado en las anidaciones, incluso la rotación y el efecto Alpha se heredan. Todo ello no impide +que se pueda trabajar desde el objeto base y anidar con simples Array, lo que sería realmente +agrupar, como sucede en el juego [https://xgravity.k3y.pw/ XGravity]. + +Las iteracciones humanas con el entorno se harán a partir de eventos sobre el objeto HTML CANVAS, +por lo que ha de estar disponible cara el usuario sin que halla elementos por delante, si se monta +un objeto por delante, éste impedirá que se interactúe con el objeto HTML CANVAS en la parte que +éste ocupe. Los eventos recogen posición por lo que se pueden hacer rangos y analizar si se +encuentra en una posición concreta o no, como por ejemplo, para hacer botones o interactuar como +Shooter contra objetos en pantalla. + +Finalmente, nos encontramos ante un entorno gráfico que intenta representar lo mismo en cualquier +proporción y resolución, aunque halla recortes en los lados o extremos superiores e inferiores, así +como variación de calidad por resolución. Para ello se basa en un entorno cuadrado que se conforma +con un lado equivalente al lado más estrecho, es decir, si estamos en un entorno visual horizontal, +el cuadrado se adaptará a la altura del mismo; mientras que si es un entorno vertical se adaptará al +ancho, de esta forma, simplemente ha de extenderse la imagen o el procesado fuera del rango +cuadrado, permitiendo que la parte importante, que es el cuadrado que centra la imagen sea completo. +Con respecto a la resolución se utiliza un sistema de celdas que indica los puntos que tiene el +dibujo (No confundir los puntos de dibujado que son áreas con un número X de píxeles con los propios +píxels), lo que permite que en cualquier resolución salga el mismo dibujo puesto que el dibujo +ocupará Y celdas o cuadrados de dibujo; y cada celda ocupará X píxeles de dibujo. + +Con todo esto, se entiende que la idea es hacer un sistema muy ágil de interpretación del esquema de +dibujo (Arrays y diccionarios), lo que daría lugar a que la complejidad de proceso sea el número de +partículas (Imágenes, formas, etc.) y no los dinamismos ni las interactuaciones humanas sobre el +entorno. + +[[html_data { + "title" : "Kanvas - Objetivos", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.idea.html", + "author" : "KyMAN", + "since" : 20211230, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics,idea,planteamiento", + "description" : "La idea del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.quality.w.md b/WMD/es/doc/kanvas.quality.w.md new file mode 100755 index 0000000..7baef0c --- /dev/null +++ b/WMD/es/doc/kanvas.quality.w.md @@ -0,0 +1,108 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Calidad + +Como ya se dijo anteriormente, Kanvas se basa en la etiqueta HTML CANVAS, a la cual se le puede +establecer un parámetro de codificación de la imagen a mostrar y pocos parámetros referidos a la +calidad más. Un punto importante para este tipo de trabajos es la resolución pues a mayor resolución +más puntos por refresco ha de procesarse, y por lo tanto, también da un aumento significativo del +rendimiento, sin embargo, CANVAS no tiene ningún atributo que gestione esto a excepción de *WIDTH* y +*HEIGHT*, atributos que establecen los píxeles de ancho y alto consecutivamente, que no tienen +porqué coincidir con el ancho y alto real de la imagen, la cual puede ser alterada mediante CSS, sin +ir más lejos, para adaptarse a la pantalla, por lo tanto, la resolución en sí no es dinámica, sino +fija, cuando dicho tamaño puede ser dinámico. Para ello se pensó en 4 atributos los cuales son: + +- **quality**: Calidad global del CANVAS. +- **quality_x**: Calidad en el eje X. +- **quality_y**: Calidad en el eje Y. +- **cells**: Número de celdas en el lado más estrecho. + +Estos atributos representan la calidad porcentual comprendida en el rango \(0,1\] para representar +la resolución real dinámica del elemento CANVAS y por tanto, tener la misma relación de calidad ante +la posibilidad de cambiar de tamaño o aspecto (Proporción). Para poder conseguir ésto, Kanvas +trabaja por detrás adaptando las posiciones y medidas a éstos valores, quedando las siguientes +fórmulas: + +```maths +\displaylines{ + f_x = x \cdot q \cdot qx \\ + f_y = y \cdot q \cdot qy +} +``` + +Por lo tanto, si tenemos una pantalla FullHD y el marco HTML está a pantalla completa, la calidad +global está al 80%, la calidad del eje X está al 90% y del eje Y al 100% tendríamos el siguiente +resultado: + +```maths +\displaylines{ + W_{ancho} = x \cdot q \cdot qx = 1920 \cdot \frac{80}{100} \cdot \frac{90}{100} = 1920 \cdot 0.8 \cdot 0.9 = 1920 \cdot 0.72 = 1382.4 \\ + H_{alto} = y \cdot q \cdot qy = 1080 \cdot \frac{80}{100} \cdot \frac{100}{100} = 1080 \cdot 0.8 \cdot 1 = 1080 \cdot 0.8 = 864 +} +``` + +> **IMPORTANTE**: No se aconseja la modificación de los parámetros de configuración **quality\_x** +ni **quality\_y** por poder alterar de forma inesperada la respuesta a ciertas operaciones, posiciones, o +matices, así como variar el régimen de calidad de forma abrupta. + +El resultado de estas operaciones se pondrán como atributo WIDTH y HEIGHT del elemento HTML CANVAS, +lo que aumentará o disminiurá la calidad de la imagen, y por tanto, menor o mayor consumo de +recursos, así como a la inversa en rendimiento. + +> **IMPORTANTE**: Los valores **quality**, **quality_x** y **quality_y** son valores que no deberían +de ser nunca mayores que 1 (El 100%) por el hecho de lo aquí mostrado, que sería la resolución real +a la que trabajar, lo mismo que tampoco puede ser cero o menor pues supondría una calidad absurda o +imposible. + +Todo esto permite hacer una relación de calidad con resolución variable tanto en el tamaño como +relación de aspecto del marco HTML donde se encuentre el elemento CANVAS, así como poder gestionar a +nivel de código cambios en la calidad sin detener la vista ejecutada, ahora bien, también nos deja +ver que no hay ahora un concepto de posición fijo y que éste depende plenamente de calidad, para +ello se usará una relación de tamaño al número de celdas en el lado más estrecho del marco HTML a +partir del atributo **cells**, de esta forma, si queremos posicionar un objeto dentro del campo de +visión del Kanvas, a partir del resultado anterior, tendríamos la siguiente formulación: + +```maths +\displaylines{ + p_x = \frac{x \cdot q \cdot qx}{c} \\ + p_y = \frac{y \cdot q \cdot qy}{c} \\ + \\ + p_x = \frac{f_x}{c} \\ + p_y = \frac{f_y}{c} +} +``` + +Continuando con el ejemplo anterior, si ponemos que queremos 20 celdas y que queremos un punto el +cual esté en el 5 del eje X y en el 7 del eje Y tenemos: + +> **NOTA**: Cogemos del ejemplo anterior, para determinar el tamaño real de la celda el eje Y por +ser más pequeño que el eje X. + +```maths +\displaylines{ + {tc} = \frac{f_y}{c} = \frac{864}{20} = 43.2 \text{(Tamaño celda)} \\ + \\ + i_x = X \cdot {tc} = 5 \cdot 43.2 = 216 \\ + i_y = Y \cdot {tc} = 7 \cdot 43.2 = 302.4 +} +``` + +De esta forma podemos mover un objeto a partir de las celdas, entendiendo que se puede mover a un +fragmento de una celda concreta con valores absolutos al lienzo y no a la resolución. Dicha idea +imita los DPI de una pantalla Android por ejemplo, que hace una equivalencia de puntos, pero aquí +también se ignora el tamaño, quedando para cualquier monitor, resolución, etc. Exactamente igual. + +[[html_data { + "title" : "Kanvas - Calidad", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.quality.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,calidad", + "description" : "Manual de los parámetros de configuración del Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.settings.w.md b/WMD/es/doc/kanvas.settings.w.md new file mode 100755 index 0000000..014d468 --- /dev/null +++ b/WMD/es/doc/kanvas.settings.w.md @@ -0,0 +1,275 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Configuración + +Al ser una simple librería no contamos con archivos externos de configuración por lo que si queremos +hacer uso de ésta o cambiar los parámetros por defecto de la misma, hemos de hacer a partir del +propio constructor, a partir de meterle al constructor, como primer parámetro, un diccionario con +los parámetros que queremos alterar. + +> **NOTA**: Por defecto, si se deja vacío, se usará la configuración por defecto; si se le mete un +valor String se entenderá como el nombre de la instancia dentro de JavaScript para poder ser +referenciada en los eventos; y si es un diccionario, éste representará cada uno de los parámetros +que queramos alterar o incluso añadir, para hacer uso de éstos, por ejemplo, para nuevos componentes +que se le agreguen al Kanvas o para hacer uso de forma externa al mismo usando el sistema de gestión +de parámetros de configuración del propio Kanvas. Para agregar más parámetros simplemente hemos de +escribirlos con un valor y listo. + +> **IMPORTANTE**: Cuidado a la hora de agregar nuevos parámetros pues si se agrega uno que ya +existe, al existente se le cambiará el valor, pudiendo dar resultados inesperados. + +> **IMPORTANTE**: Si el nombre del objeto no se corresponde con el real, los eventos sobre éste no +funcionarán y se puede correr el riesgo de que los eventos tiren contra otro objeto no esperado. + +Un ejemplo de como gestionar los parámetros puede ser lo siguiente: + +```js +// Objeto Kanvas con los valores de configuración por defecto. +kanvas = new Kanvas(); + +// Objeto Kanvas con cambio de nombre del objeto. +kanvas2 = new Kanvas("kanvas2"); + +// Múltiples objetos Kanvas por diccionario. +objetos_kanvas = { + prueba_1 : new Kanvas("objetos_kanvas.prueba_1"), + prueba_2 : new Kanvas("objetos_kanvas.prueba_2"), + prueba_3 : new Kanvas("objetos_kanvas.prueba_3"), + prueba_n : new Kanvas("objetos_kanvas.prueba_n") +}; + +// Objeto Kanvas con los FPS alterados. +kanvas_slow = new Kanvas({ + object_name : "kanvas_slow", + frames_per_second : 12 +}); + +``` + +Los parámetros de configuración que tiene Kanvas por defecto internamente son los siguientes: + +## quality + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad global +del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality} = (0, 1] +``` + +## quality_x + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad en el eje +X del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality_x} = (0, 1] +``` + +> **NOTA**: Se aconseja dejar dicho valor en 1 por la posibilidad de dar una visualización no +deseada, así como posicionamientos inesperados. + +## quality_y + +Valor decimal mayor que 0 y menor o igual que 1, que representa porcentualmente la calidad en el eje +Y del objeto HTML CANVAS. Su valor por defecto es 1. + +```maths +\text{quality_y} = (0, 1] +``` + +> **NOTA**: Se aconseja dejar dicho valor en 1 por la posibilidad de dar una visualización no +deseada, así como posicionamientos inesperados. + +## cells + +Valor decimal mayor que 0 que representa el número de celdas en que se divide el lado más estrecho +del objeto HTML CANVAS (El lienzo donde se plasmarán los gráficos 2D). Este valor es orientativo +para permitir dar posicionamientos absolutos a los objetos que se metan dentro del CANVAS, similar +al sistema de DPI en Android. Su valor por defecto es 100. + +## origin + +Valor entero positivo comprendido entre 1 y 9, ambos inclusive, que representa el punto 0 (Eje X 0 y +eje Y 0) u origen del cual se empieza a contar positivo o negativo. Este valor representa la +posición de origen según el teclado numérico, siendo los siguientes: + +# Esquina inferior izquierda. +# Inferior centro. +# Esquina inferior derecha. +# Medio izquierda. +# Centro del lienzo. +# Medio derecha. +# Esquina superior izquierda. +# Superior centro. +# Esquina superior derecha. + +
+ + + + + + + + + + + + + + + + + + +
789
456
123
+
+ +Su valor por defecto es 5. + +## frames\_per\_second + +Valor decimal mayor que 0 que representa los fotogramas por segundo, es decir, la tasa de refresco +por segundo, o la cantidad de imágenes o vistas a procesar cada segundo. Por defecto es 60. + +> **IMPORTANTE**: La tasa de fotogramas puede bajar según la capacidad del equipo y los recursos que +consuma el procesado del mapeado del Kanvas. + +> **NOTA**: Los fotogramas no los dará exacto puede excederse en el caso de los Webkit cosa de 3 o 4 +FPS. + +## ratio + +Valor decimal igual o superior a 0 que representa el ratio o relación de aspecto del CANVAS +(Lienzo). Dicho valor puede ser también un valor equivalente a 0 con tipado diferente como puede ser +_null_, _false_, _""_, etc. Los cuales representan que cogerá el ratio por defecto que tenga el +marco donde se instala el GUI del objeto Kanvas. Su valor por defecto es _null_. + +```maths +r = \frac{x}{y} +``` + +> **NOTA**: Para facilitar la visualización del ratio se puede hacer uso de una pequeña división +donde el numerador sea el ancho y el denominador sea el alto, o un un valor decimal que represente +el resultado de dividir el ancho entre el alto. Se entiende con un ratio de pantalla vertical a un +valor superior a 1; una pantalla cuadrada un 1; y una pantalla horizontal cuando es inferior a 1. + +> **NOTA**: El ratio no impedirá que el CANVAS intente coger el máximo área posible del marco HTML +donde se encuentre, simplemente que en el lado donde sobre, éste se centrará automáticamente. + +## overwrite + +Valor booleano que verifica si donde se llame a dicho parámetro, algún o algunos elementos puedan +ser sobreescritos si se da la ocasión. Por defecto es _false_. + +Dicho valor es usado para cuando se intenta agregar elementos nuevos a la configuración entre otros +posibles casos de este tipo. + +## position + +Posición HTML donde instalar el objeto Kanvas, es decir, el DIV con sus contenido CANVAS y cachés. +Dicho valor puede ser un objeto ya cargado propiamente dicho o bien, un selector CSS en formato +String. Su valor por defecto es el selector CSS _"body"_ para ser cargado directamente sobre el +BODY. + +## autostart + +Valor Booleano que verifica si se autoinicia (_true_) o se hace un inicio manual (_false_). Por +defecto su valor es _true_. Para hacer el inicio manual ha de llamarse a la función "start", por +ejemplo: + +```js +// Objeto Kanvas autoiniciado. +kanvas_autoiniciado = new Kanvas({ + object_name : "kanvas_autoiniciado", + autostart : true +}); + +// Objeto Kanvas no autoiniciado. +kanvas_manual = new Kanvas({ + object_name : "kanvas_manual", + autostart : false +}); +// Para iniciar el objeto Kanvas manualmente hemos de hacer tal que así: +kanvas_manual.start(); + +``` + +## object_name + +Valor String que representa el nombre del objeto. Por defecto es _"kanvas"_, sin embargo, si éste +no es el nombre del objeto ha de darse en el constructor del objeto, ya sea mandando como primera +parámetro un String con el nombre de la instancia o bien, en el diccionario de entrada, una llave +con este nombre con el valor del nombre de la instancia. + +Este parámetro es fundamental para que los eventos ataquen al objeto Kanvas en cuestión. + +> **IMPORTANTE**: Si está errado el nombre del objeto éste no funcionará correctamente, incluso +pudiendo atacar a otros objetos Kanvas por cruce de nombres, por ejemplo, usando siempre el valor +por defecto del mismo. + +## class + +Valor String que representa la clase o clases HTML para identificar, por ejemplo, desde JavaScript o +CSS. Por defecto es _"kanvas"_. + +> **IMPORTANTE**: Es importante que si se altera la clase, ésta contenga, entre otras clases +opcionales a decisión del desarrollador, la clase _kanvas_. + +## application + +Valor String que representa el nombre de la aplicación. Por defecto su valor es _Kanvas_, pero puede +ser alterado sin consecuencia alguna, simplemente, el atributo del objeto Kanvas HTML raíz +"data-application" pasará a ser dicho valor. + +## x + +Valor decimal que representa el valor del eje X de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## y + +Valor decimal que representa el valor del eje Y de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## width + +Valor decimal que representa el valor del ancho de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +## height + +Valor decimal que representa el valor del alto de cualquier elemento por defecto. Por defecto, +dicho valor es 0. + +> **NOTA**: Generalmente no se hace uso de este valor pues cada componente o elemento de un +componente ya tiene sus valores por defecto, éste se deja por si no existen dichos valores en la +configuración. + +[[html_data { + "title" : "Kanvas - Configuración", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.settings.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,configuración,parámetros,atributos", + "description" : "Manual de los parámetros de configuración del Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.starting.w.md b/WMD/es/doc/kanvas.starting.w.md new file mode 100755 index 0000000..074648a --- /dev/null +++ b/WMD/es/doc/kanvas.starting.w.md @@ -0,0 +1,69 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620 +}]] +# Iniciando + +Kanvas no es más que una pequeña librería ECMAScript 2015 totalmente autosuficiente, por lo que sólo +requiere de la implementación en HTML de dicha librería para poder ser iniciada. Para ello podemos +hacer uso de cualquiera de las direcciones puestas al principio del manual ([/es/#Kanvas]). El +siguiente ejemplo HTML muestra la creación de un Kanvas vacío que ocupa todo el marco HTML del +navegador. + +```html + + + + Kanvas - Test + + + + + + + + + + + + +``` + +Como podemos ver en el ejemplo, que el propio Kanvas es una clase objeto con la cual creamos un +objeto el cual será el objeto que gestiona todo lo que se verá en este manual. Cada instancia Kanvas +gestionará un único Kanvas en el GUI, permitiendo poder hacer uso de más de un elemento al mismo +tiempo dentro del entorno HTML. + +[[html_data { + "title" : "Kanvas - Iniciando", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.starting.html", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20210620, + "key_words" : "kanvas,canvas,kyman,2d,graphics,iniciar,implementar,incluir", + "description" : "Manual para iniciar Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/doc/kanvas.targets.w.md b/WMD/es/doc/kanvas.targets.w.md new file mode 100755 index 0000000..6d32a1e --- /dev/null +++ b/WMD/es/doc/kanvas.targets.w.md @@ -0,0 +1,29 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210621, + "version" : 20211229 +}]] +# Objetivos + +Aquí aparecerán reflejadas todas las tareas acerca de las tareas que hay que llevar a cabo en el +Kanvas. + +- [X] Crear logo. +- [-] Documentar Kanvas. + - *Repasar funcionalidad.* +- [ ] Generar ejemplos para la documentación del Kanvas. +- [ ] Generar Delta Time Constant. +- [ ] Deslimitar los FPS de forma opcional, reduciendo la tasa de refresco de los 4ms por defecto de +los Intervals. + +[[html_data { + "title" : "Kanvas - Objetivos", + "url" : "https://kanvas.k3y.pw/es/doc/kanvas.targets.html", + "author" : "KyMAN", + "since" : 20210621, + "version" : 20211229, + "key_words" : "kanvas,canvas,kyman,2d,graphics,objetivos,tareas", + "description" : "Tareas a realizar o realizadas en el proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/es/index.w.md b/WMD/es/index.w.md new file mode 100755 index 0000000..79259f8 --- /dev/null +++ b/WMD/es/index.w.md @@ -0,0 +1,55 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230 +}]] +# Kanvas + +El proyecto Kanvas no es más que una pequeña librería JavaScript en ECMAScript 2015 que nos permite +crear y gestionar gráficos 2D sobre un elemento CANVAS gestionado dentro de una etiqueta de capa +DIV, de forma sencilla y limpia, basado en un mapeado Array anidado que nos permite tener tanto la +profundidad como agrupar elementos en diferentes niveles de profundidad, todos ellos ordenados entre +sí. Dichos elementos también están gestionados dentro de la propia librería como elementos de dibujo +o para dibujar. Para poder descargar o hacer uso como CDN de ésta librería se puede utilizar los +siguientes links: + +- https://kanvas.k3y.pw/Kanvas.ecma.js +- https://git.k3y.pw/KyMAN/Kanvas/-/raw/master/Public/Kanvas.ecma.js + +La idea es crear un mapa de los gráficos que se quieren representar en un Array a partir de los +componentes de dibujo que contenga la librería, si hay alguno del cual se quiera hacer uso y no lo +tiene, éste ha de ser implementado por el usuario desarrollador, permitiendo dicha metodología la +reutilización de código para diversos fines. En JavaScript, los objetos almacenados en una variable +funcionan por Mark and Sweep, por tanto son elementos referenciados en memoria y por ello, podemos +moverlos a diferentes puntos del código enviándolo funcionalmente como parámetro donde podrá ser +tratado tanto por Kanvas como por el desarrollador simultáneamente. + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.idea.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.starting.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.settings.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.quality.w.md]] + +[[header_level 0]] +[[include /WMD/es/doc/kanvas.targets.w.md]] + +[[header_level 0]] +[[wdictionaries Diccionario https://wdictionaries.k3y.pw/?es/users,values,own_projects,projects,digital,common]] + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/WMD/index.w.md b/WMD/index.w.md new file mode 100755 index 0000000..a1b65ea --- /dev/null +++ b/WMD/index.w.md @@ -0,0 +1,25 @@ +[[post_data { + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230 +}]] +# Kanvas + +[[links_group [{ + "images" : ["https://i.imgur.com/im1o0gc.png"], + "link" : "/es/", + "text" : "Español", + "self" : true +}] ]] + +[[html_data { + "title" : "Kanvas - Manual", + "url" : "https://kanvas.k3y.pw/es/", + "author" : "KyMAN", + "since" : 20210620, + "version" : 20211230, + "key_words" : "kanvas,canvas,kyman,2d,graphics", + "description" : "Manual del proyecto Kanvas.", + "project" : "Kanvas", + "logo" : "https://kanvas.k3y.pw/images/kanvas.png" +}]] diff --git a/push.bat b/push.bat new file mode 100755 index 0000000..ab8e9c4 --- /dev/null +++ b/push.bat @@ -0,0 +1,12 @@ +@echo off + +if "%~1" == "" ( + set /p text="Text commit: " +) else ( + set text=%~1 +) + +git pull +git add . +git commit -m "%text%" +git push \ No newline at end of file diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..63a9673 --- /dev/null +++ b/push.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +text="$1" + +if [ -z "$1" ]; then + echo "Commit text:" + read text +fi + +git pull +git add . +git commit -m "$text" +git push \ No newline at end of file