Skip to content

Commit 8bd6a84

Browse files
committed
Added minor optimizations to grid/fog rendering
1 parent d5bf4e5 commit 8bd6a84

File tree

6 files changed

+113
-71
lines changed

6 files changed

+113
-71
lines changed

client/src/pages/tabletop-page/monster-menu/monster-menu.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ monster-menu {
3535
border-radius: 16px;
3636

3737
@media (prefers-color-scheme: dark) {
38-
background-color: hsl(var(--grey-400-hsl) / 0.15);
38+
background-color: hsl(var(--grey-400-hsl) / 0.15)
3939
}
4040

4141
svg {

client/src/pages/tabletop-page/tabletop-component/table-canvas/table-canvas.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ table-canvas{
33
top: 50%;
44
left: 50%;
55
pointer-events: none;
6-
transform: translate(-50%, -50%);
6+
transform: translate3d(-50%, -50%, 0);
77

88
canvas{
99
display: inline-block;

client/src/pages/tabletop-page/tabletop-component/table-canvas/table-canvas.ts

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,40 @@ interface ITableCanvas { }
1818
export default class TableCanvas extends SuperComponent<ITableCanvas>{
1919
private canvas: HTMLCanvasElement;
2020
private fogCanvas: HTMLCanvasElement;
21+
private gridCanvas: HTMLCanvasElement;
2122
private fogctx: CanvasRenderingContext2D;
2223
private imgctx: CanvasRenderingContext2D;
23-
private time: number;
24+
private gridctx: CanvasRenderingContext2D;
2425
private renderGrid: boolean;
2526
private gridSize: number;
2627
private fogOfWar: boolean;
27-
private ticket: string;
2828
private w: number;
2929
private h: number;
3030
private fogOfWarShapes: Array<FogOfWarShape>;
3131
private tabletop: TabeltopComponent;
3232
private image: HTMLImageElement;
33+
private updateGrid: boolean;
34+
private updateFog: boolean;
3335

3436
constructor() {
3537
super();
3638
this.w = 0;
3739
this.h = 0;
3840
this.canvas = document.createElement("canvas") as HTMLCanvasElement;
3941
this.fogCanvas = document.createElement("canvas") as HTMLCanvasElement;
42+
this.gridCanvas = document.createElement("canvas") as HTMLCanvasElement;
4043
this.fogctx = this.fogCanvas.getContext("2d");
4144
this.imgctx = this.canvas.getContext("2d");
45+
this.gridctx = this.gridCanvas.getContext("2d");
4246
this.tabletop = document.querySelector("tabletop-component");
43-
this.time = performance.now();
4447
this.renderGrid = false;
4548
this.gridSize = 32;
4649
this.fogOfWar = false;
4750
this.fogOfWarShapes = [];
4851
this.image = null;
52+
this.updateGrid = false;
53+
this.updateFog = false;
54+
4955
subscribe("socket", this.inbox.bind(this));
5056
subscribe("fog", this.fogInbox.bind(this));
5157
}
@@ -95,16 +101,20 @@ export default class TableCanvas extends SuperComponent<ITableCanvas>{
95101
case "room:tabletop:fog:sync":
96102
this.fogOfWar = data.fogOfWar;
97103
this.fogOfWarShapes = data.fogOfWarShapes;
104+
this.updateFog = true;
98105
this.render();
99106
break;
100107
case "room:tabletop:clear":
101108
this.fogOfWarShapes = [];
109+
this.updateFog = true;
102110
this.render();
103111
break;
104112
case "room:tabletop:map:update":
105113
this.renderGrid = data.renderGrid;
106114
this.gridSize = data.cellSize;
107115
this.fogOfWar = data.prefillFog;
116+
this.updateGrid = true;
117+
this.updateFog = true;
108118
this.render();
109119
break;
110120
default:
@@ -143,7 +153,7 @@ export default class TableCanvas extends SuperComponent<ITableCanvas>{
143153
}
144154

145155
private renderFogOfWar() {
146-
if (!this.fogOfWar) return;
156+
if (!this.fogOfWar || !this.updateFog) return;
147157
if (room.isGM) {
148158
this.fogctx.globalAlpha = 0.6;
149159
}
@@ -154,35 +164,39 @@ export default class TableCanvas extends SuperComponent<ITableCanvas>{
154164
this.fogctx.fillStyle = color;
155165
this.fogctx.fillRect(0, 0, this.w, this.h);
156166
this.revealShapes();
167+
this.updateFog = false;
157168
}
158169

159170
private renderGridLines(){
160-
if (!this.renderGrid) return;
171+
if (!this.renderGrid || !this.updateGrid) return;
161172
const columns = Math.ceil(this.w / this.gridSize);
162173
const rows = Math.ceil(this.h / this.gridSize);
163174

164-
this.imgctx.strokeStyle = "rgb(0,0,0)";
175+
this.gridctx.strokeStyle = "rgb(0,0,0)";
165176
for (let i = 0; i < columns; i++) {
166177
const x = i * this.gridSize;
167-
this.imgctx.beginPath();
168-
this.imgctx.moveTo(x, 0);
169-
this.imgctx.lineTo(x, this.h);
170-
this.imgctx.stroke();
178+
this.gridctx.beginPath();
179+
this.gridctx.moveTo(x, 0);
180+
this.gridctx.lineTo(x, this.h);
181+
this.gridctx.stroke();
171182
}
172183
for (let i = 0; i < rows; i++) {
173184
const y = i * this.gridSize;
174-
this.imgctx.beginPath();
175-
this.imgctx.moveTo(0, y);
176-
this.imgctx.lineTo(this.w, y);
177-
this.imgctx.stroke();
185+
this.gridctx.beginPath();
186+
this.gridctx.moveTo(0, y);
187+
this.gridctx.lineTo(this.w, y);
188+
this.gridctx.stroke();
178189
}
190+
this.updateGrid = false;
179191
}
180192

181193
public load(image: HTMLImageElement) {
182194
if (!image) {
183195
this.w = 0;
184196
this.h = 0;
185197
this.image = null;
198+
this.updateGrid = true;
199+
this.updateFog = true;
186200

187201
this.canvas.width = this.w;
188202
this.canvas.height = this.h;
@@ -193,10 +207,17 @@ export default class TableCanvas extends SuperComponent<ITableCanvas>{
193207
this.fogCanvas.height = this.h;
194208
this.fogCanvas.style.width = `0px`;
195209
this.fogCanvas.style.height = `0px`;
210+
211+
this.gridCanvas.width = this.w;
212+
this.gridCanvas.height = this.h;
213+
this.gridCanvas.style.width = `0px`;
214+
this.gridCanvas.style.height = `0px`;
196215
} else {
197216
this.w = image.width;
198217
this.h = image.height;
199218
this.image = image;
219+
this.updateGrid = true;
220+
this.updateFog = true;
200221

201222
this.canvas.width = this.w;
202223
this.canvas.height = this.h;
@@ -207,25 +228,44 @@ export default class TableCanvas extends SuperComponent<ITableCanvas>{
207228
this.fogCanvas.height = this.h;
208229
this.fogCanvas.style.width = `${image.width}px`;
209230
this.fogCanvas.style.height = `${image.height}px`;
231+
232+
this.gridCanvas.width = this.w;
233+
this.gridCanvas.height = this.h;
234+
this.gridCanvas.style.width = `${image.width}px`;
235+
this.gridCanvas.style.height = `${image.height}px`;
210236
}
211237
this.render();
212238
}
213239

214240
override render(): void {
215-
this.fogctx.clearRect(0, 0, this.w, this.h);
216241
this.imgctx.clearRect(0, 0, this.w, this.h);
217-
242+
if (this.updateFog) this.fogctx.clearRect(0, 0, this.w, this.h);
243+
if (this.updateGrid) this.gridctx.clearRect(0, 0, this.w, this.h);
244+
218245
if (!this.image) return;
219246

220247
// Always draw map first
221-
this.imgctx.drawImage(this.image, 0, 0, this.w, this.h);
248+
this.imgctx.drawImage(
249+
this.image,
250+
0, 0, this.w, this.h
251+
);
222252

223253
// Other
224254
this.renderGridLines();
255+
this.renderFogOfWar();
256+
257+
this.imgctx.drawImage(
258+
this.gridCanvas,
259+
0, 0,
260+
this.w, this.h
261+
);
225262

226263
// Always draw fog last
227-
this.renderFogOfWar();
228-
this.imgctx.drawImage(this.fogCanvas, 0, 0);
264+
this.imgctx.drawImage(
265+
this.fogCanvas,
266+
0, 0,
267+
this.w, this.h
268+
);
229269
}
230270
}
231271
env.bind("table-canvas", TableCanvas);

0 commit comments

Comments
 (0)