You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

395 lines
12 KiB

class Drawer{
constructor(){
this.dim = {x: 5000, y: 5000};
this.viewport = {
x: (this.dim.x - p.width) / 2,
y: (this.dim.y - p.height) / 2,
maxX: this.dim.x,
maxY: this.dim.y,
scroll: 10,
zoom: 1,
zoomV: 2
};
this.oldMouseX = this.mouseX;
this.oldMouseY = this.mouseY;
this.map = new MiniMap($("#minimap"), "#minimap > canvas", true);
//Free draw
this.lines = [];
this.linesToDraw = [];
this.linesImage = p.createGraphics(this.dim.x, this.dim.y);
this.linesImage.background(255);
//Pixel art
this.pixels = [];
this.pixelsToFill = [];
this.gridPixelsToFill = [];
this.gridActive = false;
this.pixelsImage = p.createGraphics(this.dim.x, this.dim.y);
this.pixelsImage.background(255);
this.gridImage = p.createGraphics(this.dim.x, this.dim.y);
this.gridImage.background(255, 0);
this.gridImage.noStroke();
this.gridImage.fill(0, 255 * 0.1);
this.pixelCount = {x: 1000, y: 1000};
this.pixelSize = {x: this.dim.x / this.pixelCount.x, y: this.dim.y / this.pixelCount.y};
for (let x = 0; x < this.pixelCount.x; x++){
let column = [];
for (let y = 0; y < this.pixelCount.y; y++){
let pixel = {x: x, y: y, c: "#FFFFFF"};
column.push(pixel);
if (x % 2 == 0 && (y + 1) % 2 == 0
|| y % 2 == 0 && (x + 1) % 2 == 0)
this.gridPixelsToFill.push(pixel);
}
this.pixels.push(column);
}
this.isCopying = false;
this.drawType = null;
this.thickness = parseInt($("#thickness").val());
this.pixelsMap = new MiniMap($("#pixels_map_holder"), "#pixels_map_holder > canvas", false);
this.linesMap = new MiniMap($("#lines_map_holder"), "#lines_map_holder > canvas", false);
}
get image(){
if (this.type === 'free') return this.linesImage;
if (this.type === 'pixel') return this.pixelsImage;
}
get scrollSpeed(){
return this.viewport.scroll;
}
get mouseX(){
return p.mouseX * this.viewport.zoom + this.viewport.x;
}
get mouseY(){
return p.mouseY * this.viewport.zoom + this.viewport.y;
}
sendDrawing(){
if (this.isDrawing && this.hasDrawnAllLines && this.hasFilledAllPixels){
if (this.type === 'free'){
let pos1 = {x: p.round(this.oldMouseX), y: p.round(this.oldMouseY)};
let pos2 = {x: p.round(this.mouseX), y: p.round(this.mouseY)};
let color = colorPicker.getColor();
let line = {p1: pos1, p2: pos2, c: color, t: this.thickness};
socket.emit('add-line', line);
}
if (this.type === 'pixel'){
let x = p.floor(this.mouseX / (this.dim.x / this.pixelCount.x));
x = p.constrain(x, 0, this.pixelCount.x);
let y = p.floor(this.mouseY / (this.dim.y / this.pixelCount.y));
y = p.constrain(y, 0, this.pixelCount.y);
let color = colorPicker.getColor();
if (color === this.pixels[x][y].c)
return;
let pixel = {x: x, y: y, c: color};
socket.emit('fill-pixel', pixel);
}
let color = colorPicker.getColor();
if (colorPicker.lastSetUsedColor != color)
colorPicker.setUsed(color);
}
}
draw(){
p.clear();
if (this.hasDrawnAllLines && this.hasFilledAllPixels){
this.moveViewport();
this.map.draw(this.image, this.dim, this.viewport);
let x = this.viewport.x;
let y = this.viewport.y;
let w = p.width * this.viewport.zoom;
let h = p.height * this.viewport.zoom;
p.image(this.image, 0, 0, p.width, p.height, x, y, w, h);
if (this.type === 'pixel' && this.gridActive){
p.image(this.gridImage, 0, 0, p.width, p.height, x, y, w, h);
}
}
else {
this.pixelsMap.draw(this.pixelsImage, this.dim, this.viewport);
this.linesMap.draw(this.linesImage, this.dim, this.viewport);
this.updateProgress();
}
let drawSpeed = 800;
for (let line of this.linesToDraw.slice(0, drawSpeed))
this.drawLine(line);
this.linesToDraw.splice(0, drawSpeed);
if (this.linesToDraw.length === 0 && !this.hasDrawnAllLines && this.receivedLines && this.receivedPixels){
this.hasDrawnAllLines = true;
if (this.hasFilledAllPixels)
$("#loading_drawings").fadeOut(200);
}
for (let pixel of this.pixelsToFill.slice(0, drawSpeed))
this.drawPixel(pixel);
this.pixelsToFill.splice(0, drawSpeed);
if (this.pixelsToFill.length === 0 && !this.hasFilledAllPixels && this.receivedPixels && this.receivedLines){
this.hasFilledAllPixels = true;
if (this.hasDrawnAllLines)
$("#loading_drawings").fadeOut(200);
}
for (let pixel of this.gridPixelsToFill.slice(0, drawSpeed))
this.drawGridPixel(pixel);
this.gridPixelsToFill.splice(0, drawSpeed);
this.oldMouseX = this.mouseX;
this.oldMouseY = this.mouseY;
}
moveViewport(){
if (givesFeedback)
return;
let y = 0, x = 0;
if (p.keyIsDown(40) || p.keyIsDown(83))
y += this.scrollSpeed;
if (p.keyIsDown(38) || p.keyIsDown(87))
y -= this.scrollSpeed;
if (p.keyIsDown(37) || p.keyIsDown(65))
x -= this.scrollSpeed;
if (p.keyIsDown(39) || p.keyIsDown(68))
x += this.scrollSpeed;
this.viewport.x += x;
this.viewport.y += y;
let maxX = this.viewport.maxX - p.width * this.viewport.zoom;
let maxY = this.viewport.maxY - p.height * this.viewport.zoom;
if (this.viewport.x > maxX) this.viewport.x = maxX;
if (this.viewport.y > maxY) this.viewport.y = maxY;
if (this.viewport.x < 0) this.viewport.x = 0;
if (this.viewport.y < 0) this.viewport.y = 0;
if (x != 0 || y != 0)
this.sendDrawing();
}
addAll(lines){
for (let line of lines)
this.addLine(line);
}
drawLine(line){
this.linesImage.strokeWeight(line.t);
this.linesImage.stroke(line.c);
this.linesImage.line(line.p1.x, line.p1.y, line.p2.x, line.p2.y);
}
addLine(line){
this.lines.push(line);
this.linesToDraw.push(line);
}
fillPixel(pixel){
this.pixels[pixel.x][pixel.y].c = pixel.c
this.pixelsToFill.push(pixel);
}
fillAll(pixels){
pixels.forEach(c => {
if (!c) return;
c.forEach(p => {
if (!p) return;
this.fillPixel(p);
});
});
}
drawPixel(pixel){
let px = pixel.x * this.pixelSize.x;
let py = pixel.y * this.pixelSize.y;
let w = this.pixelSize.x;
let h = this.pixelSize.y;
this.pixelsImage.fill(pixel.c);
this.pixelsImage.strokeWeight(1);
this.pixelsImage.noStroke();
this.pixelsImage.rect(px, py, w, h);
}
drawGridPixel(pixel){
let px = pixel.x * this.pixelSize.x;
let py = pixel.y * this.pixelSize.y;
let w = this.pixelSize.x;
let h = this.pixelSize.y;
this.gridImage.rect(px, py, w, h);
}
onLinesLoaded(lines){
this.receivedLines = lines;
console.log('Received all lines from server');
if (this.receivedPixels)
this.startDrawing();
}
onPixelsLoaded(pixels){
this.receivedPixels = pixels;
console.log('Received all pixels from server');
if (this.receivedLines)
this.startDrawing();
}
startDrawing(){
$("#action").html('Drawing...');
$('#loading_drawings > *:not(#action)').show();
this.receivedPixels.forEach((c, i, a) => {
a[i] = c.filter(p => p.c !== '#ffffff' && p.c !== '#FFFFFF');
});
this.addAll(this.receivedLines);
this.fillAll(this.receivedPixels);
console.log('Started drawing...');
}
updateProgress(){
if (!(this.receivedLines && this.receivedPixels))
return;
let pixelCountDraw = 0;
this.receivedPixels.forEach(c => pixelCountDraw += c.length);
let allThingsToDraw = this.receivedLines.length + pixelCountDraw;
let thingsToDraw = this.pixelsToFill.length + this.linesToDraw.length;
let progress = thingsToDraw / allThingsToDraw;
progress = progress * 100;
progress = isNaN(progress) ? 0 : progress;
$("#loading_drawings > progress").val(progress);
}
isLineVisible(line){
return this.isPointVisible(line.pos1) || this.isPointVisible(line.pos2);
}
isPointVisible(point){
if (!point) return;
let viewX = this.viewport.x;
let viewY = this.viewport.y;
return point.x - viewX > 0 && point.x - viewX < p.width
&& point.y - viewY > 0 && point.y - viewY < p.height
}
onMouseDown(){
if (p.mouseX > 0 && p.mouseX < p.width){
if (this.isCopying){
this.isCopying = false;
$("body").css('cursor', 'default');
} else {
this.isDrawing = true;
this.sendDrawing();
}
}
this.map.onMouseDown();
}
onMouseUp(){
this.isDrawing = false;
this.map.onMouseUp();
}
onMouseDragged(){
if (this.isDrawing){
this.sendDrawing();
}
this.map.onMouseDragged();
}
onMouseMoved(){
if (this.isCopying){
let vp = this.viewport;
let image = this.image.get(vp.x, vp.y, p.width * vp.zoom, p.height * vp.zoom);
let pixel = image.get(p.mouseX * vp.zoom, p.mouseY * vp.zoom);
colorPicker.updateFromRGB(pixel);
}
}
zoom(delta){
let oldZoom = this.viewport.zoom;
this.viewport.zoom += delta / 100 * this.viewport.zoomV;
if (p.width * this.viewport.zoom > this.dim.x)
this.viewport.zoom = this.dim.x / p.width;
if (p.height * this.viewport.zoom > this.dim.y)
this.viewport.zoom = this.dim.y / height;
if (this.viewport.zoom < 0.1)
this.viewport.zoom = 0.1;
let addZoom = this.viewport.zoom - oldZoom;
this.viewport.x -= addZoom * p.mouseX;
this.viewport.y -= addZoom * p.mouseY;
}
skipDrawing(html){
if (!this.receivedLines || !this.receivedPixels)
return;
$(html).attr('disabled', 'disabled');
setTimeout(() => {
for (let pixel of this.pixelsToFill){
this.drawPixel(pixel);
}
this.pixelsToFill = [];
for (let line of this.linesToDraw){
this.drawLine(line);
}
this.linesToDraw = [];
}, 0);
}
requestServerSave(html){
$(html).attr('disabled', 'disabled');
socket.emit('save-all');
}
answerServerSave(){
console.log('Drawings successfully saved on server');
$('#server_answer').fadeIn(200, 'swing', () => {
setTimeout(() =>
$('#server_answer').fadeOut(200)
, 1000 * 5);
setTimeout(() =>
$('#server_save').attr('disabled', false)
, 1000 * 60 * 5);
});
}
}
function updateDrawType(drawType){
drawer.type = drawType;
if (drawType === 'pixel'){
p.noSmooth();
$("#free_settings").hide();
$('#pixel_settings').show();
}
if (drawType === 'free'){
p.smooth();
$("#free_settings").show();
$('#pixel_settings').hide();
}
}
function startCopyColor(){
drawer.isCopying = true;
$("body").css('cursor', 'crosshair');
}