How to color different objects with fillStyle - javascript

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>

Related

How to redraw a rectangle in canvas?

In a canvas, I have drawn two rectangles. In button click event, I want to redraw one rectangle out of these two rectangles I have drawn. How can I achieve this?
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.rect(10, 20, 150, 100);
ctx.fill();
ctx.rect(200, 20, 100, 100);
ctx.stroke();
change = () => {
//need to change height of second rectangle
alert('size changed')
}
jsFiddle link
In the above fiddle link, I want to change the height of the second rectangle . Can anyone suggest ideas to achieve thii?
Thanks in advance,
You need to redraw the canvas - i.e. redraw the background and the two rectangles, something like this:
ctx.fillRect(0, 0, canvas.width, canvas.height);
//change the size of one rectangle, then redraw both of them
ctx.rect(10, 20, 150, 100);
ctx.fill();
ctx.rect(200, 20, 200, 150);
ctx.stroke();
Another way would be to cover only the second rectangle with a white rectangle (or whatever background color you have), and redraw this second rectangle:
//draw first rectangle
ctx.rect(10, 20, 150, 100);
//cover old rectangle using a white rect
ctx.fillStyle = "white";
ctx.fill();
ctx.rect(200, 20, 100, 100);
//redraw second rectangle
ctx.fillStyle = "black";
ctx.fill();
ctx.rect(200, 20, 200, 150);
ctx.stroke();
You need to save the rectangle information and redraw them on each change.
This is because canvas doesn't store information as objects, but merely commits pixels.
//Setup canvas
var canvas = document.body.appendChild(document.createElement("canvas"));
var ctx = canvas.getContext('2d');
canvas.height = 200;
canvas.width = 400;
ctx.fillStyle = "red";
//Setup rectangles as objects
var rect1 = { x: 10, y: 20, w: 150, h: 100 };
var rect2 = { x: 200, y: 20, w: 100, h: 100 };
//Setup controls
var table = document.body.appendChild(document.createElement("table"));
var tr = table.appendChild(document.createElement("tr"));
tr.appendChild(document.createElement("td")).innerHTML = "X-position:";
var xInput = tr.appendChild(document.createElement("input"));
xInput.type = "number";
xInput.value = rect2.x.toString();
tr = table.appendChild(document.createElement("tr"));
tr.appendChild(document.createElement("td")).innerHTML = "Y-position:";
var yInput = tr.appendChild(document.createElement("input"));
yInput.type = "number";
yInput.value = rect2.y.toString();
tr = table.appendChild(document.createElement("tr"));
tr.appendChild(document.createElement("td")).innerHTML = "Width:";
var wInput = tr.appendChild(document.createElement("input"));
wInput.type = "number";
wInput.value = rect2.w.toString();
tr = table.appendChild(document.createElement("tr"));
tr.appendChild(document.createElement("td")).innerHTML = "Height:";
var hInput = tr.appendChild(document.createElement("input"));
hInput.type = "number";
hInput.value = rect2.h.toString();
//Draw function
function change() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
[rect1, rect2].forEach(function (rect) {
ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
});
}
//initial draw
change();
//Redraw event
function redraw() {
rect2.x = parseInt(xInput.value, 10);
rect2.y = parseInt(yInput.value, 10);
rect2.w = parseInt(wInput.value, 10);
rect2.h = parseInt(hInput.value, 10);
change();
}
//Bind events
[xInput, yInput, wInput, hInput].forEach(function (input) {
input.addEventListener("change", redraw);
input.addEventListener("keyup", redraw);
});

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();
}

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.

How to make a jQuery function for html5 canvas

Consider a simple canvas as
$(document).ready(function(){
draw();
});
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
}
How can I introduce variable into the jQuery function to draw several canvases with defined variable (e.g. color set).
In fact, I want to replace canvas id and its options (like color) with variable provided by draw(variables), e.g.draw(canvas_id, color, ...).
Example: (for creating several canvases on different DOM elements)
function draw(ccc) {
var canvas = document.getElementById(ccc);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
}
draw(canvas1);
draw(canvas2);
try this:
function draw(id, clr, fill) {
var canvas = document.getElementById(id);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = clr;
ctx.fillRect (fill);
}
}
Here is one way you could do it:
function draw(colors) {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
for(var i=0; i < colors.length; i ++){
ctx.fillStyle = colors[i];
ctx.fillRect (10*i, 10*i, 55, 50);
}
}
}
// define some colors in an array
var colors = ["rgb(200,0,0)","rgba(0, 0, 200, 0.5)","rgba(0, 128, 200, 0.5)"];
draw(colors);
EDIT
Here is jsfiddle example

Issue with fill() method

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);

Categories

Resources