Created
May 28, 2022 22:43
-
-
Save shawnco/859268523f7c0389ac8d84d5a7273017 to your computer and use it in GitHub Desktop.
Collaborative Drawing App files as of article 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Collaborative Drawing App</title> | |
<style type="text/css"> | |
canvas { | |
border: 1px solid black; | |
} | |
.palette { | |
border: 1px solid black; | |
display: inline-block; | |
margin: 2px; | |
height: 25px; | |
width: 25px; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Collaborative Drawing App</h1> | |
<div> | |
<canvas id="canvas" height="500px" width="500px"></canvas><br /> | |
<b>Mode:</b> <span id="mode"></span><br /> | |
<b>Message:</b> <span id="message"></span> | |
</div> | |
<div id="palette"> | |
<div id="row-1"> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
</div> | |
<div id="row-2"> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
<div class="palette"></div> | |
</div> | |
</div> | |
<div id="draw-methods"> | |
<button onclick="canvas.setMode('Line')">Line</button> | |
<button onclick="canvas.setMode('Hollow Rectangle')">Hollow Rectangle</button> | |
<button onclick="canvas.setMode('Filled Rectangle')">Filled Rectangle</button> | |
<button onclick="canvas.setMode('Hollow Circle')">Hollow Circle</button> | |
<button onclick="canvas.setMode('Filled Circle')">Filled Circle</button> | |
</div> | |
<script type="text/javascript" src="./script.js"></script> | |
<script type="text/javascript"> | |
const canvas = new Canvas(); | |
const palette = new Palette(); | |
palette.draw(canvas); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Canvas { | |
constructor() { | |
this.canvas = document.querySelector('#canvas'); | |
this.ctx = this.canvas.getContext('2d'); | |
this.activeColor = '#000000'; | |
this.startPoint = null; | |
this.endPoint = null; | |
this.pointMode = 'start'; | |
this.mode = 'Line'; | |
this.handleDraw = this.handleDraw.bind(this); | |
this.canvas.addEventListener('click', this.handleDraw); | |
this.shapeMessages = [ | |
{ type: 'line', start: 'Select the starting point', end: 'Select the ending point' }, | |
{ type: 'rectangle', start: 'Select the first corner', end: 'Select the second corner' }, | |
{ type: 'circle', start: 'Select the middle of the circle', end: 'Select the edge of the circle' } | |
]; | |
this.displayMode(); | |
this.displayMessage(); | |
} | |
setColor(color) { | |
this.activeColor = color; | |
this.ctx.strokeStyle = color; | |
this.ctx.fillStyle = color; | |
} | |
setMode(mode) { | |
this.mode = mode; | |
this.displayMode(); | |
this.displayMessage(); | |
} | |
handleDraw(e) { | |
const rect = this.canvas.getBoundingClientRect(); | |
const x = e.clientX - rect.left; | |
const y = e.clientY - rect.top; | |
if (this.pointMode == 'start') { | |
this.startPoint = [x, y]; | |
this.pointMode = 'end'; | |
} else if (this.pointMode == 'end') { | |
this.pointMode = 'start'; | |
this.endPoint = [x, y]; | |
// do the drawing | |
if (this.mode == 'Line') { | |
this.drawLine(this.startPoint, this.endPoint); | |
} else if (this.mode == 'Hollow Rectangle') { | |
this.drawHollowRectangle(this.startPoint, this.endPoint); | |
} else if (this.mode == 'Filled Rectangle') { | |
this.drawFilledRectangle(this.startPoint, this.endPoint); | |
} else if (this.mode == 'Hollow Circle') { | |
this.drawHollowCircle(this.startPoint, this.endPoint); | |
} else if (this.mode == 'Filled Circle') { | |
this.drawFilledCircle(this.startPoint, this.endPoint); | |
} | |
this.startPoint = null; | |
this.endPoint = null; | |
} | |
this.displayMessage(); | |
} | |
drawLine(startPoint, endPoint) { | |
this.ctx.beginPath(); | |
this.ctx.moveTo(startPoint[0], startPoint[1]); | |
this.ctx.lineTo(endPoint[0], endPoint[1]); | |
this.ctx.stroke(); | |
} | |
drawHollowRectangle(startPoint, endPoint) { | |
this.ctx.beginPath(); | |
this.ctx.strokeRect( | |
startPoint[0], | |
startPoint[1], | |
endPoint[0] - startPoint[0], | |
endPoint[1] - startPoint[1] | |
); | |
} | |
drawFilledRectangle(startPoint, endPoint) { | |
this.ctx.beginPath(); | |
this.ctx.fillRect( | |
startPoint[0], | |
startPoint[1], | |
endPoint[0] - startPoint[0], | |
endPoint[1] - startPoint[1] | |
); | |
} | |
drawHollowCircle(startPoint, endPoint) { | |
const x = startPoint[0] - endPoint[0]; | |
const y = startPoint[1] - endPoint[1]; | |
const radius = Math.sqrt(x * x + y * y); | |
this.ctx.beginPath(); | |
this.ctx.arc(startPoint[0], startPoint[1], radius, 0, 2 * Math.PI, false); | |
this.ctx.stroke(); | |
} | |
drawFilledCircle(startPoint, endPoint) { | |
const x = startPoint[0] - endPoint[0]; | |
const y = startPoint[1] - endPoint[1]; | |
const radius = Math.sqrt(x * x + y * y); | |
this.ctx.beginPath(); | |
this.ctx.arc(startPoint[0], startPoint[1], radius, 0, 2 * Math.PI, false); | |
this.ctx.fill(); | |
} | |
displayMode() { | |
const modeDiv = document.querySelector('#mode'); | |
modeDiv.innerHTML = this.mode; | |
} | |
getModeType(mode) { | |
let type = ''; | |
switch (mode) { | |
case 'Line': | |
type = 'line'; | |
break; | |
case 'Hollow Rectangle': | |
case 'Filled Rectangle': | |
type = 'rectangle'; | |
break; | |
case 'Hollow Circle': | |
case 'Filled Circle': | |
type = 'circle'; | |
break; | |
} | |
return type; | |
} | |
displayMessage() { | |
const type = this.getModeType(this.mode); | |
const find = this.shapeMessages.find(m => m.type === type); | |
const msgDiv = document.querySelector('#message'); | |
msgDiv.innerHTML = find[this.pointMode]; | |
} | |
} | |
class Palette { | |
constructor() { | |
this.colors = [ | |
['#000000', '#FFFFFF', '#7F7F7F', '#C3C3C3', '#880015', '#B97A57', '#ED1C24', '#FFAEC9', '#FF7F27', '#FFC90E'], | |
['#FFF200', '#EFE4B0', '#22B14C', '#B5E61D', '#00A2E8', '#99D9EA', '#3F48CC', '#7092BE', '#A349A4', '#C8BFE7'] | |
]; | |
} | |
draw(canvas) { | |
const row1 = document.querySelectorAll('#row-1 .palette'); | |
const row2 = document.querySelectorAll('#row-2 .palette'); | |
row1.forEach((div, idx) => { | |
div.style.backgroundColor = this.colors[0][idx]; | |
div.onclick = e => canvas.setColor(this.colors[0][idx]); | |
}); | |
row2.forEach((div, idx) => { | |
div.style.backgroundColor = this.colors[1][idx]; | |
div.onclick = e => canvas.setColor(this.colors[1][idx]); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment