HTML canvas fill difference on Firefox vs Chrome - google-chrome

Consider the snippet below - available on jsFiddle: http://jsfiddle.net/Xqu5U/2/
ctx = document.getElementById('canvas').getContext('2d');
ctx.beginPath();
ctx.fillStyle = '#FF0000';
for (var i = 0; i < 20; i++) {
ctx.arc(i * 10, 50 + Math.sin(i * 0.5) * 15, 2, 0, Math.PI * 2);
}
ctx.fill();
It works as expected on Google Chrome, but Firefox renders a fill from the last arc to the first one.
How can the snippet above be updated to get Firefox drawing the arcs exactly like Chrome?

I found a way to get it working: http://jsfiddle.net/Xqu5U/3/.
Basically just add ctx.closePath() inside the for loop. Not sure if this is the best solution though...

I know this is old question but for the future reference:
ctx = document.getElementById('canvas').getContext('2d');
ctx.beginPath()
ctx.fillStyle = '#FF0000'
for (var i = 0; i < 20; i++) {
ctx.arc(i * 10, 50 + Math.sin(i * 0.5) * 15, 2, 0, Math.PI * 2)
ctx.closePath()
}
ctx.fill()

It's really old, but someone just pointed me to here.
The problem was a chrome bug (now fixed since an undetermined long time). FF behavior was correct.
arc() method doesn't include a moveTo(x, y) call, but a lineTo one.
So in order to get your desired result, you just have to call ctx.moveTo(nextCX + radius, nextCY) where nextCX and nextCY are the center x and y coordinates of your next arc to be drawn. We add radius to the x position because, when the arc's starting angle is set to 0, the arc is being drawn from 3 o'clock, without this + radius, we would still have an internal lineTo(cx + radius, cy) being added, visible when calling stroke().
var ctx = document.getElementById('canvas').getContext('2d');
ctx.beginPath();
ctx.fillStyle = '#FF0000';
for (var i = 0; i < 20; i++) {
// you need to moveTo manually.
ctx.moveTo(i * 10 + 2, 50 + Math.sin(i * 0.5) * 15)
ctx.arc(i * 10, 50 + Math.sin(i * 0.5) * 15, 2, 0, Math.PI * 2);
}
ctx.fill();
<canvas id="canvas"></canvas>

You don't have really something to do about it...
It's the way both browser's work...
You can always design it with CSS with the right commands to make it the same...
Go to http://w3schools.com and find what you need for doing that :)
Good luck !

Related

Draw a Pentagon with HTML 5 canvas

I need to draw a Pentagon with html 5 canvas in Javascript. Not much else to write here. I have tried looking it up, but a lot of the examples don't work correctly.
The pentagon starts at the 3oclock pos use rotation to change the start position in radians. ie To start at the top rotation is -90deg = -Math.PI / 2
function pentagon(x, y, radius, rotation){
for(var i = 0; i < 5; i ++){
const ang = (i / 5) * Math.PI * 2 + rotation;
ctx.lineTo(
Math.cos(ang) * radius + x,
Math.sin(ang) * radius + y
);
}
ctx.closePath();
}
ctx.beginPath();
pentagon(100,100,50,-Math.PI / 2);
ctx.fill();
ctx.stroke();

HTML5 canvas how to split circle to X parts

I need split circle to X parts without white center
I have already this code: http://jsfiddle.net/U2tPJ/78/
I get this result:
I need finish result like this (without white center):
Since what you want is to fill a part of the circle, use fill(), not stroke().
• The shape you want to draw (a pie) starts in the circle center :
ctx.moveTo(x,y);
Then follow the arc :
context.arc(x, y, radius, i*pieAngle, (i+1)*pieAngle, false);
Then fill().
• Notice that the segmentDepth you were using was in fact an angle in degree. To clarify i used :
// size of a pie : it is an angle in radians
var pieAngle = 2 * Math.PI / hours;
• Lastly i used hsl colors to easily get a bunch of colors different for each hour :
var hueValue = i * 15;
context.fillStyle = 'hsl(' + hueValue + ',70%, 60%)';
result look this way :
draw code
function drawSegments(radius) {
for (var i = 0; i < hours; i++) {
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, i*pieAngle, (i+1)*pieAngle, false);
context.lineWidth = segmentDepth;
var hueValue = i * 15;
context.fillStyle = 'hsl(' + hueValue + ',70%, 60%)';
// '#'+(Math.random()*0xFFFFFF<<0).toString(16);
context.fill();
context.lineWidth = 2;
context.strokeStyle = '#444';
context.stroke();
}
}
fiddle : http://jsfiddle.net/gamealchemist/U2tPJ/79/
The width of the ring is controlled by the line context.lineWidth = segmentDepth;. It seems like you forgot that the line width goes into both directions. To make the ring go to the center, change it to segmentDepth * 2. However, this will also make the whole graphic twice as big, so you might want to compensate by reducing the segmentDepth.

Wrong angle while drawing a partial circle with AS3

For a flash game project I am working on I want to create a camera which should be able to detect a player through ray-casting. The camera should be able to have different view angles (eg. 45 degrees or 90 degrees), and according to these view angles the ray-casting should vary. Creating the actual view angles using ray-casting doesn't cause a problem, however, for some reason that is beyond me the angles in which these view angles are positioned are wrong.
This is the code I use:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.cos(this._viewAngle + (i * Math.PI / 180));
var pointY:Number = (this._viewRange) * Math.sin(this._viewAngle + (i * Math.PI / 180));
this._rayHolder.graphics.lineTo(pointX, pointY);
this._rayHolder.graphics.moveTo(0, 0);
}
And this is the result:
(90 degrees)
(45 degrees)
I hope what I wrote was understandable enough, because I don't know how to explain it more clearlyIf anybody could shed some light on what I am doing wrong here, that would be awesome.
EDIT:
Changing Math.cos(this._viewAngle + (i * Math.PI / 180)); to Math.cos((this._viewAngle + i) * Math.PI / 180); results in this:
(90 degrees)
(45 degrees)
I think you're close with your update. As Sunil D points out, you presumably just want to align the vision cone so that it's centred at 90˚ from the vertical. In other words, starting from -_viewAngle * 0.5:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.cos((-this._viewAngle * 0.5 + i) * Math.PI / 180);
var pointY:Number = (this._viewRange) * Math.sin((-this._viewAngle * 0.5 + i) * Math.PI / 180);
this._rayHolder.graphics.lineTo(pointX, pointY);
this._rayHolder.graphics.moveTo(0, 0);
}
Edit: While these equations work for this application, the following reflect Flash's odd coordinate systems more accurately. Specifically, with positive x to the right, positive y downwards:
for (var i:Number = 0; i < this._viewAngle; i++)
{
var pointX:Number = (this._viewRange) * Math.sin((90 - this._viewAngle * 0.5 + i) * Math.PI / 180);
var pointY:Number = (this._viewRange) * -Math.cos((90 - this._viewAngle * 0.5 + i) * Math.PI / 180);
graphics.lineTo(pointX + 100, pointY + 100);
graphics.moveTo(100, 100);
}

Object doesn't support property or method 'getContext' in below IE 9 versions

I am using canvas element to draw curve along with text. It is working fine in chrome, Firefox, IE 9. But in IE 8,7 this is not working. Showing the error like:
SCRIPT438: Object doesn't support property or method 'getContext'
I searched in Google then i found Excanvas.js will figure out this problem, but I am getting the same error.
Thank you.
<head><!--[if IE]><script src="js/excanvas.js"></script><![endif]--></head>
My html canvas code:
<canvas id="myCanvas" width="679" height="290"></canvas>
My js code:
function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
var len = str.length, s;
context.save();
context.translate(centerX, centerY);
context.rotate(-1 * angle / 2);
context.rotate(-1 * (angle / len) / 2);
for(var n = 0; n < len; n++) {
context.rotate(angle / len);
context.save();
context.translate(0, -1 * radius);
s = str[n];
context.fillText(s, 0, 0);
context.restore();
}
context.restore();
}
var canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d'),
centerX = canvas.width / 2,
centerY = canvas.height + 40,
angle = Math.PI * 0.8,
radius = 250;
context.font = 'bold 30pt Ubuntu';
context.textAlign = 'center';
context.fillStyle = 'orange';
context.strokeStyle = '#336699';
context.lineWidth = 10;
drawTextAlongArc(context, 'Sustainable Skill Solutions', centerX, centerY, radius, angle);
// draw circle underneath text
context.arc(centerX, centerY, radius +70, 0, 2 * Math.PI, false);
context.stroke();
You need to run your JS only when document is ready.
This may not be necessary for browsers supporting <canvas>, but for IE<9, excanvas.js works after document loaded, so you'll need to run your JS after that.
Change your JS to:
function drawTextAlongArc()
{
/* ... */
}
function onLoad()
{
var canvas=document.getElementById("myCanvas"),
context=canvas.getContext("2d");
/* ... */
}
if(window.addEventListener)
{
window.addEventListener("load",onLoad,false);
}
else if(window.attachEvent)
{
window.attachEvent("onload",onLoad);
}

HTML5: Fill circle/arc by percentage

Here is my pseudo code:
var percentage = 0.781743; // no specific length
var degrees = percentage * 360.0;
var radians = degrees * Math.PI / 180.0;
var x = 50;
var y = 50;
var r = 30;
var s = 1.5 * Math.PI;
var context = canvas.getContext('2d');
context.beginPath();
context.lineWidth = 5;
context.arc(x, y, r, s, radians, false);
context.closePath();
context.stroke();
I'm using the KineticJS library to control the shapes I make and redraw them as necessary. My problem is that the above code does not work at all. I assume I have the math incorrect, because if I change radians to something like 4.0 * Math.PI is draws the entire circle.
I've been using HTML5 Canvas Arc Tutorial for reference.
Your code works just fine, but you have a starting angle that ought to be zero to get what you expect. Here's working code:
http://jsfiddle.net/HETvZ/
I think your confusion is from what starting angle does. It does not mean that it starts at that point and then adds endAngle radians to it. It means that the angle starts at that point and ends at the endAngle radians point absolutely.
So if you startAngle was 1.0 and endAngle was 1.3, you'd only see an arc of 0.3 radians.
If you want it to work the way you're thinking, you're going to have add the startAngle to your endAngle:
context.arc(x, y, r, s, radians+s, false);
Like in this example: http://jsfiddle.net/HETvZ/5/
Your code is just fine. you need to have:
s=0 i.e. starting point must be zero.
and if you want circle to start drawing at top you can use:
context.rotate(-90 * Math.PI / 180);
but after rotating you will have to check arc()'s x,y arguments. i used it like:
context.rotate(-90 * Math.PI / 180);
context.arc(-200, 200, 150, startPoint, radian, false);
context.lineWidth = 20;
context.strokeStyle = '#b3e5fc';
context.stroke();
context.closePath();
after this i needed to display percentage in text form so i did:
context.rotate(90 * Math.PI / 180);
context.fillStyle = '#1aa8ff';
context.textAlign = 'center';
context.font = "bold 76px Verdana";;
context.textBaseline = "middle";
context.fillText("50%", 200, 200);