I'm working on some code which is drawing to a canvas. One part of the code draws some lines onto the canvas. The position and colour of those lines don't change, but they often need to be redrawn because other code may have affected it (eg: drawn over the top of it).
There can be several hundred lines to draw, and in these cases, profiling shows me that it's taking ~200ms to draw, so I'm looking to optimise this somewhat.
One thing I noticed was that when drawing to the canvas, you basically are adding points to a path and then once ready, you can fill or stroke that path. Though the pixels on the canvas are out of date, if I were able to keep a reference to the path, then updating would be as simple as re-stroking the previously constructed path.
My question is: how on earth do you get a Path object?
The fill and stroke methods appear to accept a path object, and the spec defines the methods for Path, but I can't seem to find the actual Path
class anywhere...
So, just to recap:
I have something like this:
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();
}
What I'd like is something like this:
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();
}
The canvas spec calls for a Path object that is not implemented in browsers yet.
BTW, when implemented, the Path object will be useful in hit-testing when combined with context.isPointInPath(myPath); Someday...
Here's how you could create your own Path object until the browsers catch up:
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>
Turns out, it's just that no browser supports it yet, according to this blog (dated 24th January 2013) http://www.rgraph.net/blog/2013/january/html5-canvas-path-objects.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With