使用 javaScript 通过鼠标移动来更改画布中的内容,例如大小和位置

问题描述 投票:0回答:1

我刚刚开始编程,这是我的第二个项目——它是一个绘画应用程序。我在 YouTube 上看到了这个项目,并以自己的方式克隆了它。然而,当我遇到问题时,我会参考视频,就像初学者应该做的那样。但该视频并没有涵盖我想到的许多功能,比如我如何在画布内移动物体并在单击按钮后更改其大小。 这是我的代码

const canvas = document.querySelector(".canvas");
const ctx = canvas.getContext("2d");
const tools = document.querySelectorAll(".tool");
const fullColor = document.querySelector("#fill-color");
const brushSize = document.querySelector("#size-of-brush");
const colorBtns = document.querySelectorAll(".color .option");
const colorPicker = document.querySelector("#color-picker");
const clearCanvas = document.querySelector(".clear-canvas");
const saveCanvas = document.querySelector(".save-img");
// global variable
let method = "brush";
let draw = false;
let pervCorX;
let pervCorY;
let brushWidth = 5;
let oneDraw;
let color = "rgb(0, 0, 0)";

//canvas width and height
window.addEventListener("load", () => {
  canvas.width = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
});

// confirm mouse down and change  the color and size of brush and ships
const mousedown = (event) => {
  draw = true;
  ctx.strokeStyle = color;
  ctx.fillStyle = color;
  pervCorX = event.offsetX;
  pervCorY = event.offsetY;
  ctx.beginPath();
  ctx.lineWidth = brushWidth;
  oneDraw = ctx.getImageData(0, 0, canvas.width, canvas.height);
};

// witch shape and width is clicked
tools.forEach((toolsBtn) => {
  toolsBtn.addEventListener("click", () => {
    document.querySelector(".active").classList.remove("active");
    toolsBtn.classList.add("active");
    method = toolsBtn.id;
    // console.log(method);
  });
});

// confirmation of stooping drawing
const mouseup = () => {
  draw = false;
};

// drawing rectangle circle triangle
const rectangle = (event) => {
  const x = event.offsetX;
  const y = event.offsetY;
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  if (fullColor.checked) return ctx.fillRect(x, y, width, height);

  ctx.strokeRect(x, y, width, height);
};
const circle = (event) => {
  ctx.beginPath();
  console.log("hihi");
  const width = pervCorX - event.offsetX;
  const height = pervCorY - event.offsetY;
  let radius = Math.sqrt(width ** 2 + height ** 2);
  ctx.arc(pervCorX, pervCorY, radius, 0, 2 * Math.PI);
  if (fullColor.checked) return ctx.fill();
  ctx.stroke();
};
const triangle = (event) => {
  ctx.beginPath();
  ctx.moveTo(pervCorX, pervCorY);
  ctx.lineTo(event.offsetX, event.offsetY);
  ctx.lineTo(pervCorX * 2 - event.offsetX, event.offsetY);
  ctx.closePath();
  fullColor.checked ? ctx.fill() : ctx.stroke();
};

//checking what ship to draw
const startDrawing = (event) => {
  if (!draw) return;
  ctx.putImageData(oneDraw, 0, 0);

  if (method == "brush" || method == "eraser") {
    ctx.strokeStyle = method == "eraser" ? "#fff" : color;
    ctx.lineTo(event.offsetX, event.offsetY);
    ctx.stroke();
  } else if (method == "rectangle") {
    rectangle(event);
  } else if (method == "circle") {
    circle(event);
  } else if (method == "triangle") {
    triangle(event);
  }
};
colorBtns.forEach((btn) => {
  console.log(btn);
  btn.addEventListener("click", () => {
    document.querySelector(".selected").classList.remove("selected");
    btn.classList.add("selected");
    color = window.getComputedStyle(btn).backgroundColor;
  });
});
//changing color of ships  and brush
colorPicker.addEventListener("change", () => {
  colorPicker.parentElement.style.background = colorPicker.value;
  colorPicker.parentElement.click();
});
// checking if mouse down in canvas and give brush size
brushSize.addEventListener("change", () => (brushWidth = brushSize.value));
canvas.addEventListener("mousemove", startDrawing);
canvas.addEventListener("mousedown", mousedown);
canvas.addEventListener("mouseup", mouseup);
//save and clear canvas
clearCanvas.addEventListener("click", () => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
});
saveCanvas.addEventListener("click", () => {
  const a = document.createElement("a");
  a.href = canvas.toDataURL("image/png");
  a.download = "canvas_image.png";
  a.click();
});




javascript canvas
1个回答
0
投票

就像我如何在画布内移动物体并在单击按钮后更改其大小

但是,我假设您正在谈论类似于Figma/Adobe XD/等的功能,您可以在其中绘制一堆形状,然后可以使用鼠标/键盘来移动它们。

对于此类应用程序,您可以使用

Model View Controller (MVC)
架构。

  1. Model - 负责存储数据。这可以是形状的坐标和尺寸、填充、描边等。
  2. View - 负责在画布上渲染对象。它从模型中读取有关对象的信息并进行绘制。
  3. Controller - 负责处理用户事件。根据事件,更新模型中的值并要求视图重绘。

随着时间的推移,随着您不断添加更多功能,您的代码设计将变得更加复杂。这就是面向对象编程的用武之地。您可以通过在 Github 上查看开源软件的代码来探索开源软件的设计方式。

这是您可以如何做的草稿。

// This is the model. It stores an array of objects.
// Each object contains information for rendering it.
// Notice how each type has different types of data.
const objectList = [
  { id: 0, type: 'rect', data: { x: 10, y: 5, w: 2, h: 4 } },
  { id: 1, type: 'circle', data: { x: 10, y: 5, r: 3.5 } },
  { id: 2, type: 'line', data: { x0: 10, y0: 5, x1: 2, y1: 4 } },
];

// This is the view. It basically renders everything in the objectList
const renderObjects = () => {
  objectList.forEach(obj => {
    if (obj.type === 'rect') {
      // code to draw rectangle
    }
    if (obj.type === 'circle') {
      // code to draw rectangle
    }
    if (obj.type === 'line') {
      // code to draw rectangle
    }
  })
}

// Controllers
// These will be methods to modify items in objectList based on event handlers, etc.
const buttonEventHandler1 = (params) => {
  // ... update some item from objectList based on params.

  // redraw everything. Important for UI to update
  renderObjects();
}
const buttonEventHandler2 = (params) => {
  // ... update some item from objectList based on params.

  // redraw everything. Important for UI to update
  renderObjects();
}

您甚至可以更进一步,将

JSON.stringify(objectList)
写入文件,然后读取文件以填充
objectList
的初始值,就像绘画应用程序一样。

© www.soinside.com 2019 - 2024. All rights reserved.