<div></div>
const place = document.querySelector('div')
const size = 20
const [initColumn, initRow] = [20, 10]
const initColor = ['white', 'red']
let currentIndColor = 0
const cell = Object.entries({
height: `${size}px`,
width: `${size}px`,
position: 'absolute',
backgroundColor: initColor[currentIndColor],
border: '1px solid #9e9e9e',
boxSizing: 'border-box'
}).reduce((e, [s, v]) => (e.style[s] = v, e),
document.createElement('div'))
function createElementTable(d, column, row, rowListeners) {
let iColor = currentIndColor
d._pos = {
column, row,
reset() {
d.style.backgroundColor = initColor[iColor = iColor ? 0 : 1]
},
get indColor() {
return iColor
}
}
rowListeners[row] = {
set() {
if (currentIndColor === iColor) { return }
iColor = currentIndColor
d.style.backgroundColor = initColor[currentIndColor]
},
element: d
}
}
const elementsTable = []
const currentCell = []
let cl = initColumn
while (cl--) {
const rowListeners = []
elementsTable[cl] = rowListeners
let rw = initRow
while (rw--) {
const d = cell.cloneNode(true)
d.style.top = `${size * rw}px`
d.style.left = `${size * cl}px`
place.appendChild(d)
createElementTable(d, cl, rw, rowListeners)
}
}
function setColor(target) {
const startInd = currentCell[0]._pos
const { column, row } = target._pos
const rColumn = (startInd.column - column) > 0 ? -1 : 1
const rRow = (startInd.row - row) > 0 ? -1 : 1
const temp = new Set()
let cl = startInd.column
do {
let rw = startInd.row
do {
const el = elementsTable[cl][rw]
temp.add(el.element)
if (!currentCell.includes(el.element)) {
el.set()
currentCell.push(el.element)
}
} while (rw !== row && (rw += 1 * rRow, true))
} while (cl !== column && (cl += 1 * rColumn, true))
for (let i = 0; i < currentCell.length; ++i) {
if (temp.has(currentCell[i])) {
continue
}
currentCell[i]._pos.reset()
currentCell.splice(i--, 1)
}
}
const over = ({ target }) => {
if (!target._pos) { return }
setColor(target)
}
const up = () => {
place.removeEventListener('mouseover', over)
currentCell.splice(0)
}
const down = (e) => {
e.preventDefault()
if (!e.target._pos) {
return
}
document.addEventListener('mouseup', up, { once: true })
place.addEventListener('mouseover', over)
currentIndColor = e.target._pos.indColor ? 0 : 1
const { column, row } = e.target._pos
const el = elementsTable[column][row]
el.set()
currentCell.push(el.element)
}
place.addEventListener('mousedown', down)
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.