2013-07-01 19 views
15

Sto provando a disegnare un rettangolo facendo clic, spostando il mouse e facendo clic. Ci sono due problemi con il mio codice.Disegnare un rettangolo utilizzando il clic, spostare il mouse e fare clic su

Innanzitutto, dopo aver disegnato un rettangolo, si presume automaticamente che verrà disegnato un altro. In secondo luogo, il punto di partenza sul secondo rettangolo è l'ultimo clic che ha creato il primo rettangolo.

http://jsbin.com/uqonuw/3/edit

+0

È possibile rimuovere quella demo in * solo * le parti che riguardano il problema del disegno? Non sono affatto convinto che abbiamo bisogno delle parti incluso 'spin', o analisi di' document.location'. –

+0

I tuoi 2 problemi sono gli stessi da dove lo vedo. Penso che potresti considerare di utilizzare un semplice test per vedere se questo è il "primo" clic o il "secondo" –

risposta

8

Ecco come click-sposta-clic per creare un rettangolo

Creare queste variabili:

var isDrawing=false; 
var startX; 
var startY; 

Nel vostro gestore di eventi MouseDown:

  • Se questo è il clic iniziale, imposta il isDrawing flag e imposta startX/Y.
  • Se questo è il clic finale, deselezionare la pagina isDrawing e disegnare il rettangolo.

Si potrebbe anche voler cambiare il cursore del mouse in modo che l'utente sappia che sta disegnando.

if(isDrawing){ 
    isDrawing=false; 
    ctx.beginPath(); 
    ctx.rect(startX,startY,mouseX-startX,mouseY-startY); 
    ctx.fill(); 
    canvas.style.cursor="default"; 
}else{ 
    isDrawing=true; 
    startX=mouseX; 
    startY=mouseY; 
    canvas.style.cursor="crosshair"; 
} 

Ecco un violino: http://jsfiddle.net/m1erickson/7uNfW/

Invece di click-sposta-clic, come sull'utilizzo di trascinare per creare un rettangolo?

creare queste variabili:

var mouseIsDown=false; 
var startX; 
var startY; 

Nel vostro gestore di eventi MouseDown, impostare il flag mouseIsDown e impostare lo startx/Y.

Opzionalmente, cambiare il cursore in modo che l'utente sappia come trascinare un rettangolo.

 mouseIsDown=true; 
     startX=mouseX; 
     startY=mouseY; 
     canvas.style.cursor="crosshair"; 

Nel vostro gestore di eventi MouseUp, deselezionare il flag mouseIsDown e disegnare il rettangolo

Se è stato modificato il cursore, cambiare di nuovo.

 mouseIsDown=false; 
     ctx.beginPath(); 
     ctx.rect(startX,startY,mouseX-startX,mouseY-startY); 
     ctx.fill(); 
     canvas.style.cursor="default"; 
24

Eri vicino. Quindi, la domanda non riguarda proprio l'elemento "tela" in HTML5, ma una tela che è davvero una div.

http://jsfiddle.net/d9BPz/546/

Al fine per me vedere che cosa il vostro codice è stato cercando di realizzare, ho dovuto riordinare in su. Quello che doveva succedere era il tracciamento dell'elemento quadrato.

Facciamo una delle due cose ogni volta che clicchiamo sulla tela. Stiamo creando un elemento rettangolare o finendo un elemento rettangolare. Quindi, quando abbiamo finito, ha senso impostare 'elemento' (precedentemente chiamato 'd') su null. Quando creiamo un elemento, dobbiamo assegnare il nuovo elemento DOM a 'elemento'.

Ogni volta che il mouse si muove, vogliamo ottenere la posizione del mouse. Se l'elemento è nel processo di creazione (o "non null"), allora abbiamo bisogno di ridimensionare l'elemento.

Poi avvolgere il tutto in una funzione, e che è tutto là è ad esso:

function initDraw(canvas) { 
    var mouse = { 
     x: 0, 
     y: 0, 
     startX: 0, 
     startY: 0 
    }; 
    function setMousePosition(e) { 
     var ev = e || window.event; //Moz || IE 
     if (ev.pageX) { //Moz 
      mouse.x = ev.pageX + window.pageXOffset; 
      mouse.y = ev.pageY + window.pageYOffset; 
     } else if (ev.clientX) { //IE 
      mouse.x = ev.clientX + document.body.scrollLeft; 
      mouse.y = ev.clientY + document.body.scrollTop; 
     } 
    }; 

    var element = null;  
    canvas.onmousemove = function (e) { 
     setMousePosition(e); 
     if (element !== null) { 
      element.style.width = Math.abs(mouse.x - mouse.startX) + 'px'; 
      element.style.height = Math.abs(mouse.y - mouse.startY) + 'px'; 
      element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px'; 
      element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px'; 
     } 
    } 

    canvas.onclick = function (e) { 
     if (element !== null) { 
      element = null; 
      canvas.style.cursor = "default"; 
      console.log("finsihed."); 
     } else { 
      console.log("begun."); 
      mouse.startX = mouse.x; 
      mouse.startY = mouse.y; 
      element = document.createElement('div'); 
      element.className = 'rectangle' 
      element.style.left = mouse.x + 'px'; 
      element.style.top = mouse.y + 'px'; 
      canvas.appendChild(element) 
      canvas.style.cursor = "crosshair"; 
     } 
    } 
} 

Uso: Passare l'elemento a livello di blocco che si desidera fare una tela rettangolo. Esempio:

<!doctype html> 
<html> 
<head> 
    <style> 
    #canvas { 
     width:2000px; 
     height:2000px; 
     border: 10px solid transparent; 
    } 
    .rectangle { 
     border: 1px solid #FF0000; 
     position: absolute; 
    } 
    </style> 
</head> 
<body> 
    <div id="canvas"></div> 
    <script src="js/initDraw.js"></script> 
    <script> 
     initDraw(document.getElementById('canvas')); 
    </script> 
</body> 
</html> 
+0

Questa soluzione si interrompe quando la finestra scorre. I rettangoli non verranno posizionati nella posizione corretta quindi. – Max

+0

@Max Confermato in firefox: prova a fare clic, scorrere e quindi spostare il mouse. – NonameSL

0

Per coloro che ha incontrato il problema di scorrimento, ho trovato una soluzione.
È necessario ottenere l'offset (utilizzando window.pageYOffset) e ridurlo dalla posizione del mouse in uno dei frammenti consigliati forniti. Dovresti toglierlo anche dall'altezza.

+0

Questo non fornisce una risposta alla domanda. Una volta che hai [reputazione] sufficiente (https://stackoverflow.com/help/whats-reputation) sarai in grado di [commentare qualsiasi post] (https://stackoverflow.com/help/privileges/comment); invece [fornisci risposte che non richiedono chiarimenti da parte del richiedente] (https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can- i-do-, invece). - [Dalla recensione] (/ recensione/post di bassa qualità/17608407) – haindl

+0

Se hai una nuova domanda, per favore chiedi facendo clic sul pulsante [Chiedi domanda] (https://stackoverflow.com/questions/ask). Includere un collegamento a questa domanda se aiuta a fornire il contesto. - [Dalla recensione] (/ recensione/post di bassa qualità/17608407) –

Problemi correlati