Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Random colour generator help...please.

Hi,

So I've built a little monster face with rectangles that are all of different colours. I'd like to display all the colours details (rgb) in the page, in case there are some that I'd like to keep. So far so good, I can do that. But what I'd really like to do is to have all the colours matching the different parts of the face displayed separately (like face : rgb(23,45,145) then nose : rgb etc...). Any suggestions?

Here's my code :

var canvas;
var ctx;
var rgbColor;
var message;
var faceColors = [];

function randomRGB() {
  return Math.floor(Math.random() * 256 );
}

function print (message) {
  var outputDiv = document.getElementById('list');
  outputDiv.innerHTML = message;
}

function init() {
  canvas = document.getElementById('myCanvas');
  ctx = canvas.getContext('2d');
  drawSomething(80, 100);
}

/*
// Example 1 with 3 rectangles
function drawSomething(x, y) {
  //Global context values
  ctx.lineWidth = 8;
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  //Draw the 2 frames
  ctx.strokeRect (x, y, 60, 200);
  ctx.strokeRect (x+100, y, 60, 200);
  ctx.strokeRect (x+200, y, 60, 200);
  //Fill the 2 figures
  ctx.fillRect (x, y, 60, 200);
  ctx.fillRect (x+100, y, 60, 200);
  ctx.fillRect (x+200, y, 60, 200);
  //Insert a message
  ctx.font = "bold 40pt Papercutting"
  ctx.fillText ("I want cake!", 30, 40);
}
*/

function drawSomething(x,y) {
  //Drawing a monster
  //Global context values
  ctx.lineWidth = 3;

  //Head
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  ctx.fillRect (x, y, 300, 300);
  ctx.strokeRect (x, y, 300, 300);

  //Eyes
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  ctx.fillRect (x+80, y+60, 40, 40);
  ctx.fillRect (x+180, y+60, 40, 40);
  ctx.strokeRect (x+80, y+60, 40, 40);
  ctx.strokeRect (x+180, y+60, 40, 40);

  //Eyeballs
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  ctx.fillRect (x+95, y+75, 10, 10);
  ctx.fillRect (x+195, y+75, 10, 10);
  ctx.strokeRect (x+95, y+75, 10, 10);
  ctx.strokeRect (x+195, y+75, 10, 10);

  //Nose
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  ctx.fillRect (x+140, y+120, 25, 70);
  ctx.strokeRect (x+140, y+120, 25, 70);

  //Mouth
  ctx.fillStyle = randomColor();
  ctx.strokeStyle = randomColor();
  ctx.fillRect (x+100, y+220, 100, 20);
  ctx.strokeRect (x+100, y+220, 100, 20);
}

function randomColor() {
  var color = 'rgb(';
  color += randomRGB() + ',';
  color += randomRGB() + ',';
  color += randomRGB() + ')';
  faceColors += color + ', ';

  print(faceColors);
  return color;
}
Steven Parker
Steven Parker
243,318 Points

Can you also provide the HTML and CSS to go with this? I'll take a look.

Hey Steven,

The javascript is only referencing 2 elements as far as I can tell.

I was able to see what was going on with

<canvas id="myCanvas" width="500"  height="500"></canvas>
<div id="list"></div>

Hi Chris,

I'm seeing existing output like this

rgb(183,215,35), rgb(153,67,235), rgb(231,208,26), ...

Do you want it like this?

nose: rgb(183,215,35), eye: rgb(153,67,235), eyeball: rgb(231,208,26), ...

Also, you have colors for both fill and stroke so do you want it broken down further like "noseStroke: rgb(), noseFill: rgb(), ..."

4 Answers

Steven Parker
Steven Parker
243,318 Points

:point_right: You can still do the same thing.

Only now, you'll pass the part name in each call to colorParts, like this:

function drawHead() {
  colorParts(12, "Head");

And then in colorParts, you'll extend the name and pass it on to randomColor as before:

function colorParts(size, part) {
  ctx.strokeStyle = randomColor(part + " stroke");
  ctx.fillStyle = randomColor(part + " fill");
  ctx.lineWidth = size;
}

It looked like you started to add a second argument yourself.

If this project is going to change even more, it might be good to pick a "best answer" here to close this question and start a new one.

Hi guys,

Thanks a lot for helping out! Steven Parker, the html is very basic and looks pretty much like Jason Anello described it. Jason, yes that's exactly how I'd like to have it broken down(with frames and fills separate).

Steven Parker
Steven Parker
243,318 Points

:point_right: It looks like you're nearly there already.

How about if you modify randomColor to use an argument, like this:

function randomColor(part) {
  var color = 'rgb(';
  color += randomRGB() + ',';
  color += randomRGB() + ',';
  color += randomRGB() + ')';
  faceColors += part + ": " + color + '<br>';

  print(faceColors);
}

Then, each time you call it, just pass the description of the part being colored:

  //Head
  ctx.fillStyle = randomColor("head fill");
  ctx.strokeStyle = randomColor("head stroke");
// ... etc. ...

That would work great, but I've passed the randomColor() function into another function (drawPart()) which deals with lineWidth, stroke and fill...My bad, I've slightly updated the code since. Apologies.

//Drawing a human shaped robot with 2D transformations

//Defining variables
var canvas;
var ctx;
var rgbColor;
var message;
var faceColors = [];

//Defining functions

//To get random colors
function randomRGB() {
  return Math.floor(Math.random() * 256 );
}

function randomColor() {
  var color = 'rgb(';
  color += randomRGB() + ',';
  color += randomRGB() + ',';
  color += randomRGB() + ')';
  //faceColors += part + " : " + color + ",";
  //print(faceColors);
  return color;
}

//To write into the html page
function print (message) {
  var outputDiv = document.getElementById('list');
  outputDiv.innerHTML = message;
}

//Drawing all the robot parts at once
function init() {
  canvas = document.getElementById('myRobot');
  ctx = canvas.getContext('2d');
  ctx.lineJoin = 'round';
  ctx.lineCap = 'round';
  ctx.font = 'bold 30pt Papercutting';
  ctx.fillText("Hit refresh to change my colors!", 300, 50);
  drawHead();
  drawEyes(308, 115);
  drawNose(35, 20);
  drawMouth(-17, 45);
  drawNeck();
  drawBody();
  drawLeftShoulder(246, 244, 0.5);
  drawLeftArm();
  drawLeftHand();
  drawRightShoulder(400, 272, 5.8);
  drawRightArm();
  drawRightHand();
  drawBouquet(400, 280, 5.8);
  drawLeftLeg(300, 485);
  drawRightLeg(360, 485);
}
//Defining a function to color frames and body parts
function colorParts(size,) {
  ctx.strokeStyle = randomColor();
  ctx.fillStyle = randomColor();
  ctx.lineWidth = size;
}

//Defining a function to draw frames and fill them
function draw(x, y, width, height) {
  ctx.strokeRect(x, y, width, height);
  ctx.fillRect(x, y, width, height);
}

//Defining functions for each body part
function drawHead() {
  colorParts(12,);
  ctx.arc(350, 150, 70, 0, Math.PI*2, true);
  ctx.stroke();
  ctx.fill();
}

function drawEyes(x, y) {
  ctx.save();
  //One eye
  colorParts(3);
  ctx.translate(x,y);
  draw(0, 0, 15, 15);
  //Second eye
  colorParts(3);
  draw(65, 0, 15, 15);

  //Eye balls
  colorParts(1);
  draw(10, 9, 5, 5);
  colorParts(1);
  draw(75, 9, 5, 5);
}
function drawNose(x, y) {
  colorParts(6);
  ctx.translate(x,y);
  draw(0, 0, 10, 30);
}

function drawMouth(x, y) {
  colorParts(8);
  ctx.translate(x, y);
  draw(0, 0, 45, 8);
}

function drawNeck() {
  colorParts(10);
  draw(12, 50, 20, 30);
  ctx.restore();
}

function drawBody() {
  colorParts(16);
  draw(300, 272, 100, 200);
}

function drawLeftShoulder(x, y, angle) {
  ctx.save();
  ctx.translate(x,y);
  ctx.rotate(angle);
  colorParts(8);
  draw(0, 0, 50, 30);
}

function drawLeftArm() {
  colorParts(12);
  draw(5, 40, 40, 140);
}

function drawLeftHand() {
  colorParts(5);
  draw(5, 188, 10, 20);
  draw(15, 188, 15, 35);
  draw(35, 188, 10, 20);
  ctx.restore();
}

function drawRightShoulder(x, y, angle) {
  ctx.save();
  ctx.translate(x,y);
  ctx.rotate(angle);
  colorParts(8);
  draw(11, 0, 50, 30);
}

function drawRightArm() {
  colorParts(12);
  draw(17, 40, 40, 70);
  draw(17, 110, 90, 40);
}

function drawRightHand() {
  colorParts(5);
  draw(115, 110, 20, 10);
  draw(115, 120, 35, 15);
  draw(115, 138, 20, 10);
  ctx.restore();
}

  //Draw a bouquet
function drawBouquet(x, y, angle) {
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(angle);
  colorParts(1);
  draw(130, 0, 2, 165);
  draw(135, 0, 2, 165);
  draw(140, 0, 2, 165);
  draw(145, 0, 2, 165);
  colorParts(1);
  draw(120, -10, 20, 20);
  colorParts(1);
  draw(130, -10, 20, 20);
  colorParts(1);
  draw(140, -10, 15, 20);
  colorParts(1);
  draw(135, -10, 15, 20);
  ctx.restore();
}

function drawLeftLeg(x, y) {
  ctx.save();
  //Left Leg
  ctx.translate(x, y);
  colorParts(10);
  draw(10, 0, 30, 80);
  draw(-60, 80, 100, 30);
  //Left foot
  colorParts(5);
  draw(-85, 85, 18, 55);
  ctx.restore();
}

function drawRightLeg (x, y) {
  ctx.save();
  //Right Leg
  ctx.translate(x, y);
  colorParts(10);
  draw(0, 0, 90, 30);
  draw(60,35, 30, 90);
  //Right foot
  colorParts(5);
  draw(65, 132, 55, 18);
  ctx.restore();
}