How do I use this color object? - javascript

I do have an array of objects (book) here. My question is: How do I use the "color" object so each book has its color property? I think it has to be something like this -> book[amount].color <- but I can't make it work.
I don't know how to call the color property.
This is the array of objects:
var book = [
{title: "The Giver",
stars: 3,
author: "Lowry Loys",
color: color(0, 38, 255), //How do I make this property work in the code?
image: true},
{title: "How to win friends",
stars: 5,
author: "Dale Carnegie",
color: color(214, 255, 219),
image: false},
{title: "Principios fund. de la filosofía",
stars: 5,
author: "Georges Politzer",
color: color(115, 0, 255),
image: false}
];
This is the code
// draw shelf
fill(173, 117, 33);
rect(0, 120, width, 10);
// draw books + title + author
for (var amount = 0; amount < book.length; amount++) { //draw books
fill(214, 255, 219);
rect(154*amount, 20, 90, 100);
fill(0, 0, 0);
textSize(13);
text(book[amount].title, 5 + 158*amount, 27, 68, 100); //draw title
textSize(10);
text(book[amount].author, 5 + 155*amount, 91, 75, 100); //draw author
for (var s = 0; s < book[amount].stars; s++) { //draw stars
image(getImage("cute/Star"), 11 + s * 15 + amount * 151, 98, 15, 22);
}
for (var i = 0; i < book[amount].image; i++) { //draw stars
image(getImage("avatars/aqualine-sapling"), 9 + i * 60 + amount * 46, 42, 36, 39);
}
}

Assuming you don't have a color function, you'll have to quote those properties and then extract the color information.
In this simple example a regex grabs the color values from the (index 1) object, and then sets the background color of a temporary element.
var book=[{title:"The Giver",stars:3,author:"Lowry Loys",color:'color(0, 38, 255)',image:!0},{title:"How to win friends",stars:5,author:"Dale Carnegie",color:'color(214, 255, 219)',image:!1},{title:"Principios fund. de la filosofía",stars:5,author:"Georges Politzer",color:'color(115, 0, 255)',image:!1}]
const result = document.getElementById('result');
const color = book[1].color.match(/(\d+)/g);
result.style.backgroundColor = getColor(color);
function getColor(color) {
return `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
}
<div id="result">sdfdsfdsf</div>

The color function doesn't exist in plain javascript. I think the easiest way will be to store your colors as a HEXs in strings like below:
var book = [{
title: "The Giver",
stars: 3,
author: "Lowry Loys",
color: "#0026ff", // converted rgb(0, 38, 255)
image: true
}];
book[0].color; // "#0026ff"
You can use e.g. this tool to manually convert colors to HEX. If you don't like it just implement your own color function to convert rgb to hex (link).
Here you can also find an interesting npm package named Qix-/color:
JavaScript library for immutable color conversion and manipulation with support for CSS color strings.
Hope it helps!

Related

I can't figure out how to get these color variables to work in the draw function

I have been trying to use built-in functions in p5.js but I can't figure out what I am doing wrong, the col variable won't assign to moon.brightness rather the moon is always white when I preview it, I assigned my variables col and dor before the setup function and called them in the setup function before I initialised the Moon variable, at a total loss here, new to using p5.js so any help about where I am going wrong would be appreciated
var groundHeight;
var mountain1;
var mountain2;
var tree;
var moon;
var sun;
var darkness;
var brightness;
var col;
var dor;
function setup() {
cnv = createCanvas(800, 600)
//set the groundHeight proportional to the canvas size
groundHeight = (height / 3) * 2;
//initalise the mountain objects with properties to help draw them to the canvas
mountain1 = {
x: 400,
y: groundHeight,
height: 320,
width: 230
};
mountain2 = {
x: 550,
y: groundHeight,
height: 200,
width: 130
};
//initalise the tree object
tree = {
x: 150,
y: groundHeight + 20,
trunkWidth: 40,
trunkHeight: 150,
canopyWidth: 120,
canopyHeight: 100
};
//initalise the sun
sun = {
x: 150,
y: 70,
diameter: 80
};
col = (150, 200, 255)
dor = (255, 255, 255)
//TASK: intialise a moon object with an extra property for brightness
moon = {
brightness: col,
x: 700,
y: 70,
diameter: 80
};
//set the initial darkness
darkness = {
x: 800,
y: 600,
light: col
};
}
function draw() {
//TASK: update the values for the moons brightness, the sun's position and the darkness.
//You can either map this to the mouse's location (i.e. the futher left the mouse is the more daylight) or you can just change the values gradually over time.
//draw the sky
background(150, 200, 255);
noStroke();
//draw the sun
fill(255, 255, 0);
ellipse(sun.x, sun.y, sun.diameter);
sun.y = map(mouseX, 0, 800, 70, 630)
fill(moon.brightness)
ellipse(moon.x, moon.y, moon.diameter);
moon.brightness = map(mouseX, 0, 800, col, dor);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
There are two issues here:
In JavaScript the expression (1, 2, 3) does not create a an array, or a vector, or a tuple, or anything that could be used to represent a color. The comma operator evaluates the expression on the left, and the regardless of the value of that expression, it evaluates an expression on the right.
The p5.js map() function does not work with colors, it only works with numbers. If you're working with colors you need to use lerpColor()
var groundHeight;
var mountain1;
var mountain2;
var tree;
var moon;
var sun;
var col;
var dor;
function setup() {
cnv = createCanvas(800, 600)
//set the groundHeight proportional to the canvas size
groundHeight = (height / 3) * 2;
//initalise the mountain objects with properties to help draw them to the canvas
mountain1 = {
x: 400,
y: groundHeight,
height: 320,
width: 230
};
mountain2 = {
x: 550,
y: groundHeight,
height: 200,
width: 130
};
//initalise the tree object
tree = {
x: 150,
y: groundHeight + 20,
trunkWidth: 40,
trunkHeight: 150,
canopyWidth: 120,
canopyHeight: 100
};
//initalise the sun
sun = {
x: 150,
y: 70,
diameter: 80
};
// FIXED: Use the color function to create a p5.Color object from R G and B components
col = color(150, 200, 255)
dor = color(255, 255, 255)
//TASK: intialise a moon object with an extra property for brightness
moon = {
brightness: col,
x: 700,
y: 70,
diameter: 80
};
}
function draw() {
//TASK: update the values for the moons brightness, the sun's position and the darkness.
//You can either map this to the mouse's location (i.e. the futher left the mouse is the more daylight) or you can just change the values gradually over time.
scale
//draw the sky
background(150, 200, 255);
noStroke();
//draw the sun
fill(255, 255, 0);
ellipse(sun.x, sun.y, sun.diameter);
sun.y = map(mouseX, 0, 800, 70, 630)
fill(moon.brightness)
ellipse(moon.x, moon.y, moon.diameter);
// FIXED: when interpolating between two colors, use lerpColor instead of map
moon.brightness = lerpColor(col, dor, mouseX / width);
}
html, body {
margin: 0;
padding: 0;
}
canvas {
transform: scale(0.25);
transform-origin: top left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

Understanding the use of the % operator in my loop (Khan Academy project)

I hope I have come to the right place. I am currently doing a project on Khan academy where I need to use the % operator to create a loop of books for my bookshelf. I have only managed to get so far but I am stuck on how to get my list of books to automatically go to the next shelf after a certain number.
Apologies if I am not being clear but hopefully with the code and images I have provided, it makes sense.
Thanks in advance.
Bookshelf Project
Bookshelf Project Instructions
Project Code:
//array of objects for books
var book = [
{title: "The Giver",
author: "Jamie",
stars: 4,
color: color(156, 24, 222),
rec: true
},
{title: "Lord of the Rings",
author: "Mr Rings",
stars: 5,
color: color(222, 24, 97),
rec: true
},
{title: "Lord of the Flies",
author: "Mr Flies",
stars: 2,
color: color(222, 24, 215),
rec: false
},
{title: "Grapes of Wrath",
author: "Mr Grapes",
stars: 3,
color: color(34, 133, 19),
rec: true
}
];
// draw shelf
fill(173, 117, 33);
rect(0, 120, width, 10);
// loop of books
for (var i = 0; i < book.length; i++) {
fill(book[i].color);
rect(100 * i + 5, 20, 90, 100);
fill(240, 228, 240);
text(book[i].author, 100 * i + 10, 85, 70, 100);
text(book[i].title, 100 * i + 10, 30, 70, 100);
for (var s = 0; s < book[i].stars; s++) {
image(getImage("cute/Star"), 5 + s * 15 + i * 100, 90, 20, 30);
}
if(book[i].rec === true) {
image(getImage("creatures/Winston"), i * 100 + 75, 25, 15, 15);
} else {
image(getImage("creatures/OhNoes"), i * 100 + 75, 25, 15, 15);
}
fill(173, 117, 33);
rect(0, 120 + i * 100, width, 10);
}›
Javascript as many other programming languages uses % (Percentage sign) as an operator called Remainder, it will return the remainder after division of one number by another
Examples:
2 % 4 //-> 0
4 % 4 //-> 0
5 % 4 //-> 1
6 % 4 //-> 2
8 % 4 //-> 0
9 % 4 //-> 1
10 % 4 //-> 2
In the assignment he asks you to add more shelves down the canvas, and it's apparent that the shelve contains only four books, you can use % for determining the index of any book in each shelve inside the loop, as I mentioned in the examples above, if you're using the image index as the left-hand of the operation and the length of books as the right-hand, you will know which is the first book in the left in each shelve hence you can count its location in the canvas
(index + 1) % 4 // Add one to index because computer starts counting from 0

Connecting data from 2 arrays

I have a little bit hard question, but I try to explain it:
So, I have 2 arrays. First array - array of cities. The second is the matrix with distances between this cities;
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'];
var distanceMatrix = [
[0, 131, 523, 251, 600],
[131, 0, 785, 123, 541],
[252, 785, 0, 241, 741],
[251, 123, 241, 0, 632],
[600, 541, 741, 632, 0]
];
I need to generate a train with randomly choosen department and arrival point, with is not a problem. The problem is how to connect this 2 points with distance matrix correctly. If its possible. For example: distance between cities[1] and cities[3] accords to distanceMatrix[1][3] etc. So I need a function which randomly pick 2 towns and show distance between them according to distanceMatrix.
P.S. 2 days of hard mind work, and all I've done - is just 5 switch() functions, which is wrong way to complete this task.
Thank you !
You could take Array#indexOf for getting the index as accessor for the matrix.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'],
distances = [[0, 131, 523, 251, 600], [131, 0, 785, 123, 541], [252, 785, 0, 241, 741], [251, 123, 241, 0, 632], [600, 541, 741, 632, 0]];
function getDistance(city1, city2) {
return distances[cities.indexOf(city1)][cities.indexOf(city2)];
}
console.log(getDistance('Dresden', 'Berlin'));
console.log(getDistance('Dortmund', 'Bayern'));
An advanced solution could use an object with the indices.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'],
indices = { Gamburg: 0, Dresden: 1, Berlin: 2, Bayern: 3, Dortmund: 4 },
distances = [[0, 131, 523, 251, 600], [131, 0, 785, 123, 541], [252, 785, 0, 241, 741], [251, 123, 241, 0, 632], [600, 541, 741, 632, 0]];
function getDistance(city1, city2) {
return distances[indices[city1]][indices[city2]];
}
console.log(getDistance('Dresden', 'Berlin'));
console.log(getDistance('Dortmund', 'Bayern'));
Well, if I understood the problem correctly, you look for a way to form and access the matrix.
Let's first see the problem as indexes.
var cities = ['Gamburg', 'Dresden', 'Berlin', 'Bayern', 'Dortmund'];
cities[0] = Gamburg, cities[1] = Dresden, and so on.
The question is how to pick to cities at random and return the distance between the two.
function randomCities() {
while(true)
{
//Let's generate a random number between 0 and 4.
var randomCity_A = Math.floor((Math.random() * 4) + 0);
var randomCity_B = Math.floor((Math.random() * 4) + 0);
// add a condition that cities are not the same
if ( randomCity_A != randomCity_B){
var distance = distanceMatrix[randomCity_A][randomCity_B];
return "Distance between " + cities[randomCity_A] +" and " +
cities[randomCity_A] +": "+distance;
}
}
}
console.log(randomCities());
console.log(randomCities());

HERE Maps JS API v3: customize cluster marker's color

I know that I could just easily override nokia.maps.clustering.MarkerTheme.getColor in version 2.5.x to customize only the color of the cluster marker, but it seems there's no easy way to do so in version 3.0.x.
I mean, there is this H.clustering.ITheme interface that I could implement, yet it feels like it is a real pain for hacking into the color property. This is what I code so far (only relevant code shown):
var defaultTheme = clusteredDataProvider.getTheme(),
customTheme = {
/**
*
* #implements {H.clustering.ITheme.getClusterPresentation}
*/
getClusterPresentation: function (cluster) {
var clusterMarker = defaultTheme.getClusterPresentation
.call(defaultTheme, cluster);
/*
* TODO: Change the color property of the cluster marker.
* Hmm. How am I supposed to best do it?
*/
return clusterMarker;
},
/**
*
* #implements {H.clustering.ITheme.getNoisePresentation}
*/
getNoisePresentation: function (noisePoint) {
var noiseMarker = defaultTheme.getNoisePresentation
.call(defaultTheme, noisePoint);
return noiseMarker;
}
};
Does HERE Maps have a base SVG template of the cluster marker that I could make use of?
From what I can make out in the compressed code of the mapsjs-clustering.js, there is a bit more logic in the default theme than just creating new markers for every cluster. What seems to happen is that the API renders an image for each possible icon on the fly using canvas elements and then keeps reusing (get/putImageData calls) that for each marker based on the weight of the cluster. Here's some things I am able to figure out on where they create the icons:
weight < 10 : size 28, color "118, 209, 0", textPosition { x: 11, y: 18 }
weight < 25 : size 38, color "255, 105, 0", textPosition { x: 13, y: 23 }
weight < 50 : size 38, color "240, 60, 0", textPosition { x: 13, y: 23 }
weight < 100 : size 38, color "181, 0, 21", textPosition { x: 13, y: 23 }
weight < 1000 : size 48, color "181, 0, 21", textPosition { x: 15, y: 28 }
weight > 1000 : size 66, color "181, 0, 21", textPosition { x: 20, y: 38 }
So, to change the color property, you'd pretty much have completely reverse engineer the icon drawing code and rewrite it. Not sure this is a worthwhile approach...

Why am I getting an infinite for loop using javascript?

I am trying to create a bookshelf with various books. However, when I attempt to make a new bookshelf for every 4 books, I get an error. Possibly an infinite for loop? What is going wrong? (Khan Academy Program)
An array of books.
var book = [
{
title: "The Giver",
stars: 4,
author: "Lois Lowry",//2.Author property to each book added #1
color: color(0, 120, 42),//3. Property that stores color
recommended: true
},
{
title: "NWT of the Holy Scriptures",
stars: 5,
author: "Jehovah",//2.Author property... #2
color: color(204, 204, 204),//3. Property that stores color
recommended: true
},
{
title: "The Cay",
stars: 4,
author: "Theodore Taylor",//2.Author property... #3
color: color(80, 84, 209),//3. Property that stores color
recommended: true
},
{
title: "The Golden Compass",
stars: 5,
author: "Philip Pullman",//2.Author property... #4
color: color(97, 55, 186),//3. Property that stores color
recommended: true
},
];
Draw bookshelves and books
for(var x = 0; x < book.length; x++){
//Draw books
fill(book[x].color);
rect(5 + 100 * x, 20, 90, 100);
fill(0, 0, 0);
text(book[x].title, 15 + 100 * x, 29, 70, 100);
text(book[x].author,35 + 100 * x, 76, 70, 100);
//Draw leaf for recommended books
if(book[x].recommended === true){
var leaf = getImage("avatars/leaf-red");
image(leaf, 10 + 100 * x, 85,25,25);
}
//Draw stars for star rating
for (var i = 0; i < book[x].stars; i++) {
image(getImage("cute/Star"), 17 + i * 15 + 100 * x, 96 , 15, 25);
}
//Draw bookshelf for every 4 books
for(var y = book.length;y >= 0;y - 4){
// draw shelf
fill(87, 10, 0);
rect(0, 120 + 100 * y, width, 10);
}/// <------ infinite loop?
}
for(var y = book.length;y >= 0;y - 4){
...is not actually mutating the value of y. Change it to:
for( var y = book.length; y >= 0; y -= 4 ) {

Categories

Resources