Home  >  Q&A  >  body text

The start and end points of the image

<p>我正在尝试设置图像的起点和终点。所以我有我的画布和图像,当我将图像放入画布时,我希望当我将鼠标悬停在起点/终点时,它会亮起一个小红色圆圈,这意味着我可以与其他图像创建连接。例如:<strong>1) 拖动图像。 2) 将图像放入画布内。 3)鼠标悬停到起点/终点,小红点亮起。</strong> </p> <p>如您所见,红点仅在悬停时出现。另一个问题,但如果你解决第一个问题很酷,图像不会跟随烤架(正方形)。 这是 html/js 的示例</p> <p> <pre class="brush:js;toolbar:false;">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 orderStack = []; const deletedOrderStack = []; const drawnImageData = []; const deletedImageData = []; canvas.ondrop = (ev) => { const index = parseInt(ev.dataTransfer.getData('text/plain')); const img = draggableImages[index]; const x = ev.clientX - canvas.offsetLeft - img.width / 2; const y = ev.clientY - canvas.offsetTop - img.height / 2; const squareSize = 10; // adjust this to match the size of your squares const maxSize = 75; // maximum size of the image const aspectRatio = img.width / img.height; let width = maxSize; let height = maxSize / aspectRatio; if (height > maxSize) { height = maxSize; width = height * aspectRatio; } const snappedX = Math.round(x / squareSize) * squareSize; const snappedY = Math.round(y / squareSize) * squareSize; ctx.drawImage(img, snappedX, snappedY, width, height); drawnImageData.push(ctx.getImageData(0, 0, canvas.width, canvas.height)); orderStack.push(1); deletedImageData.length = 0; deletedOrderStack.length = 0; back_button.disabled = false; back_button.style.cursor = 'pointer'; clear_button.disabled = false; clear_button.style.cursor = 'pointer'; foward_button.disabled = true; foward_button.style.cursor = 'not-allowed'; return false; }; clear_button.disabled = true; clear_button.style.cursor = 'not-allowed'; foward_button.disabled = true; foward_button.style.cursor = 'not-allowed'; back_button.disabled = true; back_button.style.cursor = 'not-allowed'; /** EDIT END */ canvas.width = 1900; canvas.height = 1000; canvas.style.backgroundColor = 'white'; 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 = []; function drawSquares() { const squareSize = 10; const numColumns = Math.floor(canvas.width / squareSize); const numRows = Math.floor(canvas.height / squareSize); ctx.fillStyle = "#FAF9F9"; ctx.strokeStyle = "#F4F1F0"; ctx.lineWidth = 1; for (let i = 0; i < numColumns; i++) { for (let j = 0; j < numRows; j++) { const x = i * squareSize; const y = j * squareSize; if (i % 10 === 0 &amp;&amp; j % 10 === 0) { ctx.lineWidth = 2.6; ctx.fillStyle = "#F1ECEB"; ctx.strokeStyle = "#E6E0DE"; // set the stroke color to a darker shade ctx.strokeRect(x, y, squareSize * 10, squareSize * 10); ctx.fillStyle = "#F4F1F0"; ctx.strokeStyle = "#F4F1F0"; // reset the stroke color ctx.lineWidth = 1; } else { ctx.strokeRect(x, y, squareSize, squareSize); } } } } drawSquares();</pre> <pre class="brush:html;toolbar:false;"><!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> <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://www.elprocus.com/wp-content/uploads/Resistor-Symbol-768x288.png" height="50" draggable="true"></li> <br><br> <li><img id = "component_circuit_condensator" src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Capacitor_Symbol_alternative.svg/1280px-Capacitor_Symbol_alternative.svg.png" height="50" draggable="true"></li> <br><br> <li><img id="component_circuit_transistor" src="images/circuit_transistor.png" height="50" draggable="true"></li> <br><br> <li><img id="component_circuit_alimentator" src="images/circuit_alimentator.png" height="50" draggable="true"></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> <script src="script.js"></script> </body> </html></pre> </p> <p>提供的代码可能在 stackoverflow 上不起作用,请在本地尝试。如果您使用其他图像,请提供链接。</p>
P粉511757848P粉511757848415 days ago530

reply all(1)I'll reply

  • P粉214089349

    P粉2140893492023-09-01 00:39:24

    You can keep track of the x and y of the image in the array and iterate over the array to check if the mouse pointer is some distance away from any object, if so then draw a circle and in the remote image the connection is if you plan to add more than 2 The image shown (don't know about locally hosted images) and the start and end points are different, then at the midpoint of both sides you will need to use the current settings based on the image change value, you can hardcode it, here is mine accomplish:

    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');
    let images = [];
    
    /** 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 orderStack = [];
    const deletedOrderStack = [];
    
    const drawnImageData = [];
    const deletedImageData = [];
    canvas.ondrop = (ev) => {
        
        const index = parseInt(ev.dataTransfer.getData('text/plain'));
        const img = draggableImages[index];
        const x = ev.clientX - canvas.offsetLeft - img.width / 2;
        const y = ev.clientY - canvas.offsetTop - img.height / 2;
        const squareSize = 10; // adjust this to match the size of your squares
    
    
        const maxSize = 75; // maximum size of the image
        const aspectRatio = img.width / img.height;
        let width = maxSize;
        let height = maxSize / aspectRatio;
        if (height > maxSize) {
          height = maxSize;
          width = height * aspectRatio;
        }
        const snappedX = Math.round(x / squareSize) * squareSize;
        const snappedY = Math.round(y / squareSize) * squareSize;
        ctx.drawImage(img, snappedX, snappedY, width, height);
        images.push({ img, x: snappedX, y: snappedY, width, height });
        // Add the image and its position to the images array
    
      };
      
    
      
     
    clear_button.disabled = true;
    clear_button.style.cursor = 'not-allowed';
    foward_button.disabled = true;
    foward_button.style.cursor = 'not-allowed';
    back_button.disabled = true;
    back_button.style.cursor = 'not-allowed';
    /** EDIT END */
    
    canvas.width = 1900;
    
    canvas.height = 1000;
    canvas.style.backgroundColor = 'white';
    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 = [];
    
    function drawSquares() {
      const squareSize = 10;
      const numColumns = Math.floor(canvas.width / squareSize);
      const numRows = Math.floor(canvas.height / squareSize);
    
      ctx.fillStyle = "#FAF9F9";
      ctx.strokeStyle = "#F4F1F0";
      ctx.lineWidth = 1;
    
      for (let i = 0; i < numColumns; i++) {
        for (let j = 0; j < numRows; j++) {
          const x = i * squareSize;
          const y = j * squareSize;
    
          if (i % 10 === 0 && j % 10 === 0) {
            ctx.lineWidth = 2.6;
            ctx.fillStyle = "#F1ECEB";
            ctx.strokeStyle = "#E6E0DE"; // set the stroke color to a darker shade
            ctx.strokeRect(x, y, squareSize * 10, squareSize * 10);
            ctx.fillStyle = "#F4F1F0";
            ctx.strokeStyle = "#F4F1F0"; // reset the stroke color
            ctx.lineWidth = 1;
          } else {
            ctx.strokeRect(x, y, squareSize, squareSize);
          }
        }
      }
    }
    
    drawSquares();
    
    // Add a mousemove event to the canvas to show the red dot
      const redDotRadius = 5; // The radius of the red dots
      const hoverDistance = 10; // The distance from a point at which to show the dot
    
    canvas.onmousemove = (ev) => {
        const mouseX = ev.clientX - canvas.offsetLeft;
        const mouseY = ev.clientY - canvas.offsetTop;
        
        // Clear the canvas and redraw everything
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        drawSquares();
        for (let i = 0; i < images.length; i++) {
          let image = images[i];
          ctx.drawImage(image.img, image.x, image.y, image.width, image.height);
        }
        
        // Check if the mouse is near a starting or ending point
        for (let i = 0; i < images.length; i++) {
          let image = images[i];
          let startX = image.x+5;
          let startY = image.y + image.height/2;
          let endX = image.x + image.width -5;
          let endY = image.y + image.height/2;
          
          if (Math.abs(mouseX - startX) < hoverDistance && Math.abs(mouseY - startY) < hoverDistance) {
            // Near the starting point, draw a red dot
            ctx.beginPath();
            ctx.arc(startX, startY, redDotRadius, 0, 2 * Math.PI, false);
            ctx.fillStyle = 'red';
            ctx.fill();
          } else if (Math.abs(mouseX - endX) < hoverDistance && Math.abs(mouseY - endY) < hoverDistance) {
            // Near the ending point, draw a red dot
            ctx.beginPath();
            ctx.arc(endX, endY, redDotRadius, 0, 2 * Math.PI, false);
            ctx.fillStyle = 'red';
            ctx.fill();
          }
        }
      };

    I didn’t change the html

    reply
    0
  • Cancelreply