layer class, events, injected parameters
This commit is contained in:
@@ -1 +1 @@
|
||||
"use strict";export default class pechatalka{#wrap=document.getElementById("pechatalka");get wrap(){return this.#wrap}#canvas=document.getElementById("pechatalka")?.querySelector(".canvas");get canvas(){return this.#canvas}#result=document.getElementById("pechatalka")?.querySelector(".result");get result(){return this.#result}#layers=new Set();get layers(){return this.#layers}#cost=0;get cost(){return this.#cost}prices={pin:{image:150}};constructor(wrap,canvas,result,inject=false){if(wrap instanceof HTMLElement){this.#wrap=wrap;if(inject){this.#wrap.pechatalka=this}}if(canvas instanceof HTMLElement){this.#canvas=canvas}if(result instanceof HTMLElement){this.#result=result}}moving(target){const canvas=this.#canvas;const from={x:0,y:0};function moving(event){target.style.left=event.clientX-from.x+"px";target.style.top=event.clientY-from.y+"px"}function restore(){target.style.top=target.style.left=null}function start(event){if(event.button===0){[from.x,from.y]=[event.clientX-(parseInt(target.style.left)||0),event.clientY-(parseInt(target.style.top)||0)];window.addEventListener("mousemove",moving,true)}}function end(){window.removeEventListener("mousemove",moving,true)}target.addEventListener("mousedown",start,false);window.addEventListener("mouseup",end,false);canvas.addEventListener("mouseleave",end,false)}scaling(target,type="scale"){function scroll(event){if(type==="scale"){let scale=(parseFloat(target.style.scale)||1)+event.deltaY/1000;if(scale<0.4){scale=0.4}else if(scale>3){scale=3}target.style.scale=scale}else if(type==="width"){const change=event.deltaY/2;const cut=target.parentElement.offsetWidth;const bounds={minimum:cut/2-cut,maximum:cut*2-cut};let zoom=(parseFloat(target.style.getPropertyValue("--width-zoom"))||0)+change;if(zoom<bounds.minimum){zoom=bounds.minimum}else if(zoom>bounds.maximum){zoom=bounds.maximum}else{target.style.left=(parseInt(target.style.left)||0)-change/2+"px";target.style.top=(parseInt(target.style.top)||0)-change/2+"px"}target.style.setProperty("--width-zoom",zoom+"px")}}target.addEventListener("wheel",scroll,false)}image(file){const identifier=this.#layers.entries.length??1;const layer=document.createElement("div");layer.classList.add("layer");layer.setAttribute("id","pechatalka_layer_"+identifier);const button_delete=document.createElement("button");button_delete.classList.add("delete","rounded");button_delete.addEventListener("click",(event)=>{layer.remove();this.#cost-=this.prices.pin.image??0;this.#result.querySelector(".cost").innerText=this.#cost});const trash=document.createElement("i");trash.classList.add("icon","trash");const image=document.createElement("img");image.classList.add("rounded");image.setAttribute("draggable",false);image.setAttribute("src",URL.createObjectURL(file));layer.appendChild(image);button_delete.appendChild(trash);layer.appendChild(button_delete);this.#canvas.appendChild(layer);this.#cost+=this.prices.pin.image??0;this.#result.querySelector(".cost").innerText=this.#cost;this.moving(layer);this.scaling(layer)}}
|
||||
"use strict";export default class pechatalka{#wrap=document.getElementById("pechatalka");get wrap(){return this.#wrap}#canvas=document.getElementById("pechatalka")?.querySelector(".canvas");get canvas(){return this.#canvas}#result=document.getElementById("pechatalka")?.querySelector(".result");get result(){return this.#result}#layers=new Set();get layers(){return this.#layers}#preset=new Map();get preset(){return this.#preset}#cost=0;set cost(value){if(typeof value==="number"){const from=this.#cost;this.#cost=value;if(this.#cost<0){this.#cost=0}this.#events.get("cost")?.get("changed")(this.#cost,from)}}get cost(){return this.#cost}prices={pin:{image:150}};#events=new Map([["layers",new Map([["create",(layer)=>{}]])],["cost",new Map([["changed",(to,from)=>{}]])]]);get events(){return this.#events}constructor(wrap,canvas,result,preset,inject=false){if(wrap instanceof HTMLElement){this.#wrap=wrap;if(inject){this.#wrap.pechatalka=this}}if(canvas instanceof HTMLElement){this.#canvas=canvas}if(result instanceof HTMLElement){this.#result=result}if(preset instanceof Map){this.#preset=preset}}global(name,value=null,preset=false){if(typeof name==="string"){for(const layer of this.#layers){layer.set(name,value)}if(preset){this.#preset.set(name,value)}}}moving(layer){const from={x:0,y:0};function moving(event){layer.wrap.style.left=event.clientX-from.x+"px";layer.wrap.style.top=event.clientY-from.y+"px"}function restore(){layer.wrap.style.top=layer.wrap.style.left=null}function start(event){if(event.button===0){[from.x,from.y]=[event.clientX-(parseInt(layer.wrap.style.left)||0),event.clientY-(parseInt(layer.wrap.style.top)||0)];window.addEventListener("mousemove",moving,true)}}function end(){window.removeEventListener("mousemove",moving,true)}layer.wrap.addEventListener("mousedown",start,false);window.addEventListener("mouseup",end,false);this.#canvas.addEventListener("mouseleave",end,false)}scaling(layer,type="scale"){function scroll(event){if(type==="scale"){let scale=(parseFloat(layer.wrap.style.scale)||1)+event.deltaY/1000;if(scale<0.4){scale=0.4}else if(scale>3){scale=3}layer.wrap.style.scale=scale}else if(type==="width"){const change=event.deltaY/1.5;const cut=target.parentElement.offsetWidth;const bounds={minimum:cut/1.5-cut,maximum:cut*1.5-cut};let zoom=(parseFloat(layer.wrap.style.getPropertyValue("--width-zoom"))||0)+change;if(zoom<bounds.minimum){zoom=bounds.minimum}else if(zoom>bounds.maximum){zoom=bounds.maximum}else{layer.wrap.style.left=(parseInt(layer.wrap.style.left)||0)-change/2+"px";layer.wrap.style.top=(parseInt(layer.wrap.style.top)||0)-change/2+"px"}layer.wrap.style.setProperty("--width-zoom",zoom+"px")}}layer.wrap.addEventListener("wheel",scroll,false)}image(file,cost=0){const identifier=this.#layers.size+1;const wrap=document.createElement("div");wrap.classList.add("layer");wrap.setAttribute("id","pechatalka_layer_"+identifier);const button_delete=document.createElement("button");button_delete.classList.add("delete");const trash=document.createElement("i");trash.classList.add("icon","trash");const image=document.createElement("img");image.setAttribute("draggable",false);image.setAttribute("src",URL.createObjectURL(file));wrap.appendChild(image);button_delete.appendChild(trash);wrap.appendChild(button_delete);this.#canvas.appendChild(wrap);const instance=new layer("image",cost,wrap,image,{delete:button_delete},this.#preset,);this.#layers.add(instance);this.#events.get("layers")?.get("create")(instance);this.cost+=instance.cost;this.moving(instance);this.scaling(instance);button_delete.addEventListener("click",(event)=>{instance.wrap.remove();this.#layers.delete(instance);this.cost-=instance.cost})}}export class layer{#type;set type(value){const types=new Set(["image","film"]);if(types.has(value)){this.#type=value}}get type(){return this.#type}#cost=0;set cost(value){if(typeof value==="number"){const from=this.#cost;this.#cost=value;if(this.#cost<0){this.#cost=0}this.#events.get("cost")?.get("changed")(from,this.#cost)}}get cost(){return this.#cost}#wrap;get wrap(){return this.#wrap}#content;get content(){return this.#content}#buttons=new Map();get buttons(){return this.#buttons}#events=new Map([["cost",new Map([["changed",(to,from)=>{}]])]]);get events(){return this.#events}constructor(type,cost,wrap,content,buttons,preset,inject=false){this.type=type;if(typeof this.#type==="string"){this.cost=cost;if(wrap instanceof HTMLElement){this.#wrap=wrap;if(inject){this.#wrap.layer=this}}if(content instanceof HTMLElement){this.#content=content}if(buttons instanceof Object){for(const[name,element]of Object.entries(buttons)){this.#buttons.set(name,element)}}for(const[name,value]of preset.entries()){this[name]=value}}}set(name,value){const from=this[name];this[name]=value;this.#events.get(name)?.get("set")(this[name],from);return this[name]}toggle(name){this[name]=!this[name]??true;this.#events.get(name)?.get("toggle")(this[name]);return this[name]}}
|
||||
|
565
pechatalka.mjs
565
pechatalka.mjs
@@ -107,18 +107,78 @@ export default class pechatalka {
|
||||
return this.#layers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Preset
|
||||
*
|
||||
* @description
|
||||
* Registry of parameters that will be write into created layers
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#preset = new Map();
|
||||
|
||||
/**
|
||||
* @name Preset (get)
|
||||
*
|
||||
* @description
|
||||
* Registry of parameters that will be write into created layers
|
||||
*
|
||||
* @return {Map}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get preset() {
|
||||
return this.#preset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cost
|
||||
*
|
||||
* @description
|
||||
* The total cost
|
||||
*
|
||||
* @type {number}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#cost = 0;
|
||||
|
||||
/**
|
||||
* @name Cost (set)
|
||||
*
|
||||
* @description
|
||||
* The total cost
|
||||
*
|
||||
* @return {number}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
set cost(value) {
|
||||
if (typeof value === "number") {
|
||||
// Validated the value
|
||||
|
||||
// Initializing the deprecated cost
|
||||
const from = this.#cost;
|
||||
|
||||
// Writing the value
|
||||
this.#cost = value;
|
||||
|
||||
// Filtering by the minimal value
|
||||
if (this.#cost < 0) this.#cost = 0;
|
||||
|
||||
// Processing the `cost changed` event function
|
||||
this.#events.get("cost")?.get("changed")(this.#cost, from);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cost (get)
|
||||
*
|
||||
* @description
|
||||
* The total cost
|
||||
*
|
||||
* @return {number}
|
||||
*
|
||||
* @public
|
||||
@@ -139,22 +199,46 @@ export default class pechatalka {
|
||||
*/
|
||||
prices = {
|
||||
pin: {
|
||||
image: 150
|
||||
}
|
||||
image: 150,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Events
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#events = new Map([
|
||||
["layers", new Map([["create", (layer) => {}]])],
|
||||
["cost", new Map([["changed", (to, from) => {}]])],
|
||||
]);
|
||||
|
||||
/**
|
||||
* @name Events (get)
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get events() {
|
||||
return this.#events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Constructor
|
||||
*
|
||||
* @description
|
||||
* Initialize the instance
|
||||
* Initialize the instance of Pechatalka
|
||||
*
|
||||
* @param {HTMLElement} wrap The wrap element
|
||||
* @param {HTMLElement} canvas The canvas element
|
||||
* @param {HTMLElement} result The result element
|
||||
* @param {(Map|null)} [preset=null] Preset parameters for layers
|
||||
* @param {boolean} [inject=false] Write the instance into the wrap element?
|
||||
*/
|
||||
constructor(wrap, canvas, result, inject = false) {
|
||||
constructor(wrap, canvas, result, preset, inject = false) {
|
||||
if (wrap instanceof HTMLElement) {
|
||||
// Initialized the wrap element
|
||||
|
||||
@@ -178,20 +262,54 @@ export default class pechatalka {
|
||||
// Writing the result
|
||||
this.#result = result;
|
||||
}
|
||||
|
||||
if (preset instanceof Map) {
|
||||
// Received the preset registry
|
||||
|
||||
// Writing the preset registry
|
||||
this.#preset = preset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Global
|
||||
*
|
||||
* @description
|
||||
* Write the parameter into all layers
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
* @param {(Object|string|number|boolean|null)} [value=null] Value of the parameter
|
||||
* @param {boolean} [preset=false] Reinitialize the parameter in the preset registry?
|
||||
*/
|
||||
global(name, value = null, preset = false) {
|
||||
if (typeof name === "string") {
|
||||
// Received required arguments
|
||||
|
||||
for (const layer of this.#layers) {
|
||||
// Iterating over layers
|
||||
|
||||
// Reinitializing the layer parameter
|
||||
layer.set(name, value);
|
||||
}
|
||||
|
||||
if (preset) {
|
||||
// Requested to reinitialize the parameter in the preset registry
|
||||
|
||||
// Writing the parameter into the preset registry
|
||||
this.#preset.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Moving
|
||||
*
|
||||
* @description
|
||||
* Add moving for the target
|
||||
* Add moving for the layer
|
||||
*
|
||||
* @param {HTMLElement} target
|
||||
* @param {layer} layer
|
||||
*/
|
||||
moving(target) {
|
||||
// Initializing the link to the canvas
|
||||
const canvas = this.#canvas;
|
||||
|
||||
moving(layer) {
|
||||
// Initializing the start moving cursor coordinates buffer
|
||||
const from = { x: 0, y: 0 };
|
||||
|
||||
@@ -200,10 +318,10 @@ export default class pechatalka {
|
||||
*/
|
||||
function moving(event) {
|
||||
// Writing the X coordinate
|
||||
target.style.left = event.clientX - from.x + "px";
|
||||
layer.wrap.style.left = event.clientX - from.x + "px";
|
||||
|
||||
// Writing the Y coordinate
|
||||
target.style.top = event.clientY - from.y + "px";
|
||||
layer.wrap.style.top = event.clientY - from.y + "px";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,7 +329,7 @@ export default class pechatalka {
|
||||
*/
|
||||
function restore() {
|
||||
// Restoring initial coordinates
|
||||
target.style.top = target.style.left = null;
|
||||
layer.wrap.style.top = layer.wrap.style.left = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,8 +341,8 @@ export default class pechatalka {
|
||||
|
||||
// Writing the start moving cursor coordinates
|
||||
[from.x, from.y] = [
|
||||
event.clientX - (parseInt(target.style.left) || 0),
|
||||
event.clientY - (parseInt(target.style.top) || 0)
|
||||
event.clientX - (parseInt(layer.wrap.style.left) || 0),
|
||||
event.clientY - (parseInt(layer.wrap.style.top) || 0),
|
||||
];
|
||||
|
||||
// Initializing the event listener
|
||||
@@ -241,16 +359,16 @@ export default class pechatalka {
|
||||
}
|
||||
|
||||
// Initializing event listeners
|
||||
target.addEventListener("mousedown", start, false);
|
||||
layer.wrap.addEventListener("mousedown", start, false);
|
||||
window.addEventListener("mouseup", end, false);
|
||||
canvas.addEventListener("mouseleave", end, false);
|
||||
this.#canvas.addEventListener("mouseleave", end, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Scaling
|
||||
*
|
||||
* @description
|
||||
* Add resizing for the target
|
||||
* Add resizing for the layer
|
||||
*
|
||||
* 1. Resizing by changing the `scale` parameter disables the buttons visibility
|
||||
* outside the cut borders (`overflow: fixed` did not work)
|
||||
@@ -258,10 +376,10 @@ export default class pechatalka {
|
||||
* 2. Resizing by changing the `width` parameter has problems with boundaries,
|
||||
* that is it has movement glitches
|
||||
*
|
||||
* @param {HTMLElement} target
|
||||
* @param {layer} layer
|
||||
* @param {string} [type='scale'] Type of scaling (scale, width)
|
||||
*/
|
||||
scaling(target, type = "scale") {
|
||||
scaling(layer, type = "scale") {
|
||||
/**
|
||||
* @name Scroll
|
||||
*/
|
||||
@@ -270,32 +388,34 @@ export default class pechatalka {
|
||||
// Scaling by changing scale
|
||||
|
||||
// Initializing new scale
|
||||
let scale = (parseFloat(target.style.scale) || 1) + event.deltaY / 1000;
|
||||
let scale = (parseFloat(layer.wrap.style.scale) || 1) +
|
||||
event.deltaY / 1000;
|
||||
|
||||
// Normalization and protection against out of scale boundaries
|
||||
if (scale < 0.4) scale = 0.4;
|
||||
else if (scale > 3) scale = 3;
|
||||
|
||||
// Writing the scale
|
||||
target.style.scale = scale;
|
||||
layer.wrap.style.scale = scale;
|
||||
} else if (type === "width") {
|
||||
// Scaling by changing width
|
||||
|
||||
// Initializing the zoom changing value
|
||||
const change = event.deltaY / 2;
|
||||
const change = event.deltaY / 1.5;
|
||||
|
||||
// Initializing width of the cut space
|
||||
const cut = target.parentElement.offsetWidth;
|
||||
|
||||
// Initializing bounds for zooming
|
||||
const bounds = {
|
||||
minimum: cut / 2 - cut,
|
||||
maximum: cut * 2 - cut
|
||||
minimum: cut / 1.5 - cut,
|
||||
maximum: cut * 1.5 - cut,
|
||||
};
|
||||
|
||||
// Initializing new scale
|
||||
let zoom =
|
||||
(parseFloat(target.style.getPropertyValue("--width-zoom")) || 0) +
|
||||
(parseFloat(layer.wrap.style.getPropertyValue("--width-zoom")) ||
|
||||
0) +
|
||||
change;
|
||||
|
||||
if (zoom < bounds.minimum) zoom = bounds.minimum;
|
||||
@@ -304,53 +424,46 @@ export default class pechatalka {
|
||||
// The layer scale was changed
|
||||
|
||||
// Writing the X coordinate
|
||||
target.style.left =
|
||||
(parseInt(target.style.left) || 0) - change / 2 + "px";
|
||||
layer.wrap.style.left = (parseInt(layer.wrap.style.left) || 0) -
|
||||
change / 2 +
|
||||
"px";
|
||||
|
||||
// Writing the Y coordinate
|
||||
target.style.top =
|
||||
(parseInt(target.style.top) || 0) - change / 2 + "px";
|
||||
layer.wrap.style.top = (parseInt(layer.wrap.style.top) || 0) -
|
||||
change / 2 +
|
||||
"px";
|
||||
}
|
||||
|
||||
// Writing the scale
|
||||
target.style.setProperty("--width-zoom", zoom + "px");
|
||||
layer.wrap.style.setProperty("--width-zoom", zoom + "px");
|
||||
}
|
||||
}
|
||||
|
||||
// Initializing the even listeners
|
||||
target.addEventListener("wheel", scroll, false);
|
||||
layer.wrap.addEventListener("wheel", scroll, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Image
|
||||
*
|
||||
* @description
|
||||
* Add the image into the canvas
|
||||
* Generate and write the image into the canvas
|
||||
*
|
||||
* @param {File} file The file from input FileList
|
||||
* @param {number} [cost=0] The layer cost
|
||||
*/
|
||||
image(file) {
|
||||
image(file, cost = 0) {
|
||||
// Initializing identifier
|
||||
const identifier = this.#layers.entries.length ?? 1;
|
||||
const identifier = this.#layers.size + 1;
|
||||
|
||||
// Creating the layer <div> element
|
||||
const layer = document.createElement("div");
|
||||
layer.classList.add("layer");
|
||||
layer.setAttribute("id", "pechatalka_layer_" + identifier);
|
||||
// Creating the layer wrap <div> element
|
||||
const wrap = document.createElement("div");
|
||||
wrap.classList.add("layer");
|
||||
wrap.setAttribute("id", "pechatalka_layer_" + identifier);
|
||||
|
||||
// Creating the button <button> element
|
||||
const button_delete = document.createElement("button");
|
||||
button_delete.classList.add("delete", "rounded");
|
||||
button_delete.addEventListener("click", (event) => {
|
||||
// Deleting the wrap
|
||||
layer.remove();
|
||||
|
||||
// Removing from the total cost
|
||||
this.#cost -= this.prices.pin.image ?? 0;
|
||||
|
||||
// Writing the total cost into the document
|
||||
this.#result.querySelector(".cost").innerText = this.#cost;
|
||||
});
|
||||
button_delete.classList.add("delete");
|
||||
|
||||
// Creating the trash icon <i> element
|
||||
const trash = document.createElement("i");
|
||||
@@ -358,26 +471,358 @@ export default class pechatalka {
|
||||
|
||||
// Creating the image <img> element
|
||||
const image = document.createElement("img");
|
||||
image.classList.add("rounded");
|
||||
image.setAttribute("draggable", false);
|
||||
image.setAttribute("src", URL.createObjectURL(file));
|
||||
|
||||
// Writing into the gallery
|
||||
layer.appendChild(image);
|
||||
wrap.appendChild(image);
|
||||
button_delete.appendChild(trash);
|
||||
layer.appendChild(button_delete);
|
||||
this.#canvas.appendChild(layer);
|
||||
wrap.appendChild(button_delete);
|
||||
this.#canvas.appendChild(wrap);
|
||||
|
||||
// Initializing the layer instance
|
||||
const instance = new layer(
|
||||
"image",
|
||||
cost,
|
||||
wrap,
|
||||
image,
|
||||
{
|
||||
delete: button_delete,
|
||||
},
|
||||
this.#preset,
|
||||
);
|
||||
|
||||
// Writing into the layers registry
|
||||
this.#layers.add(instance);
|
||||
|
||||
// Processing the `layer create` event function
|
||||
this.#events.get("layers")?.get("create")(instance);
|
||||
|
||||
// Adding to the total cost
|
||||
this.#cost += this.prices.pin.image ?? 0;
|
||||
|
||||
// Writing the total cost into the document
|
||||
this.#result.querySelector(".cost").innerText = this.#cost;
|
||||
this.cost += instance.cost;
|
||||
|
||||
// Adding moving for the layer
|
||||
this.moving(layer);
|
||||
this.moving(instance);
|
||||
|
||||
// Adding scaling for the layer
|
||||
this.scaling(layer);
|
||||
this.scaling(instance);
|
||||
|
||||
// Initializing the event listener function
|
||||
button_delete.addEventListener("click", (event) => {
|
||||
// Deleting the layer root element
|
||||
instance.wrap.remove();
|
||||
|
||||
// Deleting from the layer registry
|
||||
this.#layers.delete(instance);
|
||||
|
||||
// Substraction from the total cost
|
||||
this.cost -= instance.cost;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class layer {
|
||||
/**
|
||||
* @name Type
|
||||
*
|
||||
* @description
|
||||
* The layr type
|
||||
*
|
||||
* @type {string}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#type;
|
||||
|
||||
/**
|
||||
* @name Type (set)
|
||||
*
|
||||
* @description
|
||||
* The layr type
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
set type(value) {
|
||||
// Initializing types of layers
|
||||
const types = new Set(["image", "film"]);
|
||||
|
||||
// Writing the value
|
||||
if (types.has(value)) this.#type = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Type (get)
|
||||
*
|
||||
* @description
|
||||
* The layr type
|
||||
*
|
||||
* @return {string}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get type() {
|
||||
// Exit (success)
|
||||
return this.#type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cost
|
||||
*
|
||||
* @description
|
||||
* The layr cost
|
||||
*
|
||||
* @type {number}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#cost = 0;
|
||||
|
||||
/**
|
||||
* @name Cost (set)
|
||||
*
|
||||
* @description
|
||||
* The layer cost
|
||||
*
|
||||
* @return {number}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
set cost(value) {
|
||||
if (typeof value === "number") {
|
||||
// Validated the value
|
||||
|
||||
// Initializing the deprecated cost
|
||||
const from = this.#cost;
|
||||
|
||||
// Writing the value
|
||||
this.#cost = value;
|
||||
|
||||
// Filtering by the minimal value
|
||||
if (this.#cost < 0) this.#cost = 0;
|
||||
|
||||
// Processing the `cost changed` event function
|
||||
this.#events.get("cost")?.get("changed")(from, this.#cost);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cost (get)
|
||||
*
|
||||
* @description
|
||||
* The layer cost
|
||||
*
|
||||
* @return {number}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get cost() {
|
||||
return this.#cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Wrap
|
||||
*
|
||||
* @description
|
||||
* The layer root element
|
||||
*
|
||||
* @type {HTMLElement}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#wrap;
|
||||
|
||||
/**
|
||||
* @name Wrap (get)
|
||||
*
|
||||
* @description
|
||||
* The layer root element
|
||||
*
|
||||
* @return {HTMLElement}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get wrap() {
|
||||
return this.#wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Content
|
||||
*
|
||||
* @description
|
||||
* The layer target content element
|
||||
*
|
||||
* @type {HTMLElement}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#content;
|
||||
|
||||
/**
|
||||
* @name Content (get)
|
||||
*
|
||||
* @description
|
||||
* The layer target content element
|
||||
*
|
||||
* @return {HTMLElement}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get content() {
|
||||
return this.#content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Buttons
|
||||
*
|
||||
* @description
|
||||
* The layer buttons elements registry
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#buttons = new Map();
|
||||
|
||||
/**
|
||||
* @name Buttons (get)
|
||||
*
|
||||
* @description
|
||||
* The layer buttons elements registry
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get buttons() {
|
||||
return this.#buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Events
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
#events = new Map([
|
||||
["cost", new Map([["changed", (to, from) => {}]])],
|
||||
]);
|
||||
|
||||
/**
|
||||
* @name Events (get)
|
||||
*
|
||||
* @type {Map}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
get events() {
|
||||
return this.#events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Constructor
|
||||
*
|
||||
* @description
|
||||
* Initialize the instance of the layer
|
||||
*
|
||||
* @param {string} type The layer type
|
||||
* @param {number} cost The layer cost
|
||||
* @param {HTMLElement} wrap The layer root element
|
||||
* @param {HTMLElement} content The layer target content element
|
||||
* @param {object} buttons The layer buttons elements
|
||||
* @param {Map} preset Preset parameters
|
||||
* @param {boolean} [inject=false] Write the instance into the element?
|
||||
*/
|
||||
constructor(type, cost, wrap, content, buttons, preset, inject = false) {
|
||||
// Writing the layer type
|
||||
this.type = type;
|
||||
|
||||
if (typeof this.#type === "string") {
|
||||
// Initialized the layer type
|
||||
|
||||
// Writing the layer cost
|
||||
this.cost = cost;
|
||||
|
||||
if (wrap instanceof HTMLElement) {
|
||||
// Received the layer root element
|
||||
|
||||
// Writing the layer root element
|
||||
this.#wrap = wrap;
|
||||
|
||||
// Writing the instance into the layer root element
|
||||
if (inject) this.#wrap.layer = this;
|
||||
}
|
||||
|
||||
if (content instanceof HTMLElement) {
|
||||
// Received the layer target content element
|
||||
|
||||
// Writing the layer target content element
|
||||
this.#content = content;
|
||||
}
|
||||
|
||||
if (buttons instanceof Object) {
|
||||
// Received the layer buttons elements
|
||||
|
||||
for (const [name, element] of Object.entries(buttons)) {
|
||||
// Iterating over the layers buttons elements
|
||||
|
||||
// Writing into the layer buttons registry
|
||||
this.#buttons.set(name, element);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [name, value] of preset.entries()) {
|
||||
// Iterating over preset parameters
|
||||
|
||||
// Writing the parameter
|
||||
this[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Set
|
||||
*
|
||||
* @description
|
||||
* Set the parameter value
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
* @param {(Object|string|number|boolean|null)} value Value of the parameter
|
||||
*
|
||||
* @return {boolean} The new parameter value
|
||||
*/
|
||||
set(name, value) {
|
||||
// Initializing the old parameter value
|
||||
const from = this[name];
|
||||
|
||||
// Writing the value
|
||||
this[name] = value;
|
||||
|
||||
// Processing the parameter `set` event function
|
||||
this.#events.get(name)?.get("set")(this[name], from);
|
||||
|
||||
// Exit (success)
|
||||
return this[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Toggle
|
||||
*
|
||||
* @description
|
||||
* Toggle the parameter valu
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
*
|
||||
* @return {boolean} The new parameter value
|
||||
*/
|
||||
toggle(name) {
|
||||
// Writing the value
|
||||
this[name] = !this[name] ?? true;
|
||||
|
||||
// Processing the parameter `toggle` event function
|
||||
this.#events.get(name)?.get("toggle")(this[name]);
|
||||
|
||||
// Exit (success)
|
||||
return this[name];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user