// https://stackoverflow.com/a/29676404 context = document.getElementById("canvas").getContext("2d"); let defaultFillStyle = '#000'; let shapeDebug = true; let shapeDebugColour = '#FF00FF'; class Shape extends Path2D{ constructor(params){ super(); this.shape = params.shape || 'rectangle'; this.name = params.name; this.x = params.x || 0; this.y = params.y || 0; this.width = params.width || 0; this.height = params.height || 0; this.fillStyle = params.fillStyle || false; this.strokeStyle = params.strokeStyle || false; this.lineWidth = params.lineWidth || 0; this.shadow = params.shadow || false; } setShadow(shadow){ this.shadow = shadow; } draw(){ //console.log('Draw Shape: '+this.name); //console.log('X: '+this.x+' Y: '+this.y); //console.log('W: '+this.width+' H: '+this.height); //console.log(''); if (this.fillStyle) { context.fillStyle = this.fillStyle; if(this.shadow){ context.shadowColor = "#333"; context.shadowOffsetX = 1; context.shadowOffsetY = 3; context.shadowBlur = 10; } if(this.shape == 'circle'){ // X,Y,Radius, start, end context.beginPath(); context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI); context.fill(); context.closePath(); }else if(this.shape == 'semi'){ context.beginPath(); context.arc(this.x, this.y, this.width/2, Math.PI, 0); context.fill(); context.closePath(); }else if (this.shape == 'rectangle'){ context.fillRect(this.x, this.y, this.width, this.height); } context.fillStyle = defaultFillStyle; // Reset back to default context.shadowColor = 'transparent'; context.shadowBlur = null; context.shadowOffsetX = null; context.shadowOffsetY = null; } if (this.strokeStyle && this.lineWidth || shapeDebug) { context.strokeStyle = this.strokeStyle; context.lineWidth = this.lineWidth; context.lineWidth = 2; if(!this.strokeStyle && shapeDebug){ context.strokeStyle = shapeDebugColour; } if(this.shape == 'circle'){ // X,Y,Radius, start, end context.beginPath(); context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI); context.stroke(); context.closePath(); }else if(this.shape == 'semi'){ context.beginPath(); context.arc(this.x, this.y, this.width/2, Math.PI, 0); context.stroke(); context.closePath(); }else if (this.shape == 'rectangle'){ context.strokeRect(this.x, this.y, this.width, this.height); } else if (this.shape == 'unit'){ context.beginPath(); context.arc(this.x, this.y, this.width/2, Math.PI, 0); // Start at bottom left of the semi context.moveTo(this.x-this.width/2, this.y); // Draw accross to bottom right of semi context.lineTo(this.x+this.width/2, this.y); // Draw down to the desired height context.lineTo(this.x+this.width/2, this.y+this.height/3); // Draw accross to that height, but aligned to left of semi context.lineTo(this.x-this.width/2, this.y+this.height/3); context.stroke(); context.closePath(); } context.strokeStyle = defaultFillStyle; } } startClip(shape = null){ // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip#creating_a_complex_clipping_region if(this.shape == 'circle'){ // X,Y,Radius, start, end context.beginPath(); context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI); context.fill(); context.closePath(); }else if(this.shape == 'semi'){ context.beginPath(); context.arc(this.x, this.y, this.width/2, Math.PI, 0); context.fill(); context.closePath(); }else if (this.shape == 'rectangle'){ context.fillRect(this.x, this.y, this.width, this.height); } // This is one of the shapes for the card images to sit it // TODO: Will be: unit,token,spell, etc. ALSO will have each shape for UI elements too else if (this.shape == 'unit'){ context.beginPath(); context.arc(this.x, this.y, this.width/2, Math.PI, 0); // Start at bottom left of the semi context.moveTo(this.x-this.width/2, this.y); // Draw accross to bottom right of semi context.lineTo(this.x+this.width/2, this.y); // Draw down to the desired height context.lineTo(this.x+this.width/2, this.y+this.height/3); // Draw accross to that height, but aligned to left of semi context.lineTo(this.x-this.width/2, this.y+this.height/3); context.fill(); context.closePath(); } ctx.save(); // Save the canvas draw before the clip is applied context.clip(); } endClip(){ ctx.restore(); // Restore the canvas draw post clip applied, to get everything else back too } }