찾다

 >  Q&A  >  본문

이미지를 드래그하여 캔버스에 배치하는 방법에 대한 단계별 가이드

내가 만든 것과 동일한 크기의 이미지를 캔버스 안에 드래그 앤 드롭하려고 하는데 작동하지 않습니다.

으아아아 으아아아 으아아아

일부 이미지를 캔버스에 끌어다 놓으려고 합니다. 드래그할 수는 있지만 드롭하려고 하면 작동하지 않습니다. 코드는 다음과 같습니다:

으아아아

다음은 HTML 예입니다. 이미지를 캔버스에 넣고 싶다는 것을 알 수 있습니다. 캔버스용 JavaScript는 다음과 같습니다.

//Javascript per la creazione di cirucuiti elettrici

const NUMERO_CICLO = 990;
const NUMERO_CICLO_INTERNO = 60;


const resistor = document.getElementById("component_circuit_resistor");
const condensator = document.getElementById("component_circuit_condensator");
const tranistor = document.getElementById("component_circuit_tranistor");
const alimentator = document.getElementById("component_circuit_alimentator");
const circuit = document.getElementById("components_circuit");
const back_button = document.getElementById("back-button");
const clear_button = document.getElementById("clear-button");
const draggable = document.querySelectorAll(".draggable");
const container = document.querySelectorAll(".container");
const canvas = document.getElementById("canvas");
const foward_button = document.getElementById("foward-button");

canvas.width = 1500;
canvas.height = 855;
canvas.style.backgroundColor = "lightgrey";
circuit.appendChild(canvas);
canvas.style.borderRadius = "10px";
canvas.style.marginLeft = "auto";
canvas.style.marginRight = "auto";
canvas.style.display = "block";
const ctx = canvas.getContext("2d");


const circles = [];
const lines = [];
const lines_c = [];
var deletedLines = [];

for (let y = 20; y <= NUMERO_CICLO; y += 20) {
  for (let i = 0; i < NUMERO_CICLO_INTERNO; i++) {
    circles.push({
      x: 13 + i * 25,
      y,
      radius: 5,
      color: "grey",
    });
  }
}

let startCircle = null;
let endCircle = null;


function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  circles.forEach((circle) => {
    ctx.beginPath();
    ctx.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
    ctx.fillStyle = circle.color;
    ctx.fill();
  });
  lines.forEach((line) => {
    ctx.beginPath();
    ctx.lineWidth = 4;
    ctx.moveTo(line.start.x, line.start.y);
    ctx.lineTo(line.end.x, line.end.y);
    ctx.stroke();
  });
  if (startCircle && endCircle) {
    ctx.beginPath();
    ctx.lineWidth = 4;
    ctx.moveTo(startCircle.x, startCircle.y);
    ctx.lineTo(endCircle.x, endCircle.y);
    ctx.stroke();
  }
  requestAnimationFrame(draw);
}
draw();

function goBack() {
  if (lines.length > 0 && back_clicked == true) {
    const eliminato = lines.pop();
    deletedLines.push(eliminato);
  }
  else if(foward_clicked == true && deletedLines.length > 0){
    const lastDeleted = deletedLines[deletedLines.length - 1];
    if (!lines.includes(lastDeleted)) {
      lines.push(lastDeleted);
      deletedLines.pop();
    }
  }
  //se non ci sono linee da eliminare mando alert
  else if (lines.length == 0 && back_clicked == true) {
    alert("There are no lines to delete");
  }
}

function clearCanvas() {
    if(confirm("Are you sure you want to delete the circuit?")){
      lines.length = 0;
      deletedLines.length = 0;
      lastDeleted = null;
    }
}

function getNearestCircle(x, y) {
  let nearestCircle = null;
  let nearestDistance = Infinity;
  circles.forEach((circle) => {
    const distance = Math.sqrt((circle.x - x) ** 2 + (circle.y - y) ** 2);
    if (distance < nearestDistance && distance < 30) {
      nearestCircle = circle;
      nearestDistance = distance;
    }
  });
  return nearestCircle;
}

let isDrawing = false;

canvas.addEventListener("mousedown", (event) => {
  const x = event.offsetX;
  const y = event.offsetY;
  const circle = getNearestCircle(x, y);
  if (circle) {
    startCircle = circle;
    endCircle = { x, y };
    isDrawing = true;
  }
});

canvas.addEventListener("mousemove", (event) => {
  if (isDrawing) {
    endCircle.x = event.offsetX;
    endCircle.y = event.offsetY;
  } else {
    const x = event.offsetX;
    const y = event.offsetY;
    const circle = getNearestCircle(x, y);
    if (circle) {
      circles.forEach((circle) => {
        circle.color = "grey";
      });
      circle.color = "red";
    } else {
      circles.forEach((circle) => {
        circle.color = "grey";
      });
    }
  }
});

canvas.addEventListener("mouseup", () => {
    if (isDrawing) {
        const x = endCircle.x;
        const y = endCircle.y;
        const circle = getNearestCircle(x, y);
        if (circle) {
        lines.push({
            start: startCircle,
            end: circle,
        });
        }
        isDrawing = false;
        startCircle = null;
        endCircle = null;
    }
});

//back_button.addEventListener("click", goBack);
//foward_button.addEventListener("click", goBack);
clear_button.addEventListener("click", clearCanvas);
var back_clicked = false;
back_button.addEventListener("click", function(){
  back_clicked = true;
  goBack();
  back_clicked = false;
})

var foward_clicked = false;
foward_button.addEventListener("click", function () {
  foward_clicked = true;
  goBack();
  foward_clicked = false;
})

  //risposta stack overflow
const draggableImages = document.querySelectorAll('img[draggable]');
for (const img of draggableImages)
  img.ondragstart = (ev) => {
    ev.dataTransfer.setData('text', img.src);
  };

canvas.ondragover = (ev) => ev.preventDefault(); // IMPORTANT

canvas.ondrop = (ev) => {
  const img = new Image();
  img.src = ev.dataTransfer.getData('text');
  img.onload = () => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img, 0, 0);
  };
};  

P粉207483087P粉207483087276일 전424

모든 응답(1)나는 대답할 것이다

  • P粉808697471

    P粉8086974712024-02-18 00:25:15

    당신에게:

    으아아아 으아아아

    회신하다
    0
  • 취소회신하다