Workshop › Sokoban › Step 8 of 29
The level sits in the top-left corner. We measure it (rows and the longest row), and shift everything by ox and oy
so it is centered, leaving room at the top and bottom for text.
```js
const TOP = 48 // room for the level number and the move counter
const BOTTOM = 40 // room for the hint line
// Center the level on the canvas.
const rows = LEVELS[level].length
const cols = Math.max(...LEVELS[level].map((line) => line.length))
const ox = (canvas.width - cols * TILE) / 2
const oy = TOP + (canvas.height - TOP - BOTTOM - rows * TILE) / 2
const tile = (x, y, color, inset = 0) => {
ctx.fillStyle = color
ctx.fillRect(ox + x * TILE + inset, oy + y * TILE + inset, TILE - inset * 2, TILE - inset * 2)
}
```rows is the number of rows; cols the length of the longest row. Math.max(...list) gives the biggest number.ox is the left edge: half of the width left over. oy is the same for the height, below the TOP strip and above
the BOTTOM strip.tile now starts from ox and oy.const TILE = 48 write the TOP and BOTTOM lines.draw, above const tile, write the comment and the four lines.tile, add ox + and oy + at the start of the first two numbers. Press Run.Skills: Drawing on a canvas