This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
SA3/hw3/Claudio_Maggioni/scripts/app.js
2019-10-06 20:22:53 +02:00

142 lines
3.7 KiB
JavaScript

// vim: set ts=2 sw=2 et tw=80:
class App {
static get BRUSHES() {
return {
"PenBrush": new PenBrush(),
"DiscBrush": new DiscBrush(),
"StarBrush": new StarBrush(),
};
}
constructor(conf) {
if (!(typeof conf === 'object' && conf)) {
throw new Error('Argument conf different from specification');
}
this.canvas = document.getElementById(conf.canvas);
if (!this.canvas || this.canvas.tagName !== 'CANVAS') {
throw new Error(`canvas is not a canvas`);
}
this.ctx = this.canvas.getContext('2d');
this.favourites = document.querySelector('div#favourites');
if (typeof conf.buttons === 'object' && conf.buttons) {
this.buttons = {}
for (const b of ['clear', 'undo', 'camera'])
this.buttons[b] = document.getElementById(conf.buttons[b]);
if (this.buttons.clear)
this.buttons.clear.addEventListener('click', () => {
this.erase();
history.clear();
});
if (this.buttons.undo)
this.buttons.undo.addEventListener('click', () => history.pop(this));
if (this.buttons.camera)
this.buttons.camera.addEventListener('click', () => {
const base64 = this.canvas.toDataURL();
const img = document.createElement('img');
img.src = base64;
const span = document.createElement('span');
span.contentEditable = true;
this.favourites.appendChild(img);
this.favourites.appendChild(span);
});
}
this.ctx.lineWidth = 1;
this.strokeStyle = this.constructor.defaultStrokeStyle;
this.brush = "PenBrush";
const brushToolbar = document.querySelector('#brush-toolbar');
for (const name in App.BRUSHES) {
const b = document.createElement('button');
b.innerText = name;
b.addEventListener('click', () => this.brush = name);
brushToolbar.appendChild(b);
}
this.canvas.addEventListener('mousedown', this.startPath.bind(this));
this.canvas.addEventListener('mousemove', this.draw.bind(this));
this.canvas.addEventListener('mouseup', this.endPath.bind(this));
this.canvas.addEventListener('mouseout', this.endPath.bind(this));
}
static get defaultStrokeStyle() {
return 'black';
}
get strokeStyle() {
return this.ctx.strokeStyle;
}
set strokeStyle(style) {
if (typeof style !== 'string') {
throw new Error('style is not a string');
}
this.ctx.strokeStyle = style;
}
get brush() {
return this._brush.name;
}
set brush(brushName) {
this._brush = App.BRUSHES[brushName];
}
erase() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
startPath(e, record = true) {
this.ctx.beginPath();
this.ctx.moveTo(e.offsetX, e.offsetY);
if (record) {
history.initializeNewPath();
history.push(new Stroke(this.brush, e.offsetX, e.offsetY));
}
this.mousedown = true;
}
draw(e, beginNew = true, record = true) {
if (this.mousedown) {
this._brush.draw(this.ctx, this.strokeStyle, e.offsetX, e.offsetY);
if (record) {
history.push(new Stroke(this.brush, e.offsetX, e.offsetY));
}
if (beginNew) {
this.ctx.beginPath();
this.ctx.moveTo(e.offsetX, e.offsetY);
} else {
this.mousedown = false;
}
}
}
endPath(e, record = true) {
this.draw(e, false, record);
}
drawPath(path) {
const last = path.length - 1;
const lastBrush = this.brush;
for (let i = 0; i <= last; i++) {
this.brush = path[i].brushName;
switch(i) {
case 0: this.startPath(path[i], false); break;
case last: this.endPath(path[i], false); break;
default: this.draw(path[i], true, false);
}
}
this.brush = lastBrush;
}
}