Приветствия.
Во-первых оформляй код текстом, а не скриншотом. Так будет проще с ним работать, и ты с большей вероятностью получишь ответ на свой вопрос. Пример хорошо оформленного вопроса - Подсчет среднего значения ячеек столбца
Во-вторых. То, что делает твой код - чисто отрисовка линий. Хоть визуально мы видим ячейки, в программе нет сущностей, которые представляли собой ячейки.
Задача решается так: ты создаешь структуру данных, которая представляет набор ячеек. Для представления ячеек лучше использовать объект. Набор ячеек представить массивом. Можно представить все ячейки как массивы массивов. Можно как один массив. Разница в выборе в том, на сколько будет просто обрабатывать полученную структуру данных для твоих задач.
Вот код https://jsfiddle.net/yyjoazuy/
var canvas = document.querySelector('canvas')
var context = canvas.getContext('2d')
// Представление всех ячеек
var cells = []
var canvasWidth = 300
var canvasHeight = 300
canvas.width = canvasWidth
canvas.height = canvasHeight
var cellWidth = 10
var cellHeight = 10
var cellsInRow = Math.floor(canvasWidth / cellWidth)
var cellsInColumn = Math.floor(canvasHeight / cellHeight)
for (var top = 0; top < canvasWidth; top += cellWidth) {
for (var left = 0; left < canvasHeight; left += cellHeight) {
var cell = {
top: top,
left: left,
solid: false,
// аргумент говорит о том каким цветом закрашивать клетку. Предполагается что у клетки может быть 2 цвета.
fill: function (solid) {
// запоминаем состояние закрашенности клетки
this.solid = solid
context.fillStyle = solid ? '#000' : '#fff';
context.fillRect(this.top, this.left, cellWidth,cellHeight);
},
drawBorder: function () {
context.beginPath();
context.strokeStyle = 'yellow';
// magic. According to http://stackoverflow.com/questions/8696631/canvas-drawings-like-lines-are-blurry
context.moveTo(this.top - 0.5, this.left - 0.5)
context.lineTo(this.top - 0.5, this.left + cellWidth - 0.5)
context.lineTo(this.top + cellHeight - 0.5, this.left + cellWidth - 0.5)
context.lineTo(this.top + cellHeight - 0.5, this.left - 0.5)
context.lineTo(this.top - 0.5, this.left - 0.5)
context.stroke()
},
getTop: function () {
return this.top
},
getLeft: function () {
return this.left
}
}
cells.push(cell)
cell.fill(true)
cell.drawBorder()
}
}
function getCellByPosition(top, left) {
var topIndex = Math.floor(top / cellHeight) * cellsInRow
var leftIndex = Math.floor(left / cellWidth)
return cells[topIndex + leftIndex]
}
// Взаимодействие
var filling = false
function fillCellAtPositionIfNeeded(x, y, fillingMode) {
var cellUnderCursor = getCellByPosition(x, y)
if (cellUnderCursor.solid !== fillingMode) {
cellUnderCursor.fill(fillingMode)
}
cell.drawBorder()
}
function handleMouseDown(event) {
// нужно вычислить координаты клика относительно верхнего левого края canvas
// это делается с использованием вычисления координат канваса и кроссбраузерных свойств объекта event
// я использую некроссбраузерные свойства объекта событий
filling = !getCellByPosition(event.layerX, event.layerY).solid
fillCellAtPositionIfNeeded(event.layerX, event.layerY, filling)
canvas.addEventListener('mousemove', handleMouseMove, false)
}
function handleMouseUp() {
canvas.removeEventListener('mousemove', handleMouseMove)
}
function handleMouseMove(event) {
fillCellAtPositionIfNeeded(event.layerX, event.layerY, filling)
}
canvas.addEventListener('mousedown', handleMouseDown, false)
canvas.addEventListener('mouseup', handleMouseUp, false)
По коду:
- Каждый объект ячейки хранит информацию о заполненности ячейки
solid
. Эта иформация используется как снаружи чтобы принять решение как обрабатывать клик по ячейке. Так же хранит метод, которые знает как закрасить ячейку.
- Отрисовка границ ячеек не идеальна. Границы ячеек совпадают, и когда закрашивается одна ячейка, она перекрывает границу ячейки рядом. Я упростил задачу вычисления положения ячейки.
- Не все ячейки под мышкой закрашиваются, когда водишь мышкой быстро. Это особенность работы браузера (положение мыши считывается раз в 16мс).
- Канвас не дает API, которое позволило бы работать с элементами канваса как с объектами. С точки зрения использования канвас - это набор точек с состоянием каждой точки. Поэтому чтобы работать на канвасе с объектами, нужно самому вести учет где объект расположен, какую имеет форму. В этой задаче я, исходя из предпосылок, что все ячейки имеют одинаковый размер, и плотно подогнаны друг к другу, вычисляю объект ячейки по координатам клика. Есть библиотеки, которые представляют объекты, отрисованные на канвасе в виде объектов. С их использованием работа с элементами канваса сводится к манипуляции объектами. Рекомендую http://fabricjs.com/