2014-01-12 14 views
5

Ich arbeite an etwas Code, der auf eine Leinwand zeichnet. Ein Teil des Codes zeichnet einige Linien auf die Leinwand. Die Position und die Farbe dieser Linien ändern sich nicht, aber sie müssen oft neu gezeichnet werden, weil anderer Code sie beeinflusst haben könnte (zB: darüber gezogen).Speichern Sie einen Verweis auf einen HTML-Canvas-Pfad

Es kann mehrere hundert Zeilen zum Zeichnen geben, und in diesen Fällen zeigt mir das Profiling, dass es ~ 200ms zum Zeichnen braucht, also möchte ich das etwas optimieren.

Eine Sache, die ich bemerkte, war, dass beim Zeichnen auf die Leinwand, Sie grundsätzlich Punkte zu einem Pfad hinzufügen und dann, wenn Sie fertig sind, können Sie diesen Pfad füllen oder streichen. Obwohl die Pixel auf der Zeichenfläche veraltet sind, wenn ich in der Lage wäre, einen Verweis auf den Pfad beizubehalten, wäre die Aktualisierung so einfach wie das Überstreichen des zuvor erstellten Pfads.

Meine Frage ist: Wie auf der Erde erhalten Sie ein Path-Objekt?

Die Füll- und Strich Methoden scheinen accept a path object, und die Spezifikation definiert die methods for Path, aber ich kann nicht die tatsächliche Path Klasse scheint überall ...

Also, nur zu rekapitulieren zu finden:

ich habe so etwas wie dies:

function update() { 
    context.beginPath(); 
    // lots of lines added to the default path... 
    context.moveTo(x1, y1); context.lineTo(somewhere, else); 
    context.moveTo(x2, y2); context.lineTo(somewhere, else); 

    context.stroke(); 
} 

Was ich mag würde, ist so etwas wie dieses:

function update() { 
    if (!this.path) { 
    this.path = new Path(); // <-- here's the magic 
    this.path.moveTo(x1, y2); this.path.lineTo(somewhere, else); // etc 
    } 
    this.path.stroke(); 
} 

Antwort

2

Die Canvas-Spezifikation ruft ein Path-Objekt auf, das noch nicht in Browsern implementiert ist.

BTW, wenn implementiert, wird das Path-Objekt in Hit-Tests nützlich sein, wenn es mit context.isPointInPath (myPath) kombiniert wird; Ein Tag ...

Hier ist, wie Sie Ihr eigenes Path-Objekt erstellen können, bis der Browser aufholen:

  • erstellen JS-Objekt, das eine Leinwand enthält, in dem Sie Ihren Weg Strich gezeichnet werden.
  • Wenn Sie myPath.stroke() ausführen möchten, verwenden Sie myVisibleContext.drawImage (myPath.context, 0,0), um die Zeichenfläche des Pfads auf Ihrer Zeichenfläche zu "blit".

Demo: http://jsfiddle.net/m1erickson/QLJv8/

Code:

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; } 
    #canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 

    function Path(maxWidth,maxHeight,color,linewidth,drawingContext){ 
     this.width=maxWidth; 
     this.height=maxHeight; 
     this.drawingCtx=drawingContext; 
     this.points=[] 
     this.canvas=document.createElement("canvas"); 
     this.canvas.width=maxWidth; 
     this.canvas.height=maxHeight; 
     this.ctx=this.canvas.getContext("2d"); 
     this.ctx.strokeStyle=color; 
     this.ctx.lineWidth=linewidth; 
     this.lastX; 
     this.lastY; 
    } 
    Path.prototype.moveTo=function(x,y){ 
     this.lastX=x; 
     this.lastY=y; 

    } 
    Path.prototype.lineTo=function(x,y){ 
     this.ctx.moveTo(this.lastX,this.lastY); 
     this.ctx.lineTo(x,y); 
     this.ctx.stroke(); 
     this.lastX=x; 
     this.lastY=y; 
    } 
    Path.prototype.stroke=function(){ 
     this.drawingCtx.drawImage(this.canvas,0,0); 
    } 

    // create a new path object 

    var p=new Path(300,300,"blue",2,ctx); 

    // set the Path's drawing commands 

    p.moveTo(69,91); 
    p.lineTo(250,150); 
    p.moveTo(69,208); 
    p.lineTo(180,54); 
    p.lineTo(180,245); 
    p.lineTo(69,91); 
    p.moveTo(69,208); 
    p.lineTo(250,150); 

    // draw the Path.canvas to the drawing canvas 
    p.stroke(); 

    // tests... 

    $("#stroke").click(function(){ 
     p.stroke(); 
    }); 
    $("#erase").click(function(){ 
     ctx.clearRect(0,0,canvas.width,canvas.height); 
    }); 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <button id="stroke">Path.stroke</button><br> 
    <button id="erase">Erase main canvas</button><br> 
    <canvas id="canvas" width=300 height=300></canvas> 
</body> 
</html> 
+0

Das Pfadobjekt ist jetzt in Chrome Canary verfügbar. Bald im normalen Chrome. – K3N

+1

@Ken Ich habe ein großes Lächeln auf meinem Gesicht bei dem Gedanken, dass Pfadobjekte über den Browser verfügbar sind !!!! – markE

0

Sie ist kein Weg Unterstützung in Leinwand, aber warum sein nicht svg Linie verwenden und zIndex soll über anderen stehen.

0

Mit keiner der Canvas-Zeichnungs-API können Sie Verweise auf Objekte speichern. Mit Canvas können Sie Pixel in einer Bitmap zeichnen, Objekte nicht wie SVG erstellen und bearbeiten.

Wenn Sie die Leistung optimieren möchten und den gleichen Pfad immer wieder verwenden möchten, sollten Sie es einmal in einem separaten Zeichenflächenobjekt zeichnen und dann diese Zeichenfläche mithilfe von drawImage in Ihre andere Zeichenfläche zeichnen. das kann eine Leinwand als Argument nehmen).

+0

Nun, die Spezifikation für Canvas-Zeichnung gibt Ihnen Referenzen auf Vektor-Objekte (http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas/#path-objects) aber keiner der Browser hat dies offen gelegt , anscheinend. – nickf

Verwandte Themen