Ваша проблема в этой строке:
ctx.fillRect(0, 0, 20, 20);
Вместо заполнения ячейки, по которой щелкнули, вы заполняете только верхнюю левую ячейку при каждом щелчке.
В настоящее время вы используете только(0, 0) здесь, когда вы должны рассчитывать эту позицию от курсора.Координаты, используемые холстом и курсором, разные, поэтому вам нужно написать функцию преобразования:
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
Функция mousePosToCanvasPos()
возвращает текущую визуализированную позицию холста (canvasPos
) и вычисляет смещение курсора от верхнего левого угла холста (mouse_ - canvasPos._
).Затем он округляет это значение до ближайшего кратного 20, чтобы вернуть левый верхний угол ячейки, по которой щелкнули (Math.floor((mouse_ - canvasPos._) / 20) * 20
).Если вы измените размер ячейки на значение, отличное от 20, обязательно измените его и в этой функции.Или еще лучше, извлеките константу (var cellSize = 20
).
Добавление этой функции в ваш код дает нам:
var title = document.getElementById("title");
var canvas = document.getElementById("canvas");
var color = document.getElementById("color");
var btn = document.getElementById("btn");
var ctx = canvas.getContext("2d");
// The function that draws the grid
function drawGrid() {
ctx.fillStyle = "#009EFF";
ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// The for loop that draws the x-axis
for (x = 0; x <= 400; x += 20) {
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
}
// The for loop that draws the y-axis
for (y = 0; y <= 400; y += 20) {
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
}
}
drawGrid();
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
// Function that clicks and fill grid boxes w / color
function colorPicker() {
canvas.addEventListener("click", function(event) {
var newColor = color.value;
ctx.fillStyle = newColor;
var canvasCellPos = mousePosToCanvasPos(event.x, event.y);
ctx.fillRect(canvasCellPos.x, canvasCellPos.y, 20, 20);
console.log(event.x, event.y);
console.log(newColor);
});
}
colorPicker();
#canvas {
border: 1px solid black;
background-size: 100%;
display: block;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding-left: 0;
padding-right: 0;
}
<div class="color-wheel">
Color: <input type="color" id="color" />
</div>
<canvas id="canvas" width="400" height="400"></canvas>
Вы заметите, что что-то здесь не совсем так: каждый раз, когда вы заполняете ячейку, она делает ее границу более тонкой.Чтобы решить эту проблему, вам нужно удалить по одному пикселю с каждой стороны вашего fillRect
:
ctx.fillRect(canvasCellPos.x + 1, canvasCellPos.y + 1, 18, 18);
var title = document.getElementById("title");
var canvas = document.getElementById("canvas");
var color = document.getElementById("color");
var btn = document.getElementById("btn");
var ctx = canvas.getContext("2d");
// The function that draws the grid
function drawGrid() {
ctx.fillStyle = "#009EFF";
ctx.fillRect(0, 0, 400, 400);
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
// The for loop that draws the x-axis
for (x = 0; x <= 400; x += 20) {
ctx.moveTo(x, 0);
ctx.lineTo(x, 400);
ctx.stroke();
}
// The for loop that draws the y-axis
for (y = 0; y <= 400; y += 20) {
ctx.moveTo(0, y);
ctx.lineTo(400, y);
ctx.stroke();
}
}
drawGrid();
function mousePosToCanvasPos(mouseX, mouseY) {
var canvasPos = canvas.getBoundingClientRect();
return {
x: Math.floor((mouseX - canvasPos.x) / 20) * 20,
y: Math.floor((mouseY - canvasPos.y) / 20) * 20,
};
}
// Function that clicks and fill grid boxes w / color
function colorPicker() {
canvas.addEventListener("click", function(event) {
var newColor = color.value;
ctx.fillStyle = newColor;
var canvasCellPos = mousePosToCanvasPos(event.x, event.y);
ctx.fillRect(canvasCellPos.x + 1, canvasCellPos.y + 1, 18, 18);
console.log(event.x, event.y);
console.log(newColor);
});
}
colorPicker();
#canvas {
border: 1px solid black;
background-size: 100%;
display: block;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding-left: 0;
padding-right: 0;
}
<div class="color-wheel">
Color: <input type="color" id="color" />
</div>
<canvas id="canvas" width="400" height="400"></canvas>