Нужна помощь в написании функции, чтобы сделать любой блок внутри сетки кликабельным и заполненным цветом - PullRequest
0 голосов
/ 25 декабря 2018

Я работаю над проектом пиксельной графики.То, что я ожидал сделать здесь, это иметь возможность щелкнуть любое поле внутри сетки и отобразить его с цветом из цветного ввода.

Мне удалось понять, как работает цикл для создания сетки с использованием canvas иJavaScript.Затем я создал функцию с именем colorPicker(), которая позволяет мне щелкнуть любую ячейку сетки, взять значение из цветового ввода и отобразить его в этом цвете.Я использовал canvas.addEventListener("click", function(event) { ... }) и передал переменные xCoord и yCoord со значениями event.x и event.y.Это позволяет мне возвращать положение мыши при щелчке внутри сетки.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что она рендерит только 1 квадрат из всех 400, которые я нарисовал на сетке.Рендеринг работает, просто я могу только щелкнуть один блок и отобразить его цвет из входных данных.

Может ли кто-нибудь помочь мне решить эту функцию, просто используя логику javascript, которая у меня сейчас есть?

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 that clicks and fill grid boxes w / color
function colorPicker() {
  canvas.addEventListener("click", function(event) {
    var newColor = color.value;
    ctx.fillStyle = newColor;
    xCoord = event.x;
    yCoord = event.y;
    ctx.fillRect(0, 0, 20, 20);

    console.log(xCoord, yCoord);
    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>

1 Ответ

0 голосов
/ 25 декабря 2018

Ваша проблема в этой строке:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...