|
|
|
class Layer {
|
|
|
|
constructor({height=600, width=800}) {
|
|
|
|
this.drawCanvas = new Canvas({height, width});
|
|
|
|
this.selectCanvas = new Canvas({height, width});
|
|
|
|
this.active = false;
|
|
|
|
|
|
|
|
const previewElement = document.createElement('div');
|
|
|
|
previewElement.className = 'layer-preview';
|
|
|
|
this.previewElement = previewElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
setHeight({height}) {
|
|
|
|
this.height = height;
|
|
|
|
this.drawCanvas.setHeight(height);
|
|
|
|
this.selectCanvas.setHeight(height);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
setWidth({width}) {
|
|
|
|
this.width = width;
|
|
|
|
this.drawCanvas.setWidth(width);
|
|
|
|
this.selectCanvas.setWidth(width);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
resize({height, width}) {
|
|
|
|
this.height = height;
|
|
|
|
this.width = width;
|
|
|
|
this.drawCanvas.resize({height, width});
|
|
|
|
this.selectCanvas.resize({height, width});
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshPreviewElement() {
|
|
|
|
this.previewElement.src = this.drawCanvas.toDataURL();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class Layers {
|
|
|
|
constructor({easelElement, controllersElement, height=600, width=800, backgroundColor=new Color(255, 255, 255)}) {
|
|
|
|
this.backgroundColor = backgroundColor;
|
|
|
|
this.height = height;
|
|
|
|
this.width = width;
|
|
|
|
this.easelElement = easelElement;
|
|
|
|
this.controllersElement = controllersElement;
|
|
|
|
this.zoom = 1;
|
|
|
|
this.layers = [
|
|
|
|
new Layer({height: this.height, width: this.width}).fill({color: this.backgroundColor}),
|
|
|
|
new Layer({height: this.height, width: this.width})
|
|
|
|
];
|
|
|
|
this.activeIndex = 1;
|
|
|
|
this.refresh();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setHeight({height}) {
|
|
|
|
this.height = height;
|
|
|
|
this.easelElement.style.height = `${height}px`;
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
layer.setHeight(height);
|
|
|
|
});
|
|
|
|
this.layers[0].fill({color: this.background});
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
setWidth({width}) {
|
|
|
|
this.width = width;
|
|
|
|
this.easelElement.style.width = `${width}px`;
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
layer.setWidth(width);
|
|
|
|
});
|
|
|
|
this.layers[0].fill({color: this.background});
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
getActive() {
|
|
|
|
return this.layers[this.activeIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
resize({height, width}) {
|
|
|
|
this.height = height;
|
|
|
|
this.width = width;
|
|
|
|
this.easelElement.style.height = `${height}px`;
|
|
|
|
this.easelElement.style.width = `${width}px`;
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
layer.resize({height, width});
|
|
|
|
});
|
|
|
|
this.layers[0].fill({color: this.background});
|
|
|
|
}
|
|
|
|
|
|
|
|
add() {
|
|
|
|
const layer = new Layer();
|
|
|
|
this.layers.push(layer);
|
|
|
|
layer.moveUpButton.addEventListener('click', () => {
|
|
|
|
this.moveUp(layer);
|
|
|
|
});
|
|
|
|
layer.moveDownButton.addEventListener('click', () => {
|
|
|
|
this.moveDown(layer);
|
|
|
|
});
|
|
|
|
layer.deleteButton.addEventListener('click', () => {
|
|
|
|
layer.remove();
|
|
|
|
this.delete(layer);
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delete({layer}) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (index > -1) {
|
|
|
|
this.layers.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switchIndex({index1, index2}) {
|
|
|
|
const temp = this.layers[index1];
|
|
|
|
this.layers[index1] = this.layers[index2];
|
|
|
|
this.layers[index2] = temp;
|
|
|
|
this.refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
mergeIndex({index1, index2}) {
|
|
|
|
this.layers[index1].add(this.layers[index2]);
|
|
|
|
this.delete(this.layers[index2]);
|
|
|
|
this.refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
moveUp = function({layer}) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (index === 0 || index === this.layers.length - 1) return;
|
|
|
|
this.switchIndex({index1: index, index2: index + 1});
|
|
|
|
}
|
|
|
|
|
|
|
|
moveDown = function({layer}) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (index === 0 || index === 1) return;
|
|
|
|
this.switchIndex({index1: index, index2: index - 1});
|
|
|
|
}
|
|
|
|
|
|
|
|
mergeUp = function({layer}) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (index === 0 || index === this.layers.length - 1) return
|
|
|
|
this.mergeIndex({index1: index, index2: index + 1});
|
|
|
|
}
|
|
|
|
|
|
|
|
mergeDown = function({layer}) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (index === 0 || index === 1) return;
|
|
|
|
this.mergeIndex({index2: index, index1: index - 1});
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshEasel() {
|
|
|
|
this.easelElement.innerHTML = '';
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
console.log("test");
|
|
|
|
this.easelElement.appendChild(layer.drawCanvas);
|
|
|
|
this.easelElement.appendChild(layer.selectCanvas);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshControllers() {
|
|
|
|
this.controllersElement.innerHTML = '';
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
|
|
|
|
const controllerElement = document.createElement('div');
|
|
|
|
controllerElement.className = 'layer-controller';
|
|
|
|
|
|
|
|
const previewElement = this.layers.previewElement;
|
|
|
|
previewElement.addEventListener('click', () => {
|
|
|
|
this.activeIndex = this.layers.indexOf(layer);
|
|
|
|
});
|
|
|
|
controllerElement.appendChild(previewElement);
|
|
|
|
|
|
|
|
const moveButtons = document.createElement('div');
|
|
|
|
moveButtons.classList.add('button');
|
|
|
|
moveButtons.classList.add('layer-move-buttons');
|
|
|
|
moveButtons.className = 'layer-move-buttons';
|
|
|
|
|
|
|
|
const moveUpButton = document.createElement('div');
|
|
|
|
moveUpButton.classList.add('button');
|
|
|
|
moveUpButton.classList.add('layer-move-button');
|
|
|
|
moveUpButton.innerHTML = '<i class="fa-solid fa-arrow-up"></i>';
|
|
|
|
moveUpButton.addEventListener('click', () => {
|
|
|
|
this.moveUp({layer});
|
|
|
|
});
|
|
|
|
|
|
|
|
moveButtons.appendChild(layer.moveUpButton);
|
|
|
|
|
|
|
|
const moveDownButton = document.createElement('div');
|
|
|
|
moveDownButton.classList.add('button');
|
|
|
|
moveDownButton.classList.add('layer-move-button');
|
|
|
|
moveDownButton.innerHTML = '<i class="fa-solid fa-arrow-down"></i>';
|
|
|
|
moveDownButton.addEventListener('click', () => {
|
|
|
|
this.moveDown({layer});
|
|
|
|
});
|
|
|
|
|
|
|
|
layer.moveButtons.appendChild(layer.moveDownButton);
|
|
|
|
|
|
|
|
layer.controllerElement.appendChild(layer.moveButtons);
|
|
|
|
|
|
|
|
const mergeButtons = document.createElement('div');
|
|
|
|
mergeButtons.classList.add('button');
|
|
|
|
mergeButtons.classList.add('layer-merge-buttons');
|
|
|
|
mergeButtons.className = 'layer-merge-buttons';
|
|
|
|
|
|
|
|
const mergeUpButton = document.createElement('div');
|
|
|
|
mergeUpButton.classList.add('button');
|
|
|
|
mergeUpButton.classList.add('layer-merge-button');
|
|
|
|
mergeUpButton.innerHTML = '<i class="fa-solid fa-angles-up"></i>';
|
|
|
|
mergeUpButton.addEventListener('click', () => {
|
|
|
|
this.mergeUp({layer});
|
|
|
|
});
|
|
|
|
|
|
|
|
mergeButtons.appendChild(layer.mergeUpButton);
|
|
|
|
|
|
|
|
layer.controllerElement.appendChild(layer.mergeButtons);
|
|
|
|
|
|
|
|
const deleteButton = document.createElement('div');
|
|
|
|
deleteButton.classList.add('button');
|
|
|
|
deleteButton.classList.add('layer-delete-button');
|
|
|
|
deleteButton.innerHTML = '<i class="fa-solid fa-trash-can"></i>';
|
|
|
|
deleteButton.addEventListener('click', () => {
|
|
|
|
this.delete({layer});
|
|
|
|
});
|
|
|
|
|
|
|
|
layer.controllerElement.appendChild(layer.deleteButton);
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshPreviews() {
|
|
|
|
this.layers.forEach(layer => {
|
|
|
|
layer.refreshPreviewElement();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
refresh() {
|
|
|
|
console.log("test");
|
|
|
|
this.refreshEasel();
|
|
|
|
this.refreshControllers();
|
|
|
|
this.refreshPreviews();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|