2015-09-22 17 views
5

Ho un elemento canvas HTML e ho implementato un pennello che cattura gli eventi mousedown, mousemove e mouseup dell'elemento canvas. Tutto funziona perfettamente per disegnare sulla tela. Tuttavia, non penso che mi piaccia come non si possa continuare un disegno se il mouse lascia la tela a metà corsa. In un certo senso lo interrompe. A mio parere è molto spietato per la persona e non molto user-friendly.Come disegnare al di fuori di un elemento canvas HTML?

Se si apre Microsoft Paint e si inizia a disegnare con il pennello o l'ellisse o qualcosa del genere, se si inizia all'interno dell'area di disegno, è possibile trascinare il mouse in qualsiasi punto dello schermo e reinserire la tela ovunque. Inoltre, rende facile, ad esempio, disegnare quarti di cerchio negli angoli perché è possibile trascinare lo strumento di ellisse fuori dallo schermo. Spero che abbia senso.

In ogni caso, mi chiedevo se c'era un modo per implementare questo con la tela HTML5 o come avrei implementato questo tipo di cose. L'utente non avrebbe mai visto effettivamente qualcosa disegnato lì; per lo più sarà solo una funzionalità per l'usabilità.

Modifica: un problema con molte di queste soluzioni è come gestire le coordinate. Attualmente la mia tela è al centro dello schermo e quella in alto a sinistra è (0, 0) e quella in basso è (500, 500). Anche il lavoro di traduzione delle coordinate deve essere considerato.

Edit2: Ho scoperto che a quanto pare è possibile trarre i limiti della tela bene. Ad esempio, puoi fornire larghezze, altezze e coordinate negative e l'elemento canvas lo gestirà bene. Quindi, in pratica, la soluzione probabilmente riguarderà solo l'acquisizione del documento mousemove e mouseup e la semplice conversione di x e per iniziare nell'angolo in alto a sinistra della tela.

+3

Potrebbe catturare il mouse eventi sulla finestra stessa e quindi delegare alla tela? – zero298

+0

Forse prova a postare un esempio di ciò che hai attualmente. È più semplice aiutare se non dovessimo prima ricreare il nostro esempio "spezzato". – duncanhall

+0

Forse potresti anche rendere l'elemento canvas in larghezza e altezza della finestra e l'area di disegno leggermente più piccola all'interno dell'area di disegno? –

risposta

1

Ecco un estremamente pericolosa prima bozza di come si può ascoltare per gli eventi del mouse sulla finestra, piuttosto che la tela per essere in grado di disegnare in modo continuo:

var logger = document.getElementById("logger"), 
 
    mState = document.getElementById("mState"), 
 
    mX = document.getElementById("mX"), 
 
    mY = document.getElementById("mY"), 
 
    cX = document.getElementById("cX"), 
 
    cY = document.getElementById("cY"), 
 
    c = document.getElementById("canvas"), 
 
    ctx = c.getContext("2d"); 
 

 
var mouse = { 
 
    x: 0, 
 
    y: 0, 
 
    state: "" 
 
}; 
 

 
function printCanvasLocation() { 
 
    var b = c.getBoundingClientRect(); 
 
    cX.innerHTML = b.top; 
 
    cY.innerHTML = b.left; 
 
} 
 

 
function setState(mouseE, state) { 
 
    mouse.x = mouseE.clientX; 
 
    mouse.y = mouseE.clientY; 
 

 
    mX.innerHTML = mouseE.clientX; 
 
    mY.innerHTML = mouseE.clientY; 
 
    if (state) { 
 
    mState.innerHTML = state; 
 
    mouse.state = state; 
 
    } 
 
} 
 

 
window.addEventListener("mousedown", function(mouseE) { 
 
    setState(mouseE, "down"); 
 
}); 
 

 
window.addEventListener("mouseup", function(mouseE) { 
 
    setState(mouseE, "up"); 
 
}); 
 

 
window.addEventListener("mousemove", function(mouseE) { 
 
    var offset = c.getBoundingClientRect(); 
 

 
    var fix = { 
 
    x1: (mouse.x - offset.left), 
 
    y1: (mouse.y - offset.top), 
 
    x2: (mouseE.clientX - offset.left), 
 
    y2: (mouseE.clientY - offset.top) 
 
    }; 
 

 
    if (mouse.state === "down") { 
 
    ctx.moveTo(fix.x1, fix.y1); 
 
    ctx.lineTo(fix.x2, fix.y2); 
 
    ctx.strokeStyle = "#000"; 
 
    ctx.stroke(); 
 
    } 
 
    setState(mouseE); 
 
}); 
 

 
window.addEventListener("resize", function() { 
 
    printCanvasLocation(); 
 
}); 
 

 
printCanvasLocation();
  .center { 
 

 
       text-align: center; 
 

 
      } 
 

 
      canvas { 
 

 
       background-color: lightblue; 
 

 
      }
<main> 
 
    <div class="center"> 
 
    <canvas id="canvas" width="128" height="128">If you can see me, you should update your browser</canvas> 
 
    </div> 
 
    <div id="logger" role="log"> 
 
    <span>State: </span><span id="mState">Unknown</span> 
 
    <span>X: </span><span id="mX">Unknown</span> 
 
    <span>Y: </span><span id="mY">Unknown</span> 
 
    <span>Canvas X: </span><span id="cX">Unknown</span> 
 
    <span>Canvas Y: </span><span id="cY">Unknown</span> 
 
    </div> 
 
</main>

+0

Il tuo 'Canvas X' e' Canvas Y' sono indietro ma in caso contrario ottima risposta! Penso che lo farò. –

2

Ecco un modo è possibile mantenere disegno quando Immettere nuovamente la tela:

  • Creare una variabile globale e impostare quello di vero su mousedown
  • Aggiungi un evento globale per mouseup in modo da poter prendere se qualcuno farlo al di fuori la tela, e in tal caso, impostare la variabile globale su false, e MouseUp necessità dell'elemento canvas naturalmente anche per impostare la stessa variabile
  • su MouseMove, verificare la presenza di variabile globale per essere vero prima di disegnare

Per disegnare "fuori" la tela, come i cerchi di quarto in un angolo, spostarei tutti gli eventi a livello di documento come gestore globale e catturare l'elemento canvas al clic e passare le sue coordinate client per essere calcolato con le coordinate del documento .

Problemi correlati