Reputation: 35
I need to be able to plot points as an SVG path on HTML canvas. I am using Fabric JS with OpenSeaDragon. The path I have generated works on Firefox but does not work on any other browser. It seems that other browsers expect a continuous path and will only render the last point. I cannot use fabric.circle as I need to render 1000's of points.
Is anyone familiar with this problem, and know a way i can generate an SVG path so that it can be rendered x-browser. The format that works on firefox is:
Move, Line, Close and repeat for as many points. e.g:
M 25333 15819 L 25333 15819 Z
M 25116 15764 L 25116 15764 Z
M 24396 15437 L 24396 15437 Z
M 23976 16585 L 23976 16585 Z
M 23976 16579 L 23976 16579 Z
M 23977 16576 L 23977 16576 Z
Many thanks!
Upvotes: 1
Views: 1398
Reputation: 105015
Your SVG data commands are oddly formed
Your M
& L
values are the same for each subpath so you're not really drawing lines, you're drawing points. From your question I assume this is what you want ... to draw a series of points with each point defined by one M L
command.
Getting points from SVG commands
Parse your Svg M+L commands into Canvas moveTo+lineTo commands and put those canvas commands into a single beginPath.
Your example data
has a simple an uniform structure so you could parse it with .split
. If your actual data
is more complex you can use regEx
to parse it.
var data='M 25333 15819 L 25333 15819 Z M 25116 15764 L 25116 15764 Z M 24396 15437 L 24396 15437 Z M 23976 16585 L 23976 16585 Z M 23976 16579 L 23976 16579 Z M 23977 16576 L 23977 16576 Z';
var canvasPts=[];
var dataCmds=data.split('M');
for(var i=1;i<dataCmds.length;i++){
var cmd=dataCmds[i].split(' ');
canvasPts.push({x:parseInt(cmd[1]),y:parseInt(cmd[2])});
}
Once you parse out your points-set you can draw them with Fabric.Circle
s or with Fabric.Polyline
if you want the points connected.
Here's example code and a Demo (using native canvas):
Your coordinates are very large so this demo divides each coordinate by 100
Note: the points are drawn in the lower right of the canvas so you will have to scroll the Stack Snippet window down or view it in full-page mode.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var data='M 25333 15819 L 25333 15819 Z M 25116 15764 L 25116 15764 Z M 24396 15437 L 24396 15437 Z M 23976 16585 L 23976 16585 Z M 23976 16579 L 23976 16579 Z M 23977 16576 L 23977 16576 Z';
var canvasPts=[];
var dataCmds=data.split('M');
for(var i=1;i<dataCmds.length;i++){
var cmd=dataCmds[i].split(' ');
canvasPts.push({x:parseInt(cmd[1]),y:parseInt(cmd[2])});
}
var ptRadius=2;
ctx.beginPath();
for(var i=0;i<canvasPts.length;i++){
var x=canvasPts[i].x/100;
var y=canvasPts[i].y/100;
ctx.moveTo(x+ptRadius,y);
ctx.arc(x,y,ptRadius,0,Math.PI*2);
}
ctx.fill();
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>
Upvotes: 1