2014-10-07 10 views
6

Scopo del mio codice:Ottenere coordinate di due posti diversi su tela HTML

  1. disegnare un piccolo rettangolo su una tela HTML ogni volta che un utente fa clic sul tela. Il rettangolo dovrebbe avere un numero piccolo che rappresenta il numero di rettangoli creati dall'utente.

  2. L'utente deve essere in grado di collegare due rettangoli utilizzando una linea retta. (Preferibilmente semplicemente premendo il tasto sinistro del mouse, e prendendo il mouse dal primo rettangolo a secondo rettangolo)

approccio e il mio tentativo

Come si può vedere in questa jsFiddle, sono stato in grado di raggiungere la prima parte di sopra molto bene. Facendo clic sulla tela, viene creato un rettangolo con un numero al suo interno. Ma sono davvero all'oscuro della seconda parte.

Come faccio a connettere l'utente con due rettangoli creati? Voglio che la connessione venga effettuata solo se c'è un rettangolo (quindi avrei bisogno di memorizzare le coordinate di ogni rettangolo che è stato fatto, va bene, perché posso usare un array per questo). Fondamentalmente, voglio solo verificare se il mouse era in un posto e mouseup all'altro. Come ottengo queste due coordinate diverse (una di mouse e l'altra di mouseup) e traccia una linea tra di esse? Mi hanno dato il violino sopra, ma ancora ecco la mia jquery:

$(function() { 
    var x, y; 
    var globalCounter = 0; 
    $('#mycanvas').on("click", function (event) { 

     x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 
     x -= mycanvas.offsetLeft; 

     y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
     y -= mycanvas.offsetLeft; 

     // alert("x:"+x+"y: "+y); 

     drawRectangle(x, y); 
    }); 

    function drawRectangle(x, y) { 
     var acanvas = document.getElementById("mycanvas"); 
     var context = acanvas.getContext("2d"); 
     context.strokeRect(x, y, 25, 25); 
     globalCounter++; 
     writeNo(x, y, globalCounter); 
    } 

    function writeNo(x, y, n) { 
     var acanvas = document.getElementById("mycanvas"); 
     var context = acanvas.getContext("2d"); 
     context.font = "bold 14px sans-serif"; 
     context.fillText(n, x + 8, y + 12.5); 
    } 
}); 

La questione principale è quindi: che collega i due rettangoli fatte da mouseDrag

Come faccio a raggiungere questo obiettivo? Grazie.

+0

come si presenta la "connessione"? –

+0

Il collegamento è solo una linea, una linea retta che collega i centri di due rettangoli –

+1

È necessario prima utilizzare eventi diversi. uno per creare un elemento e un altro per disegnare una linea. non è possibile utilizzare l'evento click per entrambe le attività poiché il disegno di una linea utilizza indirettamente anche l'evento click. mouseup e mousedown creeranno un conflitto in modo migliore per differenziarli. Ho fatto un po 'la stessa attività su https://github.com/alpesh1988/ETSAssignment .. puoi usarlo come riferimento. fammi sapere se hai dei dubbi –

risposta

4

ne dite di questo: http://jsfiddle.net/4jqptynt/4/

Ok, prima ho fatto un po 'di refactoring per il codice per rendere le cose più facili. Solo cose come mettere il codice che ottiene le coordinate del canvas nella sua funzione, e mettere in cache alcune variabili (come il contesto della tela) nello scope della funzione esterna. Oh, e definendo le dimensioni del rettangolo come costanti perché useremo gli stessi numeri in un paio di luoghi diversi.

Come hai detto, la prima cosa di cui abbiamo bisogno è tenere traccia dei rettangoli esistenti usando un array rects (abbastanza facile da fare entro drawRectangle). Allora una funzione per controllare se una particolare coppia di coordinate sono entro alcuni rettangolo:

function inRectangle(x, y) { 

    for (var i = 0, l = rects.length; i < l; i++) { 

     if ((x - rects[i].x) <= RECT_X && (y - rects[i].y) <= RECT_Y && 
       (x - rects[i].x) >= 0 && (y - rects[i].y) >= 0) { 

      return i;  

     } 

    } 

} 

dove RECT_X & RECT_Y definiscono i lati del rettangolo. Se le coordinate esistono all'interno di un rettangolo, questo restituirà l'indice di quel rettangolo all'interno dell'array rects.

allora è un caso di verificare se un mousedown verificato all'interno di un rettangolo, notando che inRectangle restituisce solo un numero se l'evento mousedown era in un rettangolo:

$acanvas.on("mousedown", function (event) { 

    var coords = getCoords(event), 
     rect = inRectangle(coords.x, coords.y); 

    if (typeof rect === "number") { 
     dragStart = rect + 1; 
    } else { 
     drawRectangle(coords.x, coords.y); 
    } 

}); 

caso affermativo, annotare di quale rettangolo usando dragStart, se non si disegna un rettangolo come prima.

Poi per completare la resistenza, abbiamo bisogno di allegare un gestore per mouseup:

$acanvas.on("mouseup", function (event) { 

    if (!dragStart) { return; } 

    var coords = getCoords(event), 
     rect = inRectangle(coords.x, coords.y); 

    if (typeof rect === "number") { 
     drawConnection(dragStart - 1, rect); 
    } 

    dragStart = 0; 

}); 

Se è stata avviata alcuna resistenza, quindi non fa nulla. Se le sue coordinate non sono all'interno di un rettangolo, non fa nulla ma resetta dragStart. Se, tuttavia, si trova all'interno di un rettangolo, viene disegnata una linea di collegamento:

function drawConnection(rect1, rect2) { 

    context.strokeStyle = "black"; 
    context.lineWidth = 1; 
    context.beginPath(); 
    context.moveTo(rects[rect1].x + RECT_X/2, rects[rect1].y + RECT_Y/2); 
    context.lineTo(rects[rect2].x + RECT_X/2, rects[rect2].y + RECT_Y/2); 
    context.stroke(); 
    context.closePath(); 

} 
Problemi correlati