Newer
Older
import SkribblClient from "../logic/SkribblClient.js";
import LatexJS from "../util/Latex.js";
import Util, {CustomElement} from "../util/Util.js";
import SkribblCanvas from "./SkribblCanvas.js";
/**
* Custom element `<skribbl-canvas-container>` that manages the canvas and its overlays.
*/
export default class SkribblCanvasContainer extends CustomElement {
/**
* @param {SkribblClient} client
*/
constructor(client){
super();
this.attachShadow({mode:"open"});
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
position: relative;
}
svg {
display: block;
width: 100%;
}
#container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #ffffff;
border-radius: 5px;
}
#controls {
position: absolute;
top: 100%;
margin-top: 10px;
}
#controls.hidden {
display: none;
}
.button {
margin: auto;
text-align: center;
display:inline-block;
border: 3px solid transparent;
height:40px;
width:40px;
cursor: pointer;
}
.colorButton{
height: 20px;
width: 20px;
}
.widthButton{
height:40px;
width: 40px;
}
.drawButton{
height: 40px;
width: 100px;
}
</style>
<!-- invisible svg to maintain an aspect ratio of 960:720, aka 4:3 -->
<svg viewBox="0 0 960 720"></svg>
<div id="container">
<slot name="overlay"></slot>
</div>
<div id="controls">
<div id = "widthS" class = "button widthButton" style="background: white"> dünn </div>
<div id = "widthM" class = "button widthButton" style="background: white"> mittel </div>
<div id = "widthL" class = "button widthButton" style="background: white"> dick </div>
<div id = "widthXL" class = "button widthButton" style="background: white"> sehr dick </div>
<div id = "pen" class = "button drawButton" style="background:white"> malen </div>
<div id = "erasor" class = "button drawButton" style="background: white"> radieren </div>
<div id = "changeBackgroundColor" class = "button drawButton" style="background: white"> Hintergrund färben </div>
//@todo: vierter Button für Fill
this.colors =["darkred", "DarkRed",
"red", "Firebrick",
"orange", "orange",
"yellow", "yellow",
"lightgreen", "YellowGreen",
"green", "ForestGreen",
"lightblue", "SkyBlue",
"blue", "SlateBlue",
"purple", "BlueViolet",
"pink", "pink",
"lightbrown", "SandyBrown",
"darkbrown", "SaddleBrown",
"black", "black",
"darkgrey", "DarkGrey",
"lightgrey","LightGrey",
"white","white"];
let buttonString = "";
for (let i = 0;i<this.colors.length; i+=2){
buttonString += "<div id = \""+this.colors[i]+"\" class = \"button colorButton\" style=\"background: "+this.colors[i+1]+"\"> </div>";
console.log(buttonString);
}
this._canvas = new SkribblCanvas(client);
this._container = this.shadowRoot.getElementById("container");
this._container.insertBefore(this._canvas,this._container.firstChild);
this._controls = this.shadowRoot.getElementById("controls");
this._controls.insertAdjacentHTML("afterbegin", buttonString);
client.state.onChange(state=>{
/** whether the player should currently be allowed to draw on the canvas */
let allowToDraw = state.hasGameStarted&&state.drawingPlayer==state.playerIndex&&typeof state.word=="string";
this._canvas.drawable = allowToDraw;
this._controls.classList.toggle("hidden",!allowToDraw);
},{onlyWhen:this.connected});
// TODO implement color settings and set the correspondig properties of `this._canvas` whenever they change here.
//Logik fuer die Buttons zur Farbauswahl
let Farbe = "black";
for(let i = 0;i<this.colors.length;i+=2){
this._coolButton = this.shadowRoot.querySelector("#"+this.colors[i]);
this._coolButton.addEventListener("click",e=>{
this._canvas.color = this.colors[i+1];
this.allColorButtonsBorderTransparent();
this.shadowRoot.getElementById(this.colors[i]).style.borderColor = Farbe;
});
}
//Logik fuer Buttons zur Auswahl der Stiftdicke
//@todo: Stiftdicke bestimmen
this.penDrawButtons = ["widthS",
"widthM",
"widthL",
"widthXL"];
let penDrawButtonsSize = [5,10,30,50];
for(let i = 0;i<this.penDrawButtons.length;i+=1){
this._widthSDrawButton = this.shadowRoot.querySelector("#"+this.penDrawButtons[i]);
this._widthSDrawButton.addEventListener("click",e=>{
this._canvas.radius = penDrawButtonsSize[i];
this.allWidthButtonsBorderTransparent();
this.shadowRoot.getElementById(this.penDrawButtons[i]).style.borderColor = Farbe;
});
}
//Logik fuer Buttons (Radieren und Malen)
this._penButton = this.shadowRoot.querySelector("#pen");
this._penButton.addEventListener("click",e=>{
this._canvas.penActive = true;
this.allDrawButtonsBorderTransparent();
this.shadowRoot.getElementById("pen").style.borderColor = Farbe;
});
this._erasorButton = this.shadowRoot.querySelector("#erasor");
this._erasorButton.addEventListener("click",e=>{
this._canvas.erasorActive = true;
this.allDrawButtonsBorderTransparent();
this.shadowRoot.getElementById("erasor").style.borderColor = Farbe;
this._changeBackgroundColorButton = this.shadowRoot.querySelector("#changeBackgroundColor");
this._changeBackgroundColorButton.addEventListener ("click", e=>{
this._canvas.changeBackgroundActive = true;
this.allDrawButtonsBorderTransparent();
this.shadowRoot.getElementById("changeBackgroundColor").style.borderColor = Farbe;
})
/**
* changes bordercolor of all Colorbuttons to transparent
*/
allColorButtonsBorderTransparent() {
for(let i = 0; i<this.colors.length;i+=2){
this.shadowRoot.getElementById(this.colors[i]).style.borderColor = "transparent";
}
}
/**
* changes bordercolor of all Widthbuttons to transparent
*/
allWidthButtonsBorderTransparent() {
for(let i = 0; i<this.penDrawButtons.length;i+=1){
this.shadowRoot.getElementById(this.penDrawButtons[i]).style.borderColor = "transparent";
}
}
/**
* changes bordercolor of all Drawbuttons to transparent
*/
allDrawButtonsBorderTransparent() {
this.shadowRoot.getElementById("pen").style.borderColor = "transparent";
this.shadowRoot.getElementById("erasor").style.borderColor = "transparent";
this.shadowRoot.getElementById("changeBackgroundColor").style.borderColor = "transparent";
//this.shadowRoot.getElementById("widthXL").style.borderColor = "transparent";
}
set overlay(overlay){
if (this._overlay){
this._overlay.remove();
}
this._overlay = overlay;
if (overlay){
overlay.slot = "overlay";
this.appendChild(overlay);
}
}
/**
* @type {SkribblCanvasOverlay}
*/
get overlay(){
return this._overlay;
}
}
/**
* Custom element `<skribbl-canvas-overlay>` for overlays on the `<skribbl-canvas>`-element.
*/
export class SkribblCanvasOverlay extends HTMLElement {
/**
* Constructs a new SkribblCanvasOverlay and appends the given nodes or strings to it.
* @param {(string|Node)[]|import("../logic/SkribblClient.js").WordReveal} data the nodes or data to display
* @param {SkribblClient} client
*/
constructor(data=[],client=null){
super();
this.attachShadow({mode:"open"});
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000000bf;
color: #ffffff;
}
position: absolute;
left: 50%;
top: 50%;
width: 100%;
height: 100%;
}
#contents {
position: absolute;
max-width: 80%;
transform: translate(-50%,-50%);
text-align: center;
font-size: 1.2em;
}
::slotted(button) {
padding: 3px 5px;
margin: 3px;
border: none;
border-radius: 3px;
background: #dfdfdf;
color: #000000;
font-size: 1em;
}
::slotted(button:hover) {
cursor: pointer;
}
table {
display: inline-block;
font-size: 1.1em;
}
td {
padding: 1px 8px;
}
td:first-child {
text-align: left;
}
td:last-child {
text-align: right;
}
h2+latex-js.description {
display: block;
margin-top: -1em;
margin-bottom: 1em;
}
<div id="outer">
<div id="contents">
<slot></slot>
</div>
this._contents = this.shadowRoot.querySelector("#contents");
if (Array.isArray(data)){
this.append(...data);
}else{
let points = data.points.map((points,index)=>({name:client.players.value[index].name,points}));
points.sort((a,b)=>b.points-a.points);
this._contents.innerHTML = `
<h2>The word was: ${Util.htmlEscape(data.word)}</h2>
<table>
${points.map(({name,points})=>`
<tr>
<td>${Util.htmlEscape(name)}:</td>
<td style="color:${points>0?"#00bf00":"#bf0000"}">+${Util.htmlEscape(points.toString())}</td>
</tr>
`).join("")}
</table>
`;
if (data.description){
let latex = new LatexJS(data.description,{macros:data.macros});
latex.className = "description";
this._contents.insertBefore(latex,this._contents.children[1]);
}
}
}
customElements.define("skribbl-canvas-container",SkribblCanvasContainer);
customElements.define("skribbl-canvas-overlay",SkribblCanvasOverlay);