File size: 2,907 Bytes
9982ad3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const canvas = document.getElementById("whiteboard");
const ctx = canvas.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 = [];

canvas.width = window.innerWidth;
canvas.height = window.innerHeight - 50;

const ws = new WebSocket(`ws://${window.location.host}/ws`);

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.Update) {
    redrawWhiteboard(message.Update);
  } else if (message.Clear) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }
};

function redrawWhiteboard(actions) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (const action of actions) {
    drawPath(action);
  }
}

function drawPath(action) {
  ctx.beginPath();
  ctx.strokeStyle = action.color;
  ctx.lineWidth = action.size;
  ctx.lineCap = "round";
  ctx.lineJoin = "round";
  for (let i = 0; i < action.points.length; i++) {
    const point = action.points[i];
    if (i === 0) {
      ctx.moveTo(point.x, point.y);
    } else {
      ctx.lineTo(point.x, point.y);
    }
  }
  ctx.stroke();
}

canvas.addEventListener("mousedown", startDrawing);
canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mouseup", stopDrawing);
canvas.addEventListener("mouseout", stopDrawing);

function startDrawing(e) {
  isDrawing = true;
  currentPath = [];
  const point = getPoint(e);
  currentPath.push(point);
  ctx.beginPath();
  ctx.moveTo(point.x, point.y);
}

function draw(e) {
  if (!isDrawing) return;

  const point = getPoint(e);
  currentPath.push(point);

  // Clear the canvas and redraw the current path
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  redrawWhiteboard([]); // Redraw all previous actions
  drawCurrentPath();
}

function drawCurrentPath() {
  ctx.beginPath();
  ctx.strokeStyle = colorPicker.value;
  ctx.lineWidth = sizeSlider.value;
  ctx.lineCap = "round";
  ctx.lineJoin = "round";
  for (let i = 0; i < currentPath.length; i++) {
    const point = currentPath[i];
    if (i === 0) {
      ctx.moveTo(point.x, point.y);
    } else {
      ctx.lineTo(point.x, point.y);
    }
  }
  ctx.stroke();
}

function stopDrawing() {
  if (!isDrawing) return;
  isDrawing = false;

  const action = {
    color: colorPicker.value,
    size: parseFloat(sizeSlider.value),
    points: currentPath,
  };

  ws.send(JSON.stringify({ Draw: action }));
  currentPath = [];
}

function getPoint(e) {
  const rect = canvas.getBoundingClientRect();
  return {
    x: e.clientX - rect.left,
    y: e.clientY - rect.top,
  };
}

clearBtn.addEventListener("click", () => {
  ws.send(JSON.stringify({ Clear: null }));
});

window.addEventListener("resize", () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight - 50;
  redrawWhiteboard([]);
});