2017-07-14 4 views
0

Ich bin auf der Suche nach einer Möglichkeit, "live" zeichnen Rechtecke oder Kreise auf einer Leinwand.Javascript Leinwand Zeichnen Rechtecke oder Kreise

Ich habe verschiedene Möglichkeiten mit fillRect() gefunden, um Rechtecke zu zeichnen, aber nicht leben. Was ich meine ist, in der Lage zu mouseDown() auf einen Punkt und verschieben Sie es an einen anderen Punkt in der Zeichenfläche, die die Größe der Zeichenfläche, wie zum Beispiel in Microsoft Paint, OneNote und so weiter definiert.

Kann mir jemand helfen und mir einen Rat geben, wie ich anfangen soll? Ich könnte von einer Art und Weise zu denken, wie es zu tun, ohne das Rechteck zu sehen (oder Kreis) Größenänderung, so etwas wie:

$("canvas").mousedown(function(event){ 
    var ctx = this.getContext("2d"); 
    ctx.clearRect(0,0,$(this).width(),$(this).height()); 
    var initialX = event.clientX - this.getBoundingClientRect().left; 
    var initialY = event.clientY - this.getBoundingClientRect().top; 

    $(this).mousemove(function(evt) { 
     ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY); 
    }); 
}); 

Aber ich will es live sehen, so wie die Rechtecke Größe ändert, wenn die Benutzer bewegt die Maus.

+0

Verwenden Sie 'window.requestAnimationFrame()', um das Canvas oft zu aktualisieren – frozen

+0

@ randnum-1 und? Du willst die Leinwand alle 50ms oder so ähnlich in 'setInterval()' bis 'mouseUp' neu zeichnen? – nameless

+0

Ich nehme an, Sie wollen etwas wie diese https://jsfiddle.net/jk607fqn/3/ klicken Sie auf Leinwand, um rotes Quadrat – slackOverflow

Antwort

1

https://jsfiddle.net/zb66mxra/2/

Um es machen Sie ein konstantes Bild Ihrer Leinwand halten leben müssen. Dies wird einfach dadurch erreicht, dass ein Array von Objekten von Ihrem JavaScript immer wieder neu gezeichnet wird.

let drawArr = []; 

Ein Beispiel-Objekt enthält eine x- und y-Koordinaten zu zeichnen beginnen, eine Breite und eine Höhe:

{ x: 100, 
    y: 100, 
    w: 10, 
    h: 10 } 

, wenn Sie mit der Maus bewegt sich über die Leinwand Sie nur wollen, dass es das Array ändern, wenn Die Maus ist ausgeschaltet. Das heißt, Sie müssen einen Flag setzen, um zu sehen, ob dieser Fall entweder wahr oder falsch ist:

let mousedown = false; 
    canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    ... 
    }); 
    canvas.addEventListener('mouseup', function(e) { 
    mousedown = false; 
    }); 

Wenn Sie mit der Maus ist nach unten wollen Sie ein Element hinzufügen, um das Feld zu ziehen:

canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    drawArr.push({ 
    x: e.pageX, 
    y: e.pageY, 
    w: 0, 
    h: 0 
    }); 
}); 

Die Höhe und Breite sind anfangs auf 0 gesetzt. Was wir jetzt machen wollen, ist, wenn Sie sich vorstellen können, eine Höhe und Breite des Rechtecks, während wir die Maus über die Leinwand ziehen und die Maus nach unten zeigt. Wir möchten dies im laufenden Betrieb anpassen, damit der Bildschirm beim Rendern angezeigt wird, während er gezeichnet wird.

Es ist einfach, die Höhe und Breite zu ändern, da, solange Sie nur eins nach dem anderen zeichnen können, es IMMER das neueste Objekt ist, das dem Draw-Array hinzugefügt wurde.

Schließlich verwenden wir requestAnimationFrame, um ständig jedes Objekt innerhalb des Draw-Arrays zu zeichnen. Wir tun dies, indem sie fordern, wenn die Seite geladen wird:

requestAnimationFrame(draw); 

Und dann rekursiv innerhalb der Zeichenfunktion:

function draw() { 
... 
requestAnimationFrame(draw); 
} 

Dann haben wir einfach die vorherigen Bildschirm machen und durchlaufen die Auslosung Array löschen müssen und zeichne alles wieder auf den Bildschirm.

function draw() { 
    ctx.clearRect(0, 0, window.innerWidth, window.innerHeight); 
    for (let obj of drawArr) { 
    let { 
     x, 
     y, 
     w, 
     h 
    } = obj; 
     ctx.strokeRect(x, y, w, h); 
    } 
    requestAnimationFrame(draw); 
    } 

voila.

+0

Danke für die Antwort, sieht gut aus und ist genau das, was ich will, ich werde es ausprobieren, sobald möglich, eine Frage: Ist es schwierig, einen Kreis mit einem solchen Code zu zeichnen? Wäre es eine große Veränderung? Also das gleiche Prinzip, nur mit einem Kreis – nameless

+0

@nameless Es wäre sehr ähnlich. Sie müssten die arc-Kontextmethode gefolgt von stroke() anstelle von strokeRect verwenden. Sie müssten auch einen Radius innerhalb Ihres Zeichnungsobjekts speichern und daran herumfummeln, wenn Sie über die Leinwand ziehen. – zfrisch

+0

https://medium.com/wdstack/quick-blurb-2d-canvas-app-setup-5e6f13e12884 Dieser Artikel, den ich zurück geschrieben habe, kann Ihnen helfen, die grundlegenden Methoden und die Architektur von 2D-Canvas besser zu verstehen. Wenn Sie danach gesucht haben, akzeptieren Sie diese Antwort, indem Sie auf das grüne Kästchen daneben klicken. – zfrisch