fix(ecma): Fixing the default Kanvas ECMA file.
This commit is contained in:
parent
1164a8db12
commit
b7cd867778
747
Public/ecma/Kanvas.ecma.js
Normal file
747
Public/ecma/Kanvas.ecma.js
Normal file
@ -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();
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user