Skip to content
Snippets Groups Projects
Commit 7fff3e70 authored by deepdigger's avatar deepdigger
Browse files

SkribblClient: added BackgroundOrder to change CanvasBackground

SkribblServer: added BackgroundOrder
SkribblCanvas: added logic to draw on the board, added Radius,Color,Backgroundcolor,Erase
parent cb7e6725
1 merge request!8Merge Changes into custom-server, mainly paint-functionality
...@@ -10,6 +10,7 @@ import Util, {CallbackHandler,Value,ReadOnlyValue} from "../util/Util.js"; ...@@ -10,6 +10,7 @@ import Util, {CallbackHandler,Value,ReadOnlyValue} from "../util/Util.js";
* @typedef {import("./SkribblServer.js").ClearOrder} ClearOrder * @typedef {import("./SkribblServer.js").ClearOrder} ClearOrder
* @typedef {import("./SkribblServer.js").DrawOrder} DrawOrder * @typedef {import("./SkribblServer.js").DrawOrder} DrawOrder
* @typedef {import("./SkribblServer.js").WordReveal} WordReveal * @typedef {import("./SkribblServer.js").WordReveal} WordReveal
* @typedef {import("./SkribblServer.js").BackgroundOrder} BackgroundOrder
*/ */
/** /**
* @typedef {import("../util/Util.js").DeepReadOnly<T>} DeepReadOnly * @typedef {import("../util/Util.js").DeepReadOnly<T>} DeepReadOnly
...@@ -32,7 +33,7 @@ export default class SkribblClient { ...@@ -32,7 +33,7 @@ export default class SkribblClient {
this._state = new Value(null); this._state = new Value(null);
/** @type {CallbackHandler<[guessData:GuessResponse]>} */ /** @type {CallbackHandler<[guessData:GuessResponse]>} */
this._onGuessCallbacks = new CallbackHandler(); this._onGuessCallbacks = new CallbackHandler();
/** @type {CallbackHandler<[order:ClearOrder|DrawOrder]>} */ /** @type {CallbackHandler<[order:ClearOrder|BackgroundOrder|DrawOrder]>} */
this._onDrawCallbacks = new CallbackHandler(); this._onDrawCallbacks = new CallbackHandler();
/** @type {CallbackHandler<[message:WordReveal]>} */ /** @type {CallbackHandler<[message:WordReveal]>} */
this._onWordRevealCallbacks = new CallbackHandler(); this._onWordRevealCallbacks = new CallbackHandler();
...@@ -55,7 +56,7 @@ export default class SkribblClient { ...@@ -55,7 +56,7 @@ export default class SkribblClient {
}else if(message.action=="guessedWord"){ }else if(message.action=="guessedWord"){
let data = (({action,...data})=>data)(message); let data = (({action,...data})=>data)(message);
this._onGuessCallbacks.callAll(data); this._onGuessCallbacks.callAll(data);
}else if(message.action=="clearCanvas"||message.action=="draw"||message.action=="erase"){ }else if(message.action=="clearCanvas"||message.action=="changeBackgroundColor"||message.action=="draw"||message.action=="erase"){
this._onDrawCallbacks.callAll(message); this._onDrawCallbacks.callAll(message);
}else if(message.action=="revealWord"){ }else if(message.action=="revealWord"){
this._onWordRevealCallbacks.callAll(message); this._onWordRevealCallbacks.callAll(message);
...@@ -197,7 +198,7 @@ export default class SkribblClient { ...@@ -197,7 +198,7 @@ export default class SkribblClient {
/** /**
* Sends the given drawing order to the server and the immediately returns, without waiting for a response. * Sends the given drawing order to the server and the immediately returns, without waiting for a response.
* @param {ClearOrder|DrawOrder} order * @param {ClearOrder|BackgroundOrder|DrawOrder} order
*/ */
draw(order){ draw(order){
this._dataChannel.send(order); this._dataChannel.send(order);
...@@ -205,7 +206,7 @@ export default class SkribblClient { ...@@ -205,7 +206,7 @@ export default class SkribblClient {
/** /**
* Registers a callback to be called whenever someone draws something on the canvas. * Registers a callback to be called whenever someone draws something on the canvas.
* @param {(order:ClearOrder|DrawOrder)=>void} callback * @param {(order:ClearOrder|BackgroundOrder|DrawOrder)=>void} callback
* @param {object} [options] * @param {object} [options]
* @param {Value<boolean>|ReadOnlyValue<boolean>} [options.onlyWhen] when specified, calls the callback only when this is value is true. * @param {Value<boolean>|ReadOnlyValue<boolean>} [options.onlyWhen] when specified, calls the callback only when this is value is true.
*/ */
......
This diff is collapsed.
import SkribblClient from "../logic/SkribblClient.js"; import SkribblClient from "../logic/SkribblClient.js";
import { CustomElement } from "../util/Util.js"; import { CustomElement } from "../util/Util.js";
/**
* @typedef {import("../logic/SkribblServer.js").DrawOrder} DrawOrder
*/
/** /**
* Custom element `<skribbl-canvas>` for the canvas that can be drawn on by whoever is currently drawing. * Custom element `<skribbl-canvas>` for the canvas that can be drawn on by whoever is currently drawing.
...@@ -27,27 +32,122 @@ export default class SkribblCanvas extends CustomElement { ...@@ -27,27 +32,122 @@ export default class SkribblCanvas extends CustomElement {
<canvas width="960" height="720"></canvas> <canvas width="960" height="720"></canvas>
`; `;
this._canvas = this.shadowRoot.querySelector("canvas"); this._canvas = this.shadowRoot.querySelector("canvas");
this._radius = 10;
this._color = "red";
this._client = client;
/**
* looks what kind of order is given, then either draws, erases(=drawing with background color), changes the backgroundcolor or clears the canvas
* Todo: test functionality
*/
client.onDraw(order => { client.onDraw(order => {
// runs whenever the server tells all clients to draw something on the canvas
this._canvas = this.shadowRoot.querySelector("canvas");
var ctx = this._canvas.getContext("2d");
ctx.lineCap = "round";
if (order.action == "draw") {
let x = 960 * order.points[0].x / 1000;
let y = 720 * order.points[0].y / 1000;
ctx.beginPath();
ctx.moveTo(x, y);
let xx = 960 * order.points[1].x / 1000;
let yy = 720 * order.points[1].y / 1000;
ctx.lineTo(xx, yy);
ctx.lineWidth = order.radius;
ctx.strokeStyle = order.color;
ctx.stroke();
} else if (order.action == "erase") {
let x = 960 * order.points[0].x / 1000;
let y = 720 * order.points[0].y / 1000;
ctx.beginPath();
ctx.moveTo(x, y);
let xx = 960 * order.points[1].x / 1000;
let yy = 720 * order.points[1].y / 1000;
ctx.lineTo(xx, yy);
ctx.lineWidth = order.radius;
ctx.strokeStyle = this._backgroundColor;
ctx.stroke();
} else if (order.action == "changeBackgroundColor") {
this._backgroundColor = order.color;
ctx.fillStyle = order.color;
ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);
} else if (order.action == "clearCanvas") {
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
}
// runs whenever the server tells all clients to draw something on the canvas
// TODO draw stuff to the canvas here
console.log("incoming draw order:", order); // just for testing, can be removed once this has been implemented console.log("incoming draw order:", order); // just for testing, can be removed once this has been implemented
}, { onlyWhen: this.connected }); }, { onlyWhen: this.connected });
// TODO whenever the player draws stuff, send it to the server using `client.draw(order)` here
/**
* is allowed to Draw and last known mouse position
*/
this._isDrawing = false;
this._relativeMousePositionX = 0;
this._relativeMousePositionY = 0;
/**
* Sends on MouseMove event if you are allowed to draw a draw event to the server with color, radius and erase/draw
*/
this._canvas.addEventListener("mousemove", e => {
if (this._drawable && this._isDrawing) {
let oldMousePositionX = this._relativeMousePositionX;
let oldMousePositionY = this._relativeMousePositionY;
this.updateRelativeMousePosition(e); // Size not in Percent but in perMille (per Thousand)
/** @type {"draw"|"erase"} */
let actionToDo = "draw";
if (this._erasorActive) {
actionToDo = "erase"
}
/** @type {DrawOrder} */
let coolOrder = { action: actionToDo, color: this._color, radius: this._radius, points: [{ x: oldMousePositionX, y: oldMousePositionY }, { x: this._relativeMousePositionX, y: this._relativeMousePositionY }] };
client.draw(coolOrder);
}
});
/**
* look if you can draw on the canvas
*/
this._canvas.addEventListener("mousedown", e => { this._canvas.addEventListener("mousedown", e => {
let cAction="draw"; this._isDrawing = true;
let coolOrder={action:cAction,color:"#abcdef",radius:10,points:[{x:1,y:1},{x:100,y:100}]}; this.updateRelativeMousePosition(e);
client.draw(coolOrder); });
let uncoolOrder={action:"clearCanvas"};
this._canvas = this.shadowRoot.querySelector("canvas"); this._canvas.addEventListener("mouseup", e => {
var ctx = this._canvas.getContext("2d"); this._isDrawing = false;
ctx.moveTo(0, 0); });
ctx.lineTo(960, 720);
ctx.stroke(); this._canvas.addEventListener("mouseleave", e => {
// for example, this code runs whenever the user clicks on the canvas. "mousemove", "mouseup", "mouseenter" and "mouseleave" events can be monitored similarly. this._isDrawing = false;
}); });
}
/**
* Sets the backgroundColor of the canvas
*/
/** @param {string} backgroundColor */
set backgroundColor(backgroundColor) {
/** @type {import("../logic/SkribblServer.js").BackgroundOrder} */
let coolOrder = { action: "changeBackgroundColor", color: backgroundColor };
this._client.draw(coolOrder);
}
/**
* Tells the relative mouse position on the canvas in per Mille (min0, max1000)
*/
/** @param {MouseEvent} e */
updateRelativeMousePosition(e) {
this._canvas = this.shadowRoot.querySelector("canvas");
let canvasSizeWidth = this._canvas.getBoundingClientRect().width;
let canvasSizeHeight = this._canvas.getBoundingClientRect().height;
this._relativeMousePositionX = Math.round(1000 * e.offsetX / canvasSizeWidth); // Size not in Percent but in perMille (per Thousand)
this._relativeMousePositionY = Math.round(1000 * e.offsetY / canvasSizeHeight); // Size not in Percent but in perMille (per Thousand)
} }
/** /**
...@@ -64,6 +164,38 @@ export default class SkribblCanvas extends CustomElement { ...@@ -64,6 +164,38 @@ export default class SkribblCanvas extends CustomElement {
return this._drawable; return this._drawable;
} }
// TODO add getters and setters for properties like `color` and `radius` here, so they can then be set in `SkribblCanvasContainer.js` whenever the user clicks on the corresponding controls. /**
* which radius the pen should have
*/
/** @param {number} radius */
set radius(radius) {
this._radius = radius;
}
/**
* Which color the pen should have
*/
/** @param {string} color */
set color(color) {
this._color = color;
}
/**
* Whether the erasor is active
*/
/** @param {boolean} erasorActive */
set erasorActive(erasorActive) {
this._penActive = false;
this._erasorActive = erasorActive;
}
/**
* Whether the pen is active
*/
/** @param {boolean} penActive */
set penActive(penActive) {
this._penActive = false;
this._penActive = penActive;
}
} }
customElements.define("skribbl-canvas", SkribblCanvas); customElements.define("skribbl-canvas", SkribblCanvas);
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment