| 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 }, |
| ); |
|
|