|
const backgroundCanvas = document.getElementById("background-canvas"); |
|
const drawingCanvas = document.getElementById("drawing-canvas"); |
|
const bgCtx = backgroundCanvas.getContext("2d"); |
|
const drawCtx = drawingCanvas.getContext("2d"); |
|
const colorPicker = document.getElementById("color-picker"); |
|
const sizeSlider = document.getElementById("size-slider"); |
|
const clearBtn = document.getElementById("clear-btn"); |
|
|
|
let isDrawing = false; |
|
let currentPath = []; |
|
|
|
function resizeCanvases() { |
|
const container = document.getElementById("canvas-container"); |
|
const width = container.clientWidth; |
|
const height = container.clientHeight; |
|
|
|
backgroundCanvas.width = width; |
|
backgroundCanvas.height = height; |
|
drawingCanvas.width = width; |
|
drawingCanvas.height = height; |
|
|
|
|
|
redrawWhiteboard([]); |
|
} |
|
|
|
|
|
resizeCanvases(); |
|
window.addEventListener("resize", resizeCanvases); |
|
|
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; |
|
const ws = new WebSocket(`${protocol}//${window.location.host}/ws`); |
|
|
|
ws.onmessage = (event) => { |
|
const message = JSON.parse(event.data); |
|
if (message.Update) { |
|
redrawWhiteboard(message.Update); |
|
} else if (message.Clear) { |
|
bgCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height); |
|
} |
|
}; |
|
|
|
function redrawWhiteboard(actions) { |
|
bgCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height); |
|
for (const action of actions) { |
|
drawPath(bgCtx, action); |
|
} |
|
} |
|
|
|
function drawPath(context, action) { |
|
context.beginPath(); |
|
context.strokeStyle = action.color; |
|
context.lineWidth = action.size; |
|
context.lineCap = "round"; |
|
context.lineJoin = "round"; |
|
for (let i = 0; i < action.points.length; i++) { |
|
const point = action.points[i]; |
|
if (i === 0) { |
|
context.moveTo(point.x, point.y); |
|
} else { |
|
context.lineTo(point.x, point.y); |
|
} |
|
} |
|
context.stroke(); |
|
} |
|
|
|
drawingCanvas.addEventListener("mousedown", startDrawing); |
|
drawingCanvas.addEventListener("mousemove", draw); |
|
drawingCanvas.addEventListener("mouseup", stopDrawing); |
|
drawingCanvas.addEventListener("mouseout", stopDrawing); |
|
|
|
|
|
drawingCanvas.addEventListener("touchstart", handleTouchStart); |
|
drawingCanvas.addEventListener("touchmove", handleTouchMove); |
|
drawingCanvas.addEventListener("touchend", handleTouchEnd); |
|
|
|
function startDrawing(e) { |
|
isDrawing = true; |
|
currentPath = []; |
|
const point = getPoint(e); |
|
currentPath.push(point); |
|
drawCtx.beginPath(); |
|
drawCtx.moveTo(point.x, point.y); |
|
} |
|
|
|
function draw(e) { |
|
if (!isDrawing) return; |
|
|
|
const point = getPoint(e); |
|
currentPath.push(point); |
|
|
|
drawCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height); |
|
drawPath(drawCtx, { |
|
color: colorPicker.value, |
|
size: parseFloat(sizeSlider.value), |
|
points: currentPath, |
|
}); |
|
} |
|
|
|
function stopDrawing() { |
|
if (!isDrawing) return; |
|
isDrawing = false; |
|
|
|
const action = { |
|
color: colorPicker.value, |
|
size: parseFloat(sizeSlider.value), |
|
points: currentPath, |
|
}; |
|
|
|
ws.send(JSON.stringify({ Draw: action })); |
|
drawCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height); |
|
drawPath(bgCtx, action); |
|
currentPath = []; |
|
} |
|
|
|
function getPoint(e) { |
|
const rect = drawingCanvas.getBoundingClientRect(); |
|
const x = e.clientX || e.touches[0].clientX; |
|
const y = e.clientY || e.touches[0].clientY; |
|
return { |
|
x: x - rect.left, |
|
y: y - rect.top, |
|
}; |
|
} |
|
|
|
function handleTouchStart(e) { |
|
e.preventDefault(); |
|
startDrawing(e.touches[0]); |
|
} |
|
|
|
function handleTouchMove(e) { |
|
e.preventDefault(); |
|
draw(e.touches[0]); |
|
} |
|
|
|
function handleTouchEnd(e) { |
|
e.preventDefault(); |
|
stopDrawing(); |
|
} |
|
|
|
clearBtn.addEventListener("click", () => { |
|
ws.send(JSON.stringify({ Clear: null })); |
|
}); |
|
|
|
|
|
document.body.addEventListener( |
|
"touchstart", |
|
function (e) { |
|
if (e.target == drawingCanvas) { |
|
e.preventDefault(); |
|
} |
|
}, |
|
{ passive: false }, |
|
); |
|
document.body.addEventListener( |
|
"touchend", |
|
function (e) { |
|
if (e.target == drawingCanvas) { |
|
e.preventDefault(); |
|
} |
|
}, |
|
{ passive: false }, |
|
); |
|
document.body.addEventListener( |
|
"touchmove", |
|
function (e) { |
|
if (e.target == drawingCanvas) { |
|
e.preventDefault(); |
|
} |
|
}, |
|
{ passive: false }, |
|
); |
|
|