I started today learning HTML5/Javascript/Canvas so please be easy on me.
I wanted to plot a sin(x)
over the range x=-Pi..Pi
. Therefore, the logical coordinates will extend from x=-Pi..Pi
and from y=-1..1
. I do not want to use a plotting library or any external functions. I want to learn how to do this all in javascript and HTML5 myself.
The canvas size is width=200
and height=100
in pixels.
After lots of reading and googling, I learned I need to use translate
and scale
to be able to work in the logical coordinates, not the physical (pixels) based coordinates.
Finally I get the correct plot, but the line is too thick. It looks like line thickness is not affect by scaling? How can I make the line thickness much less than shown below?
The plot I want to generate in javascript is this (from Matematica)
The one I get now in HTML is this
Could someone look at the code and suggest what is needed to fix the line thickness issue? Am I doing the scaling correctly?
The shape seems correct, it is that the line is too thick. Here is the complete code I just wrote
function draw() {
var canvas = document.getElementById('canvas');
var W = canvas.width;
var H = canvas.height;
var ctx = canvas.getContext('2d');
ctx.lineWidth = 1; // attempt to make line less thick, but no effect
ctx.rect(0, 0, W, H); // draw frame around the physical canvas
ctx.stroke();
ctx.save();
ctx.translate(W / 2, H / 2); //put coordinates system origin in middle
ctx.scale(W / (2 * Math.PI), -H / 2); //Is this correct?
// want logical width to be 2 PI and logical height 2.
// the minus sign due to flipping of y axis.
var lowEnd = -Math.PI; // x range is -Pi..Pi
var highEnd = Math.PI;
var xValues = [];
var yValues = [];
while (lowEnd <= highEnd) //generate x,y points
{
xValues.push(lowEnd);
yValues.push(Math.sin(lowEnd));
lowEnd += (Math.PI) / 10; // arbitray sampling interval
}
// start drawing the points generated above
ctx.beginPath();
ctx.moveTo(xValues[0], yValues[0]); //move to starting point of curve.
for (var i = 1; i < xValues.length; i++) {
//console.log(xValues[i],yValues[i]);
ctx.lineTo(xValues[i], yValues[i]);
ctx.stroke();
}
ctx.restore();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="200" height="100"></canvas>
</body>
</html>