I am trying to create an etch-a-sketch project. I have a function that paints squares black if "black variable" is true. Moreover, I have another function(it is a button on click effect function) which is capable of turning "black variable" into false and painting squares with random generated colours. However, I cannot create a button which turns "black variable" into true. BlackButton function doesn't work even though tileRainbow function works. Only the last function doesn't work.
I tried altering the function, change the order of functions.
const tiles = document.getElementsByClassName("newDiv")
let black = true
//paint squares black on mouseover effect if black is true
function tileBlack() {
if (black == true) {
for (tile of tiles) {
tile.addEventListener("mouseover", function (event) {
event.target.style.backgroundColor = "black";
})
}
}
}
//make rainbow button capable of changing black variable to false. if it is false paint squares with random generated colours.
function rainbowTile() {
black = false;
const rainbow = document.querySelector("#rainbow")
rainbow.addEventListener('click', event => {
if (black !== true) {
for (tile of tiles) {
let randomnum = Math.floor(Math.random() * 255)
let randomnum2 = Math.floor(Math.random() * 255)
let randomnum3 = Math.floor(Math.random() * 255)
tile.addEventListener("mouseover", function (event) {
event.target.style.backgroundColor = `rgb(${randomnum}, ${randomnum2}, ${randomnum3})`;
})
}
}
})
}
//make black button capable of changing black variable to true so tileBlack function activates.
function blackButton() {
const paintitblack = document.querySelector("#black")
paintitblack.addEventListener('click', event => {
black = true;
})
}
I do not get any error on console. However, my code doesn't work.
You shouldn't be testing the variable when calling addEventListener(). If you call both tileBlack() and rainbowTile(), the tiles have both event listeners.
Instead, you should add a single event listener once, and it should check the variable when it runs.
Array.from(tiles).forEach(tile => tile.addEventListener("mouseover", event => {
if (black) {
event.target.style.backgroundColor = "black";
} else {
let randomnum = Math.floor(Math.random() * 255)
let randomnum2 = Math.floor(Math.random() * 255)
let randomnum3 = Math.floor(Math.random() * 255)
tile.addEventListener("mouseover", function(event) {
event.target.style.backgroundColor = `rgb(${randomnum}, ${randomnum2}, ${randomnum3})`;
})
}
}););
Related
I am creating a 24a2 browser game. I want to add another area to the game where you can not only draw using the key pad, but also when clicking on the dots, the dots within the 24x24 grid fill with the corresponding color. Here is the code:
function create(game) {}
function update(game) {}
function onKeyPress(direction) {}
let seen = {};
let config = {
create: create,
update: update,
onKeyPress: onKeyPress,
onButtonPress: onButtonPress
};
let game = new Game(config);
game.run();
let player = {};
function onButtonPress(x, y) {
game.setDot(x, y, Color.Black)
}
function create(game) {
player = {
x: 5,
y: 10,
};
game.setDot(player.x, player.y, Color.Blue);
}
function update(game) {
for (var key in seen) {
let coordinates = seen[key];
game.setDot(coordinates[0], coordinates[1], Color.Indigo);
}
game.setDot(player.x, player.y, Color.Black);
}
// Drawing using the dot with a specific color
function onKeyPress(direction) {
let key = player.x + ',' + player.y; // setting a delimeter; if the position is 1,11 for example, the dot will move to 1, 11 and not '111'.
seen[key] = [player.x, player.y];
if (direction == Direction.Up) {
player.y--;
}
if (direction == Direction.Down) {
player.y++;
}
if (direction == Direction.Left) {
player.x--;
}
if (direction == Direction.Right) {
player.x++;
}
}
This code moves the black dot around to fill the grid with color. This is the code I was thinking about in order to fill the dots when clicked.
function onButtonPressed(x, y) {
game.setDot(x, y, Color.Yellow)
}
However, when I run this, the dots do not fill when I click on them. Where am I going wrong with this?
I have an HTML canvas element that a user can draw on, and I want to change the fill color of the canvas when the refresh icon is clicked, and it set it to a different color depending on the body ID.
Currently the onClick function is changing the body ID and body color as a result but it is not updating the canvas fill color. Does anyone have any ideas.
I'm fairly new to HTML canvas and not really used it much before so any help is appreciated.
I think it is this bit of code that is wrong.
function refresh() {
const colors = ["blue", "red", "green", "pink"];
const random = Math.floor(Math.random() * colors.length);
document.body.id = colors[random];
var bodyid = document.body.id;
console.log(bodyid);
var bridge = document.getElementById("canvas"),
bridgeCanvas = bridge.getContext('2d');
if(bodyid == 'red'){
bridgeCanvas.fillStyle = "#6ecbff";
} else if(bodyid == 'blue') {
bridgeCanvas.fillStyle = "#fedcdb";
} else if(bodyid == 'green') {
bridgeCanvas.fillStyle = "#fefd55";
} else if(bodyid == 'pink') {
bridgeCanvas.fillStyle = "#96b6cd";
}
};
The full code is in the codepen below
https://codepen.io/oddpandadesign/pen/vYyybQG
You have to set the color first and then fill the rectangle.
bridgeCanvas.fillStyle = color;
bridgeCanvas.fillRect(0, 0, bridge.width, bridge.height);
I'm trying to make 'slitscan' effects.
I set 2 canvases. One on the right is for source image, and another is for scan effect.
When i tried it with text function it works perfectly, however with an image, the copy function gives me an error message.
This is the p5 code I wrote
let a1, a2;
let cv1, cv2;
let dy = 0;
let s1 = function(p) {
p.setup = () => {
cv1 = p.createCanvas(300, 300);
p.background(150);
cv1.position(0, 0);
}
p.draw = () => {
p.copy(cv2, 0, dy, 400, 1, 0, dy, 400, 1);
if (dy > cv2.height) {
dy = 0;
} else {
dy += 1;
}
}
}
a1 = new p5(s1);
let s2 = function(p) {
let img;
p.preload = () => {
img = p.loadImage('https://pbs.twimg.com/profile_images/635910989498724356/uY4bc8q2.jpg');
}
p.setup = () => {
cv2 = p.createCanvas(300, 300);
cv2.position(300, 0);
}
p.draw = () => {
p.background(30);
p.imageMode(p.CENTER);
p.image(img, p.mouseX, p.mouseY);
}
}
a2 = new p5(s2);
In addition, if you have a better idea to make multi-canvas or any suggestion about my code, please leave a comment.
Thanks,
In your s1 sketch, you try to do stuff with the canvas cv2. Yet this canvas is only created later in your sketch.
To fix it, just change the order of your two sketches, i.e., call a1 = new p5(s1); after a2 = new p5(s2); (it doesn't matter when you define s1 and s2, only when you instantiate them).
See, for example, this p5 editor sketch.
Here is the fiddle: http://jsfiddle.net/sw31uokt/
Here is some of the relevant code for the incrementValue function I set up to count overall clicks within the canvas element.
What I would like to do is be able to display a count of each color, so "you have placed 14 red pixels, 3 blue pixels, 4 black pixels'.
function incrementValue()
{
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('number').value = value;
}
$(c_canvas).click(function(evt) {
var pos = getNearestSquare(getMousePos(c_canvas, evt));
if (pos != null) {
context.fillStyle=(currentColor);
context.fillRect(pos.x,pos.y,19,19);
incrementValue();
}
});
Basically, what MarkE said above ...
In the outer scope, add two new vars :
var palette = ["333333", "0000ff", "a0522d", "46ad42", "808080", "ffc0cb", "d73952", "ffe2a8", "ffff7d", "ffffff"];//as originally defined in the .spectrum() call.
var gridModel = [];//Eventually a sparse array of sparse arrays, representing colored grid squares. Uncolored grid squares remain undefined.
And two new functions, in the same scope :
function updateGridModel(pos, color) {
var x = (pos.x - 0.5) / 20;
var y = (pos.y - 0.5) / 20;
color = color.substr(1).toLowerCase();
if (!gridModel[x]) {
gridModel[x] = [];
}
gridModel[x][y] = palette.indexOf(color);
}
function paletteTally() {
//initialise an array, same length as palettes, with zeros
var arr = palette.map(function () {
return 0;
});
for (var x = 0; x < gridModel.length; x++) {
if (gridModel[x]) {
for (var y = 0; y < gridModel[x].length; y++) {
if (gridModel[x][y] !== undefined) {
arr[gridModel[x][y]] += 1;
}
}
}
}
return arr;
}
Modify the canvas's click handler to keep the gridModel up to date :
$(c_canvas).click(function (evt) {
var pos = getNearestSquare(getMousePos(c_canvas, evt));
if (pos != null) {
context.fillStyle = currentColor;
context.fillRect(pos.x, pos.y, 19, 19);
incrementValue();
updateGridModel(pos, currentColor); //keep the gridModel up to date.
}
});
Modify printColor() as follows :
function printColor(color) {
currentColor = color.toHexString();
$(".label").text(currentColor);
}
Modify the .spectrum() options and add an initialising call to printColor() as follows :
$("#showPaletteOnly").spectrum({
color: palette[0],
showPaletteOnly: true,
showPalette: true,
hideAfterPaletteSelect: true,
change: printColor,
palette: [palette] //<<<< palette is now defined as an outer var
});
printColor( $("#showPaletteOnly").spectrum('get') );//initialize currentcolor and $(".label").text(...) .
Now paletteTally() will return an array congruent with palette containing counts of each color.
EDIT 1
Original code above was untested but is now debugged and includes improved spectrum options. Demo.
So I want a rectangle of my canvas to change the color from black to yellow, to show that this same part have received an information. There is two rectangles from 2 diferent paths, and I want them to change the color in a random way.
If one rectangle is "0" and the other is "1", for example, when I press the button "Begin", math.random() will choose it to be 1 and rectangle "1" will change it's color from black to yellow. The loop will happen again and if math.random() choose it to be 0, now it's the rectangle 0 that will change it's color. And so on, until I press the "End" button.
This is what I tried to write on javascript:
iniciarButton.onclick = function (e) {
iniciarButton.disabled = true;
pararButton.disabled = false;
for (;;) {
var numAleat = Math.floor(Math.random() * 2);
if (numAleat === 1) {
context.fillStyle = "yellow";
context.fillRect(715,140,10,15);
context.fillStyle = "black";
context.fillRect(642,80,15,10);
} else {
context.fillStyle = "yellow";
context.fillRect(642,80,15,10);
context.fillStyle = "black";
context.fillRect(715,140,10,15);
}
if (iniciarButton.disabled === false) break;
}
};
pararButton.onclick = function (e) {
pararButton.disabled = true;
iniciarButton.disabled = false;
};
The problem is that it isn't working the way I expected it. When I press the "begin" button it enters on a loop that ends on one rectangle yellow and the other black and not like blinking in a random way.