Issue with fill() method - javascript

Here is my JavaScript code:
function Show(output, startX, startY){
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.arc(startX, startY, 3, 0, Math.PI*2, true);
context.fill();
context.arc(startX + 50, startY, 3, 0, Math.PI*2, true);
context.stroke();
}
Show(outputcpu, 50, 50);
Show(outputio, 70, 50);
I have expect some thing like: o-o o-o.
But not sure why I get: o-o-o-o.
How to remove the center stroke? (I want to remove the second line o-o*-*o-o)

beginPath will seperate your calls: http://jsfiddle.net/CmuT7/1
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
function Show(output, startX, startY) {
context.beginPath();
context.arc(startX, startY, 3, 0, Math.PI * 2, true);
context.fill();
context.arc(startX + 50, startY, 3, 0, Math.PI * 2, true);
context.stroke();
}
Show('', 50, 50);
Show('', 70, 70);

You need to use moveTo() or beginPath() function to avoind line between those arcs.
function Show(output, startX, startY){
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.arc(startX, startY, 3, 0, Math.PI*2, true);
context.fill();
context.moveTo(startX +50, startY);
context.arc(startX + 50, startY, 3, 0, Math.PI*2, true);
context.stroke();
}
Show(outputcpu, 50, 50);
Show(outputio, 70, 50);

Related

How to convert an Arc into a Line with HTML5 Canvas?

I would like to animate a circle into a line with the radius equaling the width, and I am wondering how I can do this with an Arc? Or perhaps there is a better way?
From
To
Here's my arc:
function drawStar(x,y,size,scale,opacity,ctx){
ctx.save();
ctx.beginPath();
ctx.arc(x,y,size+scale,0,size+scale * Math.PI,false);
ctx.globalAlpha = opacity
ctx.closePath();
setFillStyle('rgb(255,237,219)',ctx);
ctx.fill()
ctx.restore();
}
I tried using ctx.scale(n,1), however it does not keep the same radius(width) and it scales the collection of arcs as a whole (zoom in effect).
Use instead a wide line-width value with "round" lineCap and stroke():
var ctx = c.getContext("2d");
ctx.lineWidth = 50;
ctx.lineCap = "round";
ctx.moveTo(45 , 25);
ctx.lineTo(45.5, 25); // in IE11 this must be slightly offset
ctx.moveTo( 45, 100);
ctx.lineTo(150, 100);
ctx.stroke();
<canvas id=c></canvas>
Remember beginPath() for animation.
You can use Bezier Curves to 'transform' your arc.
There's some math involved in calculating the perfect ends of your stretched circle but I guessed and tweaked my numbers.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(40, 20);
ctx.lineTo(100, 20);
ctx.bezierCurveTo(130, 20, 130, 60, 100, 60);
ctx.lineTo(40, 60);
ctx.bezierCurveTo(10, 60, 10, 20, 40, 20);
ctx.stroke();
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(40, 80);
ctx.bezierCurveTo(68, 80, 68, 120, 40, 120);
ctx.bezierCurveTo(12, 120, 12, 80, 40, 80);
ctx.fill();
ctx.stroke();
<canvas id="myCanvas"></canvas>
You could draw the left and right halves of a circle using arc, then do a fillRect in between to connect them.
Edit: To elaborate on what I said earlier:
function init() {
let canvas = document.getElementById('myCanvas');
canvas.width = 400;
canvas.height = 400;
canvas.style.width = "400px";
canvas.style.height = "400px";
let ctx = canvas.getContext("2d");
function fillArc(ctx, cx, cy, r, startDeg, endDeg) {
ctx.beginPath();
ctx.arc(cx, cy, r, startDeg * Math.PI / 180, endDeg * Math.PI / 180);
ctx.fill();
}
function fillOval(ctx, cx, cy, r, sideLength, skipFirstArc) {
if (!skipFirstArc) {
fillArc(ctx, cx, cy, r, 90, 270);
}
ctx.fillRect(cx, cy - r, sideLength, r * 2);
fillArc(ctx, cx + sideLength, cy, r, 270, 90);
}
let sideLength = 0;
ctx.fillStyle = 'red';
function animateOval() {
if (sideLength === 100) {
ctx.clearRect(0, 0, 400, 400);
}
else {
fillOval(ctx, 30, 30, 25, sideLength, sideLength > 0);
}
++sideLength;
if (sideLength > 100) {
sideLength = 0;
}
}
setInterval(animateOval, 16);
}
Here's a Plunker with the above code running: http://plnkr.co/edit/vNqoUjPKg2lqC7JtYuEb?p=preview

JavaScript Canvas/fillStyle Troubleshooting

I am currently developing a program called "Drive a Car" with my friend, where one car is controlled via WASD and the other is controlled with arrow keys. The problem is that the chassis color on the bottom car "function drawCar2()" seems to have a connection with the tires on the top car "function drawCar()", yet I cannot seem to find this connection. I even made two separate animation loops and tried to draw the tires in a different function. How can I fix this?
JSBin link: http://jsbin.com/yelojob/28/edit?html,css,js,output
drawCar functions:
function drawCar(x,y,angle,car1Color,wheel1Color) {
ctx.save();
ctx.translate(x,y);
ctx.rotate(angle);
//Chassis
ctx.fillStyle = car1Color;
ctx.fillRect(50, 50, 110, 25);
ctx.fill();
//Wheels
ctx.beginPath();
ctx.fillStyle = wheel1Color;
ctx.arc(75, 75, 15, 0, Math.PI, false);
ctx.arc(135, 75, 15, 0, Math.PI, false);
ctx.fill();
//Windows
ctx.fillStyle = 'lightblue';
ctx.fillRect(120,25,5,25);
ctx.fillStyle = 'darkorange'
ctx.fillRect(153,55,7,10);
ctx.fillStyle = 'darkred';
ctx.fillRect(50,58,7,10);
ctx.fillStyle = 'white';
ctx.fillRect(50,56,7,2);
ctx.restore();
}
function drawCar2(x,y,angle,car2Color,wheel2Color) {
ctx.save();
ctx.translate(x,y);
ctx.rotate(angle);
//Chassis
ctx.fillStyle = car2Color;
ctx.fillRect(50, 150, 110, 25);
ctx.fill();
//Wheels
ctx.beginPath();
ctx.fillStyle = wheel2Color;
ctx.arc(75, 175, 15, 0, Math.PI, false);
ctx.arc(135, 175, 15, 0, Math.PI, false);
ctx.fill();
//Windows
ctx.fillStyle = 'lightblue';
ctx.fillRect(120,125,5,25);
ctx.fillStyle = 'darkorange'
ctx.fillRect(153,155,7,10);
ctx.fillStyle = 'darkred';
ctx.fillRect(50,158,7,10);
ctx.fillStyle = 'white';
ctx.fillRect(50,156,7,2);
ctx.restore();
}

How to color different objects with fillStyle

I'm not sure if that's the correct question. I'm not managing to set different colors to different objects.
As seen below they all become red,
function Body(x, y, w, h, color, mode){
...
this.color = color;
this.draw = function(){
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.fillStyle = this.color;
};
var hero = new Body(10, 50, 30, 40, "red", 1);
var page = new Body(500, 150, 5, 5, null, 0);
var poop = new Body(40, 50, 4, 4, null, 1);
var floor = new Body(30, 300, 600, 30, null, 0);
Even if I add ctx.fillStyle = null; after ctx.fillStyle = this.color;
And if I set the other objects to have to some specific color like this:
var hero = new Body(10, 50, 30, 40, "red", 1);
var page = new Body(500, 150, 5, 5, "blue", 0);
the code bugs and colors appear to be randomly given.
fillStyle sets the fill color for the shapes you draw after it. You can't modify what you've already drawn. Therefore change the order of the statements:
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
This is a working example:
(function () {
"use strict";
var cvs, ctx;
cvs = document.getElementById("cvs");
ctx = cvs.getContext("2d");
ctx.fillStyle = "#ff0000";
ctx.fillRect(10, 10, 10, 10);
ctx.fillStyle = "#00ff00";
ctx.fillRect(20, 20, 10, 10);
ctx.fillStyle = "#0000ff";
ctx.fillRect(30, 30, 10, 10);
}());
<canvas id="cvs"></canvas>

Difficulty with javascript library: this.ctx is undefined

So I have been working on a neural network, and I was cleaning up the code earlier today so that I can include it in 2 libraries (as objects) so that I do not have to worry about graphics, and can worry about the actual logic. I have checked JSHint.com (A version of JSLint, basically), and there seems to be nothing wrong with my code. However, when I try to run my code, I get the error this.ctx is undefined. I tried to remove the this keyword, but got ctx is undefined. Here is a copy of my code. I was running it in a basic template with a canvas already created, so there was no need for the first method in the init function. So my questions are:
• Why is this.ctx undefined?
• Why does this work when I do init, drawNodes, and drawNodeConnectors from the console?
• Are there any ways that I can avoid using the this keyword ever time I reference ctx besides a global variable?
var graphics = {
init: function(overlay){
if(!overlay){
this.newCanvas = document.createElement('canvas');
this.newCanvas.id = "canvas";
this.width = 640;
this.height = 360;
document.body.appendChild(this.canvas);
}
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.pi = Math.PI;
},
blackout: function(){
this.ctx.fillStyle = "black";
this.ctx.globalAlpha = 1;
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
},
drawCircle: function(x, y, radius){
this.ctx.beginPath();
this.ctx.fillStyle = "white";
this.ctx.strokeStyle = "white";
this.ctx.globalAlpha = 1;
this.ctx.arc(x, y, radius, 0, this.pi*2);
this.ctx.stroke();
this.ctx.fill();
},
drawLine: function(x1, y1, x2, y2, alpha){
this.ctx.beginPath();
this.ctx.strokeStyle = "white";
this.ctx.lineWidth = 5;
this.ctx.globalAlpha = alpha;
this.ctx.moveTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
this.ctx.closePath();
},
drawText: function(x, y, text, size){
this.ctx.font = size+"px Times";
this.ctx.fillText(text, x, y);
},
textOffset: function(text, size){
this.ctx.font = size+"px Times";
return this.ctx.measureText( text.toString() ).width / 2;
},
drawNodes: function(){
this.drawCircle(100, 100, 50);
this.drawCircle(100, 260, 50);
this.drawCircle(300, 75, 25);
this.drawCircle(300, 180, 25);
this.drawCircle(300, 285, 25);
this.drawCircle(500, 180, 75);
},
genWeights: function(){
for(this.i = 1; this.i < 9; this.i ++){
eval("this.w" + this.i + " = Math.random();");
}
},
drawNodeConnectors: function(){
this.ctx.fillStyle = "white";
this.drawLine(100, 100, 300, 75, this.w1);
this.drawLine(100, 100, 300, 180, this.w2);
this.drawLine(100, 100, 300, 285, this.w3);
this.drawLine(100, 260, 300, 75, this.w4);
this.drawLine(100, 260, 300, 180, this.w5);
this.drawLine(100, 260, 300, 285, this.w6);
this.drawLine(300, 75, 500, 180, this.w7);
this.drawLine(300, 180, 500, 180, this.w8);
this.drawLine(300, 285, 500, 180, this.w9);
},
nodeText: function(in1, in2, node1, node2, node3, output1, output2){
this.ctx.fillStyle = "black";
this.ctx.globalAlpha = 1;
this.text(100 - this.textOffset(in1, 36), 100, in1.toString(), 36);
this.text(100 - this.textOffset(in2, 36), 260, in2.toString(), 36);
this.text(300 - this.textOffset(node1, 20), 75, node1.toString(), 20);
this.text(300 - this.textOffset(node2, 20), 180, node2.toString(), 20);
this.text(300 - this.textOffset(node3, 20), 285, node3.toString(), 20);
this.text(500 - this.textOffset(output1, 100), 180, output1.toString(), 100);
this.text(500 - this.textOffset(output2, 25), 225, output2.toString(), 25);
},
test: function(){
this.blackout();
this.init(true);
this.drawNodes();
this.genWeights();
this.drawNodeConnectors();
}
};
graphics.test();
You call blackout first and than you call init second. init is where it defines ctx.

Why is my code not working when t is similar to MDN? (OOP)

This is MDN's ball velocity code:
var ball = {
x: 100,
y: 100,
vx: 5,
vy: 2,
radius: 25,
color: 'blue',
draw: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
}
};
function draw() {
ctx.clearRect(0,0, canvas.width, canvas.height);
ball.draw();
ball.x += ball.vx;
ball.y += ball.vy;
raf = window.requestAnimationFrame(draw);
};
canvas.addEventListener('mouseover', function(e){
raf = window.requestAnimationFrame(draw);
});
ball.draw();
My code is here:
var Ball = function(x, y, vx, vy, r, color) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.radius = r;
this.color = color;
this.draw = function() {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
}
};
function movement() {
pingPong.draw();
pingPong.x += pingPong.vx;
pingPong.y += pingPong.vy;
raf = window.requestAnimationFrame(movement);
};
canvas.addEventListener('mouseover', function(e){
raf = window.requestAnimationFrame(movement);
});
var pingPong = new Ball(100, 100, 5, 1, 15, 'black');
pingPong.draw();
I can't understand why my ball isn't being redrawn. To me they look exactly the same and I have console.log'd my x and y coordinates and they are updating as they should be. Can anyone tell me why mine isn't working?
MDN's
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
ctx.closePath();
ctx.fillStyle = this.color;
Yours
ctx.arc(x, y, r, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = color;
In your code, you didn't prepend with this. which might make your object doesn't have color and placed out of screen.

Categories

Resources