我试图将一些图像拖放到我的画布中,大小与我制作的相同,但不起作用.

//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);
  };
};  
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
html,body{
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
    background-color: #ede7e1;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    font-size: 14px;
    color: #333;
    line-height: 1.5;
    overflow-x: hidden;
}

img{
    width: 100%;
    height: 100%;
}

#h1_disegna{
    text-align: center;
}
#h1_breadboard{
    text-align: center;
    position: relative;
    top: -550px;
}

#h1_titolo{
    font-size: 60px;
    text-align: center;
}
#h3_componenti_circuit{
    border-style: solid;
    width: 100px;
    border-color: black rigid 1px;
    list-style-type: none;
    margin-left: 0px;
    padding-left: 0px;
    background-color: sandybrown;
    position: relative;
    top: 85px;
}

#h3_componenti_br{
    border-style: solid;
    width: 100px;
    border-color: black rigid 1px;
    list-style-type: none;
    margin-left: 0px;
    padding-left: 0px;
    background-color: sandybrown;
    position: relative;
    top: -500px;
}

#h4_footer{
    font-size: 26px;
}


.elementi_disegno{
    position: relative;
    top: -520px;
}

#canvas{
    position: relative;
    top: -520px;
    
}

#back-button{
    position: relative;
    top: 62%;
    left: 42.5%;
    transform: translate(-50%, -50%);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    font-size: 24px;
    background-color: rgba(244, 165, 96, 0.473);
    border-radius: 6px;
    cursor: pointer;
}

#foward-button{
    position: relative;
    top: 62%;
    left: 43%;
    transform: translate(-50%, -50%);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    font-size: 24px;
    background-color: rgba(244, 165, 96, 0.473);
    border-radius: 6px;
    cursor: pointer;
}

#clear-button{
    border-radius: 6px;
    position: relative;
    top: 62%;
    left: 44.5%;
    transform: translate(-50%, -50%);
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    font-size: 24px;
    background-color: rgba(244, 165, 96, 0.473);
    cursor: pointer;
}
#components_circuit_border{
    border-style: solid;
    width: 100px;
    border-color: black rigid 1px;
    list-style-type: none;
    margin-left: 0px;
    padding-left: 0px;
    background-color: antiquewhite;
    cursor: move;
    position: relative;
    top: 85px;
}

#components_br_border{
    border-style: solid;
    width: 100px;
    border-color: black rigid 1px;
    list-style-type: none;
    margin-left: 0px;
    padding-left: 0px;
    background-color: antiquewhite;
    cursor: move;
    position: relative;
    top: -500px;
}

#components_circuit{
    list-style-type: none;
    margin-left: 0px;
    padding-left: 0px;
}
.footer{
    text-align: center;
    background-color: darkgray;
    left: 0;
    margin-bottom: 0;
    height: 40px;
    width: 100%;
}

.material-symbols-outlined{
    display: inline-flex;
    vertical-align: -3px;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0" />
    <link rel="stylesheet" href="style.css">
    <title>From Circuit to Breadboard</title>
</head>
<body>
    <h1 id="h1_titolo">From Circuit to Breadboard</h1>
    <div class="container">
        <div class="components">
            <div id="components_circuit">
                <h3 id ="h3_componenti_circuit">Componenti:</h3>
                    <ul id="components_circuit_border">
                        <li><img id ="component_circuit_resistor" src="images/circuit_resistor.png" height="50" draggable></li>
                        <br><br>
                        <li><img id = "component_circuit_condensator" src="images/circuit_condensator.png" height="50" draggable></li>
                        <br><br>
                        <li><img id="component_circuit_transistor" src="images/circuit_transistor.png" height="50" draggable></li>
                        <br><br>
                        <li><img id="component_circuit_alimentator" src="images/circuit_alimentator.png" height="50" draggable></li>
                        <!-- <li><img
                            src="https://i.kym-cdn.com/entries/icons/original/000/006/428/637738.jpg"
                            height="50px"
                            draggable
                          /></li>
                          <li>
                            <img
                              src="https://ftw.usatoday.com/wp-content/uploads/sites/90/2017/05/spongebob.jpg?w=1000&h=600&crop=1"
                              height="50px"
                              draggable
                            />
                          </li>
                          <li>
                            <img
                              src="https://pyxis.nymag.com/v1/imgs/0f9/f96/029acbf4c6d8c67e138e1eb06a277204bf-05-patrick.rsquare.w700.jpg"
                              height="50px"
                              draggable
                            />
                          </li> -->
                    </ul>
                <div class = "elementi_disegno">
                    <h1 id ="h1_disegna">Disegna il tuo circuito!</h1>
                <button id="back-button">Indietro
                    <span class="material-symbols-outlined">undo</span>
                </button>
                <button id="foward-button">Avanti
                    <span class="material-symbols-outlined">redo</span>
                </button>
                <button id="clear-button">Clear All
                    <span class="material-symbols-outlined">delete</span>
                </button>
                <canvas id = "canvas" class = "dropzone"></canvas>
                </div>
            </div>
            <br>
            <br>
            <div id="components_br">
                <h1 id = "h1_breadboard">Breadboard</h1>
                <h3 id ="h3_componenti_br">Componenti:</h3>
                <ul id="components_br_border">
                    <li><img id = "component_br_resistor" src="images/br_resistor.png" height="50" draggable="true"></li>
                    <br><br>
                    <li><img id = "component_br_condensator" src="images/br_condensator.png" height="50" draggable="true"></li>
                    <br><br>
                    <li><img id = "component_br_transistor" src="images/br_transistor.png" height="50" draggable="true"></li>
                    <br><br>
                    <li><img id="component_br_alimentator" src="images/br_alimentator.png" height="50" draggable="true"></li>
                </ul>   
            </div>
        </div>
    </div>
    

    <footer class="footer">
        <div>
          <h4 id ="h4_footer">Website made by Skerdi Velo, Davide Rossini, Andrea Quagliotti<span class="material-symbols-outlined">copyright</span></h4>
        </div>
    </footer>
    
    <script src="script.js"></script>
</body>
</html>

我正在try 将一些图像拖放到我的画布中.它可以让我拖动它,但当我想要放下它时,它不起作用.代码如下:

<div class="container">
    <div class="components">
        <div id="components_circuit">
            <h3 class ="h3_componenti" id ="h3_componenti_circuit">Componenti:</h3>
            <ul id="components_circuit_border">
                <li><img id ="component_circuit_resistor" src="images/circuit_resistor.png" height="50"></li>
                <li><img id = "component_circuit_condensator" src="images/circuit_condensator.png" height="50" draggable="true"></li>
                <li><img id="component_circuit_transistor" src="images/circuit_transistor.png" height="50" draggable="true"></li>
                <li><img id="component_circuit_alimentator" src="images/circuit_alimentator.png" height="50" draggable="true"></li>
            </ul>
            <canvas id = "canvas"></canvas>
        </div>
    </div>
</div>

这是一个超文本标记语言的例子,正如你所看到的,我有我想要放在画布上的图像.下面是画布上的Java脚本:

const draggableClass = document.getElementsByClassName("draggable");
const draggable = document.querySelectorAll(".draggable");
const container = document.querySelectorAll(".container");

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

推荐答案

这是给你的:

//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');

/** EDIT START */
const draggableImages = document.querySelectorAll('img[draggable]');

for (let i = 0; i < draggableImages.length; i++)
  draggableImages[i].ondragstart = (ev) => {
    ev.dataTransfer.setData('text/plain', i.toString());
  };

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

const drawnImageData = [];

canvas.ondrop = (ev) => {
  const index = parseInt(ev.dataTransfer.getData('text/plain'));
  const img = draggableImages[index];
  drawnImageData.push({ img, x: ev.offsetX, y: ev.offsetY });
};
/** EDIT END */

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();
  }
  /** EDIT START */
  for (const data of drawnImageData)
    ctx.drawImage(data.img, data.x, data.y, data.img.width, data.img.height);
  /** EDIT END */
  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;
});
<h1 id="h1_titolo">From Circuit to Breadboard</h1>
<div class="container">
  <div class="components">
    <div id="components_circuit">
      <h3 id="h3_componenti_circuit">Componenti:</h3>
      <ul id="components_circuit_border">
        <li>
          <img
            id="component_circuit_resistor"
            src="https://i.kym-cdn.com/entries/icons/original/000/006/428/637738.jpg"
            height="50"
            draggable
          />
        </li>
        <br /><br />
        <li>
          <img
            id="component_circuit_condensator"
            src="https://ftw.usatoday.com/wp-content/uploads/sites/90/2017/05/spongebob.jpg"
            height="50"
            draggable
          />
        </li>
        <br /><br />
        <li>
          <img
            id="component_circuit_transistor"
            src="https://pyxis.nymag.com/v1/imgs/0f9/f96/029acbf4c6d8c67e138e1eb06a277204bf-05-patrick.rsquare.w700.jpg"
            height="50"
            draggable
          />
        </li>
        <br /><br />
      </ul>
      <div class="elementi_disegno">
        <h1 id="h1_disegna">Disegna il tuo circuito!</h1>
        <button id="back-button">
          Indietro
          <span class="material-symbols-outlined">undo</span>
        </button>
        <button id="foward-button">
          Avanti
          <span class="material-symbols-outlined">redo</span>
        </button>
        <button id="clear-button">
          Clear All
          <span class="material-symbols-outlined">delete</span>
        </button>
        <canvas id="canvas" class="dropzone"></canvas>
      </div>
    </div>

您可以使用CanvasRenderingContext2D.drawImage()将图像加载到画布中,其中CanvasRenderingContext2D.drawImage()接受HTMLImageElement.您可以将可拖动的图像存储在数组中,并在开始拖动时传递图像的索引.

const draggableImages = document.querySelectorAll('img[draggable]');

for (let i = 0; i < draggableImages.length; i++)
  draggableImages[i].ondragstart = (ev) => {
    ev.dataTransfer.setData('text/plain', i.toString());
  };

由于您使用的是动画帧,因此需要存储在画布上绘制的图像以及它们的位置.为了简单起见,我使用了一个数组,但如果您要允许删除、重新拖动、调整大小等,您可能需要其他array.

const drawnImageData[] = [];

现在,要在画布上触发drop事件,您需要阻止ondragover事件的默认行为.

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

然后在触发ondrop事件时获取图像的索引.将图像IntrodrawnImages与指示绘制位置的x和y坐标放在一起.我使用的是相对于画布左上角的位置.

canvas.ondrop = (ev) => {
  const index = parseInt(ev.dataTransfer.getData('text/plain'));
  const img = draggableImages[index];
  drawnImageData.push({ img, x: ev.offsetX, y: ev.offsetY });
};

现在在您的draw函数中绘制图像.

for (const data of drawnImageData)
    ctx.drawImage(data.img, data.x, data.y, data.img.width, data.img.height);

Javascript相关问答推荐

如何在react + react路由域名中使用DeliverBrowserRouter?

在JavaScript中检索一些文本

单击更新页面的按钮后,页面刷新;测试/断言超时,有两个标题,但没有一个标题

zoom svg以适应圆

togglePopover()不打开但不关闭原生HTML popover'

Regex结果包含额外的match/group,只带一个返回

我的角模板订阅后不刷新'

有条件重定向到移动子域

从页面到应用程序(NextJS):REST.STATUS不是一个函数

Reaction组件在本应被设置隐藏时仍显示

将异步回调转换为异步生成器模式

向数组中的对象添加键而不改变原始变量

基于产品ID更新条带产品图像的JavaScript命中错误

处理app.param()中的多个参数

如何组合Multer上传?

React Refs不与高阶组件(HOC)中的动态生成组件一起工作

AG-GRIDreact 显示布尔值而不是复选框

MUI迷你图:如何将$符号添加到MUI迷你图中的工具提示数据

如何处理不带参数的redux thunk payloadCreator回调函数?

如果查询为空,则MongoDB将所有文档与$in匹配