Am trying to do an Etch-A-Sketch project and currently hit some roadblocks. Currently am able to create a grid based off user input on prompt and clear the grid through a button.
The problem I'm facing now is in the function colorChange(), where I'm trying to get opacity of the background color to increase every time a mouse hover event is captured over the div. Everything works fine but opacity maxes out at 0.9 in the current code.
If instead using if (rgbaValue <= 0.9) or (rgbaValue < 1), the opacity value resets to 0.1 on the next hover after 0.9. How would I go about getting the opacity to 1 without resetting?
Code below:
html
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="style.css">
<title>Etch A Sketch</title>
<body>
<div>
<button type="button" onclick="clearGrid()">Click to clear grid</button>
</div>
<div id="container"></div>
<script src="java.js"></script>
</body>
</html>
javascript
let gridSize = 0;
let gridWidth = 0;
gridSize = window.prompt("Please input the amount of squares per side of grid that you want created");
gridWidth = 100/gridSize;
createGrid();
colorChange();
function createSquare() {
const mainBody = document.querySelector("#container");
const gridMake = document.createElement("div");
gridMake.classList.add("squaregrid");
gridMake.style.width = gridWidth + "%";
gridMake.style.paddingBottom = gridWidth + "%";
mainBody.appendChild(gridMake);
}
function createGrid() {
gridCount = 0;
while (gridCount < (gridSize*gridSize)) {
createSquare();
gridCount++
}
}
function colorChange() {
const selectSquare = document.querySelectorAll(".squaregrid");
selectSquare.forEach(square => square.addEventListener("mouseover", event => {
square.classList.add('hover-change');
const style = getComputedStyle(square);
let styleDeep = style.backgroundColor;
rgbaValue = parseFloat(styleDeep.replace(/^.*,(.+)\)/,'$1'));
if (rgbaValue < 0.9) {
square.style.backgroundColor = `rgba(0,0,0, ${rgbaValue + 0.1})`;
}
}))
}
function clearGrid() {
const squareReset = document.querySelectorAll(".squaregrid");
squareReset.forEach(square => square.style.backgroundColor = "");
squareReset.forEach(square => square.classList.remove("hover-change"));
}
css
.squaregrid {
box-sizing: border-box;
display: inline-block;
border: 0.05px solid black;
margin:0;
}
html, body {
line-height: 0;
height: 94vh;
width: 94vh;
margin-left: auto;
margin-right: auto;
}
#container {
display: block;
overflow: hidden;
margin-left: auto;
margin-right: auto;
border: 0.05px solid black;
}
.hover-change {
background-color: rgba(0, 0, 0, 1);
}
button {
display: block;
margin-bottom: 5px;
}
The main problem with your code has to do with the way the browser
handles full opacity.
The rgba() notation accepts a number in the range 0.0 to 1.0, inclusive, or a percentage, where the number 1 corresponds to 100%, for the value of the alpha channel. Any value outside the interval, though valid, is clamped to the nearest limit in the range.
A value greater than 1 or 100% will be clamped and
omitted from the computed value
background-color: rgba(0, 0, 0, 0.5); # computed (0, 0, 0, 0.5)
background-color: rgba(0, 0, 0, 1); # computed (0, 0, 0)
background-color: rgba(0, 0, 0, 1.3); # computed (0, 0, 0)
Your regex is capturing any character between the last comma
in the rgba() notation and the closing parenthesis of the computed
value. When the event listener is triggered after you have assigned
the square an alpha value equal or greater than 1 your regex captures 0
and sets the alpha value accordingly.
In the Code snippet below you can see one way of solving the problem using an other regular expression.
Alternatively you could make use of the opacity property as #Luca Neri
already suggested.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body, html {
margin: 0;
}
.squaregrid {
display: grid;
}
.square {
background-color: rgba(20, 20, 20, 0.1);
}
button {
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<div class="squaregrid"></div>
<button onclick="clearScreen()">CLEAR</button>
<script>
//request number of rows
let rows = window.prompt("ENTER NUMBER OF ROWS")
//create a grid
document.getElementsByClassName("squaregrid")[0].style.gridTemplateColumns = "repeat("+ 1000/rows+", 1fr)"
//create Squares
for (let i = 0; i < 1000; i++) {
let newSquare = document.createElement("div")
newSquare.className = "square"
newSquare.style.height = 100/rows + "vh"
document.querySelector(".squaregrid").appendChild(newSquare)
}
//get HTML Collection of all squares
let allSquares = document.getElementsByClassName("square");
//loop HTML Collection and add a mouseover event listener to each square
for (square of allSquares) {
square.addEventListener("mouseover", event => {
//get computed background-color value of the square being hovered over
let squareBackground = getComputedStyle(event.target).backgroundColor;
//the regular expression
let regex = /\d\.\d/
//check if does not already have full opacity
if (squareBackground.match(regex) != null) {
//get the alpha channel of the square being hovered over
let squareOpacity = Number(squareBackground.match(regex))
//increase alpha value
event.target.style.backgroundColor = squareBackground.replace(regex, squareOpacity + 0.1)
}
})}
//reset every square on the grid
function clearScreen() {
for (square of allSquares) {
square.style.backgroundColor = "rgba(20, 20, 20, 0.1)"
}
}
</script>
</body>
</html>
Thanks for the feedback, #disinfor.
Related
I have an API list and I want my divs to float within this huge container. this is my reference - but for some reason this doesn't work for mine (http://jsfiddle.net/bsd3b0r0/1/) I know I'm probably missing something, naming of my divs or something but I simply cannot figure it out. Would appreciate any advice.
/* globals require */
console.log("Hello, Airtable");
let wrapper = document.querySelector(".container");
// load the airtable library, call it "Airtable"
let Airtable = require("airtable");
console.log(Airtable);
// use the airtable library, connect to our base using API key
let base = new Airtable({ apiKey: "keyXfgdNIcv7dW63l" }).base(
"appWiQM0htfVBj9RL"
);
//get the "books" table from the base, select ALL the records, and specify the functions that will receive the data
base("nature_sounds").select({}).eachPage(gotPageOfSounds, gotAllSounds);
// an empty array to hold our book data
let sounds = [];
// callback function that receives our data
function gotPageOfSounds(records, fetchNextPage) {
console.log("gotPageOfSounds()");
// add the records from this page to our books array
sounds.push(...records);
// request more pages
fetchNextPage();
}
// call back function that is called when all pages are loaded
function gotAllSounds(err) {
console.log("gotAllSounds()");
// report an error, you'd want to do something better than this in production
if (err) {
console.log("error loading sounds");
console.error(err);
return;
}
// call functions to log and show the books
consoleLogSounds();
showSounds();
}
// just loop through the books and console.log them
function consoleLogSounds() {
console.log("consoleLogSounds()");
sounds.forEach((sound) => {
console.log("Sound:", sound);
});
}
// loop through the books, create an h2 for each one, and add it to the page
function showSounds() {
console.log("showSounds()");
sounds.forEach((sound) => {
let soundTextHolder = document.createElement("div"); // victoria u changed it from h2 to div dont forget//
soundTextHolder.classList.add("entry");
soundTextHolder.innerText = sound.fields.emotion;
wrapper.appendChild(soundTextHolder);
let soundColor = sound.fields.color_hex_code;
soundTextHolder.style.backgroundColor = soundColor;
let audioHolder = document.createElement("audio");
audioHolder.src = sound.fields.audio_file[0].url;
audioHolder.classList.add("soundClass");
audioHolder.controls = true;
audioHolder.autoplay = true;
audioHolder.loop = true;
soundTextHolder.appendChild(audioHolder);
});
}
// trying to aniamte//
var divsize = 5,
divcount = 50;
var gRows = Math.floor($(".container").innerWidth() / divsize);
var gCols = Math.floor($('.container').innerHeight() / divsize);
var vals = _.shuffle(_.range(divcount));
var xpos = _.shuffle(_.range(gRows));
var ypos = _.shuffle(_.range(gCols));
_.each(vals, function(d, i) {
var $newdiv = $('<div/>').addClass("div");
$newdiv.css({
'position': 'absolute',
'left': (xpos[i] * divsize) + 'px',
'top': (ypos[i] * divsize) + 'px'
}).appendTo('.container').html(d);
animateDiv();
});
function newPosition() {
// Get viewport dimensions (remove the dimension of the div)
var h = $('.container').height() - 50;
var w = $('.container').width() - 50;
var newh = Math.floor(Math.random() * h);
var neww = Math.floor(Math.random() * w);
return [newh, neww];
}
function animateDiv() {
var newp = newPosition();
var oldp = $('div').offset();
var speed = 3000;
$('div').animate({
top: newp[0],
left: newp[1]
}, speed, function() {
animateDiv();
});
};
// // // collect all the divs
// var divs = document.getElementsByTagName('h2');
// // // get window width and height
// / var winWidth = window.innerWidth;
// / var winHeight = window.innerHeight;
// // // i stands for "index". you could also call this banana or haircut. it's a variable
// // for ( var i=0; i < divs.length; i++ ) {
// // // shortcut! the current div in the list
// // var thisDiv = divs[i];
// // // get random numbers for each element
// // randomTop = getRandomNumber(0, winHeight);
// // randomLeft = getRandomNumber(0, winWidth);
// // // update top and left position
// / thisDiv.style.top = randomTop +"px";
// / thisDiv.style.left = randomLeft +"px";
// }
// // function that returns a random number between a min and max
// function getRandomNumber(min, max) {
// return Math.random() * (max - min) + min;
// }
body{
font-family: Space Mono;
background-color: white;
}
h1{
text-align: right;
color: black;
font-family: sans-serif;
}
.container{
width: 100%;
/* align-items: center;
display: grid;
grid-row: inherit;
position: relative; */
}
div{
border-radius: 50% 20% / 10% 40%;
/* border-radius: 10% / 50%; */
width: 30vw;
margin-left: auto;
margin-right: auto;
text-align: center;
/* display: flex; */
flex-direction: column;
box-shadow: inset 0 0 2000px rgba(255, 255, 255, .5);
filter: blur(1px);
/* animation-name: floating;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out; */
}
/* #keyframes floating {
0% { transform: translate(0, 0px); }
50% { transform: translate(0, 15px); }
100% { transform: translate(0, -0px); }
} */
.entry1{
width: 60vw;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EllasticCollection</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Mono&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>sound and color through emotion</h1>
<div id="myData" class="container">
<div class="individual-colors"></div>
</div>
<script src="airtable.browser.js" defer></script>
<script src="script.js" defer></script>
</body>
</html>
I'm making a color guessing game in JS. You're given the RGB value of a color, and you're supposed to click one of the three divs with that specific color while the other two have a different color. I've managed to make these three divs have three different random colors; however, I can't figure out how to make one of them have the winning color.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1 class="text-centered">Guess The Color!</h1>
<h2 class="text-centered" id="colorguess"></h2>
<div class="box-container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
</body>
<script src="script.js"></script>
</html>
*{
box-sizing: border-box;
}
body{
font-family: arial;
background-color: #1c1874;
color: rgb(105, 105, 139);
color: #fff;
}
.text-centered{
text-align: center;
text-shadow: 0px 2px 2px rgba(150, 150, 150, 1);
}
.box-container{
padding: 200px;
align-self: center;
display: flex;
flex-direction: row;
justify-content:space-evenly;
}
.box{
width: 200px;
height: 200px;
border-radius: 20px;
cursor: pointer;
}
function gamestart(){
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
var rgb = document.getElementById('colorguess');
//here i defined the initial winning color
rgbvaluetrue = "rgb("+r+", "+g+", "+b+")";
rgb.innerHTML = rgbvaluetrue;
var body = document.getElementsByTagName('body');
var box = document.getElementsByClassName('box');
for(var i=0;i<=box.length;i++){
var r,g,b = Math.floor(Math.random() * 256);
rgbvalue = "rgb("+r+", "+g+", "+b+")";
box[i].style.backgroundColor = rgbvalue;
}
//here I am trying to assign the initial rgb value to one of the divs randomly
var rand = Math.floor(Math.random() * 3);
//here I check if the div you clicked on is correct
box[rand].style.backgroundColor = rgbvaluetrue;
for(var i=0;i<=box.length;i++){
box[i].addEventListener("click", function(el) {
if (el.style.backgroundColor == rgbvaluetrue){
h1 = document.getElementsByTagName('h1');
h1.innerHTML = "BRAVO";
}
else{
gamestart();
}
})
}
}
gamestart();
The code for the game is there but there were three of mistakes in it.
I'll go through them one by one:
The two for cycles are run 4 times instead of 3. The termination condition i<=box.length should be replaced by i<box.length.
The addEventListener handler doesn't get the element as an input parameter but the event itself. You can then get the element with the target property like this: event.target.
After this assignment h1 = document.getElementsByTagName('h1'); h1 contains an array with all the h1 elements so you can't assign use h1.innerHTML = "BRAVO"; to assign a content to it. I changed it to display the success text in the same h1 you are using to show the rgb value like this:
h1 = document.getElementById('colorguess');
Lastly, in your code the addEventListener is called every time the game is played.
After the first victory you will have 2 listeners for every box making the game unplayable unless you refresh the entire page. To solve this I moved the listeners registration in a init function that you have to call only once at the start of the first game. (Another way was to remove and then readd the event listener every time)
Here is the complete js code. I didn't touch the html/css parts.
var rgbvaluetrue;
function initGame() {
var box = document.getElementsByClassName('box');
for(var i=0;i<box.length;i++){
box[i].addEventListener("click", checkWinner);
}
}
function gamestart(){
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
var rgb = document.getElementById('colorguess');
//here i defined the initial winning color
rgbvaluetrue = "rgb("+r+", "+g+", "+b+")";
rgb.innerHTML = rgbvaluetrue;
var body = document.getElementsByTagName('body');
var box = document.getElementsByClassName('box');
for(var i=0;i<box.length;i++){
var r,g,b = Math.floor(Math.random() * 256);
rgbvalue = "rgb("+r+", "+g+", "+b+")";
box[i].style.backgroundColor = rgbvalue;
}
//here I am trying to assign the initial rgb value to one of the divs randomly
var rand = Math.floor(Math.random() * 3);
//here I check if the div you clicked on is correct
box[rand].style.backgroundColor = rgbvaluetrue;
}
function checkWinner(event) {
if (event.target.style.backgroundColor === rgbvaluetrue){
h1 = document.getElementById('colorguess');
h1.innerHTML = "BRAVO";
}
else{
gamestart();
}
}
initGame();
gamestart();
There is a small mistake in the loops:
for(var i=0;i<=box.length;i++){ It goes 4 times, but you have 3 boxes
change to for(var i=0;i<box.length;i++){
There are multiple issues:
for loops are iterating more times than needed
var r, g, b = ... will only assign b. r and g will remain undefined
I refactored the JavaScript and fixed all issues, run the below snippet:
const getRandomColor = () => {
return `rgb(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)})`;
}
let colorToGuess = '';
const resultContainer = document.querySelector('#result');
const colorToGuessContainer = document.querySelector('#color-to-guess');
const boxes = document.querySelectorAll('.box-container .box');
const startGame = () => {
resultContainer.innerText = "Guess The Color!"
colorToGuess = getRandomColor();
colorToGuessContainer.innerHTML = colorToGuess;
const randomBoxIndex = Math.floor(Math.random() * boxes.length);
boxes.forEach((box, index) => {
box.style.backgroundColor = index === randomBoxIndex ? colorToGuess : getRandomColor();
})
}
boxes.forEach((box) => {
box.addEventListener('click', ({
target
}) => {
if (target.style.backgroundColor === colorToGuess) {
resultContainer.innerText = "You guessed it, click me to play again."
} else {
startGame()
}
})
})
startGame();
resultContainer.addEventListener('click', startGame)
* {
box-sizing: border-box;
}
body {
font-family: arial;
background-color: #1c1874;
color: white;
}
.text-centered {
text-align: center;
text-shadow: 0px 2px 2px rgba(150, 150, 150, 1);
}
.box-container {
padding: 2rem;
display: flex;
align-items: center;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
border-radius: 20px;
cursor: pointer;
}
<h1 class="text-centered" id="result"></h1>
<h2 class="text-centered" id="color-to-guess"></h2>
<div class="box-container">
<div class="box">
</div>
<div class="box">
</div>
<div class="box">
</div>
</div>
When starting my program, everything initially runs as intended. However, when I click a button on the webpage that runs my clearBoard() function, the code in the global scope no longer runs.
I've used console.log and everything that is outside of a function is empty after running the clearBoard().
const container = document.getElementById("container");
//Create board
function makeRows(rows, columns) {
//let container = document.getElementById("container");
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', columns);
for (c = 0; c < (rows * columns); c++) {
let cell = document.createElement("div");
//cell.innerText = (c + 1);
container.appendChild(cell).className = "grid-item";
}
}
//Draw starting Board
makeRows(16, 16);
//Paint on board
const paint = document.getElementsByClassName("grid-item");
console.log(container);
for (let i = 0; i < paint.length; i++) {
paint[i].addEventListener('mouseover', function() {
this.style.backgroundColor = "black";
});
}
//Get new board size
function getNewBoard() {
//clear divs
const removeOldGrid = document.getElementById("container");
removeOldGrid.innerHTML = '';
//get input from user
let squares = prompt('How many squares per side?');
//convert input to number
let squaresInt = parseInt(squares);
//generate new board
makeRows(squaresInt, squaresInt);
}
//Clear board
function clearBoard() {
for (let i = 0; i < paint.length; i++) {
paint[i].style.backgroundColor = "";
}
getNewBoard();
}
:root {
--grid-cols: 0;
--grid-rows: 0;
--paint-color: ;
}
#container {
display: grid;
padding: 10em;
height: 40vh;
width: 50vh;
margin-left: auto;
margin-right: auto;
/*grid-gap: 1em;*/
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid #ddd;
text-align: center;
/*background-color: var(--paint-color);*/
}
/*.grid-item:hover {
background-color: black;
}
<button onclick="clearBoard()">Clear Board</button>
<div id="container">
</div>
That is happening because you are creating a new board, consequently a new grid-item element. The mouseover event listener is added to the paint variable, which contains the old element after clearBoard() is called.
The solution is to add a new event listener to paint when a new board is generated. Your JS should look something like this:
//Paint on board
var paint = document.getElementsByClassName("grid-item");
console.log(container);
// Function to add the mouseover event listener when "paint" changes
function addMouseoverEventListener() {
for (let i = 0; i < paint.length; i++)
{
paint[i].addEventListener('mouseover', function() {
this.style.backgroundColor = "black";
});
}
}
addMouseoverEventListener();
//Get new board size
function getNewBoard() {
//clear divs
const removeOldGrid = document.getElementById("container");
removeOldGrid.innerHTML = '';
//get input from user
let squares = prompt('How many squares per side?');
//convert input to number
let squaresInt = parseInt(squares);
//generate new board
makeRows(squaresInt, squaresInt);
// Get the new element
paint = document.getElementsByClassName("grid-item");
// Add the event listener again
addMouseoverEventListener();
}
Instead of using paint[i].addEventListener use window.onmouseover and check the target
const container = document.getElementById("container");
//Create board
function makeRows (rows, columns) {
//let container = document.getElementById("container");
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', columns);
for (c = 0; c < (rows * columns); c++) {
let cell = document.createElement("div");
//cell.innerText = (c + 1);
container.appendChild(cell).className = "grid-item";
}
}
const paint = document.getElementsByClassName("grid-item");
//Draw starting Board
makeRows(16, 16);
window.onmouseover=function(e) {
if(e.target.className == "grid-item")
{
e.target.style.backgroundColor = "black";
}
};
//Get new board size
function getNewBoard() {
//clear divs
const removeOldGrid = document.getElementById("container");
removeOldGrid.innerHTML = '';
//get input from user
let squares = prompt('How many squares per side?');
//convert input to number
let squaresInt = parseInt(squares);
//generate new board
makeRows(squaresInt, squaresInt);
}
function clearBoard() {
for (let i = 0; i < paint.length; i++) {
paint[i].style.backgroundColor = "";
}
getNewBoard();
}
:root {
--grid-cols: 0;
--grid-rows: 0;
--paint-color: ;
}
#container {
display: grid;
padding: 10em;
height: 40vh;
width: 50vh;
margin-left: auto;
margin-right: auto;
/*grid-gap: 1em;*/
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid #ddd;
text-align: center;
/*background-color: var(--paint-color);*/
}
/*.grid-item:hover {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Etch-a-Sketch</title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="style.css" rel="stylesheet">
</head>
<body>
<button onclick = "clearBoard()">Clear Board</button>
<div id="container">
</div>>
<script src="script.js"></script>
</body>
</html>
I want to link the background color of the body element to the scroll position such that when the page is scrolled all the way to the top its color 1, but then but then when its scrolled past screen.height, its a completely different color, but I want it to be interpolated such that when it is half-way scrolled, the color is only half-way transitioned. So far, I have it linked to
$(window).scrollTop() > screen.height
and
$(window).scrollTop() < screen.height
to add and remove a class that changes background-color but I want it to be dependent on scroll position not just to trigger the event, but rather smoothly animate it so fast scrolling transitions quickly, slow scrolling transitions it slowly.
One of possible solutions is to bind a rgb color to current height, count the step and set new rgb color depending on current position of scrolling. Here I've created the simplest case - black and white transition:
const step = 255 / $('#wrapper').height();
const multiplier = Math.round(
$('#wrapper').height() /
$('#wrapper').parent().height()
);
$('body').scroll(() => {
const currentStyle = $('body').css('backgroundColor');
const rgbValues = currentStyle.substring(
currentStyle.lastIndexOf("(") + 1,
currentStyle.lastIndexOf(")")
);
const scrolled = $('body').scrollTop();
const newValue = step * scrolled * multiplier;
$('#wrapper').css('background-color', `rgb(${newValue}, ${newValue}, ${newValue})`);
});
html,
body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
background-color: rgb(0, 0, 0);
}
#wrapper {
height: 200%;
width: 100%;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<section id="wrapper"></section>
And here is another one example with transition from yellow to blue:
const step = 255 / $('#wrapper').height();
const multiplier = Math.round(
$('#wrapper').height() /
$('#wrapper').parent().height()
);
$('body').scroll(() => {
const currentStyle = $('body').css('backgroundColor');
const rgbValues = currentStyle.substring(
currentStyle.lastIndexOf("(") + 1,
currentStyle.lastIndexOf(")")
);
const scrolled = $('body').scrollTop();
const newValue = step * scrolled * multiplier;
$('#wrapper').css('background-color', `rgb(${255 - newValue}, ${255 - newValue}, ${newValue})`);
});
html,
body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
background-color: rgb(255, 255, 0);
}
#wrapper {
height: 200%;
width: 100%;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<section id="wrapper"></section>
var randomHex = function () {
return (parseInt(Math.random()*16)).toString(16) || '0';
};
var randomColor = function () {
return '#'+randomHex()+randomHex()+randomHex();
};
var randomGradient = function () {
$('.longContent').css('background', 'linear-gradient(0.5turn, #222, '+randomColor()+','+randomColor()+')');
};
$(window).on('load', randomGradient);
body {
margin: 0;
}
.longContent {
height: 400vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
<div class="longContent"></div>
A much, much easier way to accomplish what you're looking to do is by simply using a gradient as the background.
There is absolutely zero need for any JS here, which will only slow down the page.
body {
height: 600vh;
background: linear-gradient(#2E0854, #EE3B3B)
}
Is there a particular reason you want to do this with JS?
I am working on a project trying to make something resembling an etch-a-sketch. I have a 780x780px square, and I am trying to get a 16x16 grid, using a series of smaller square divs.
It is on this grid that I have the hover effect. I keep getting a 15x17 grid of square divs because the last square of the row won't fit. I have margins set to 1px and padding set to 0 so I figured that to fit 16 squares on a 780px wide row, it would require me to take into account the margins (15 1px margins) and from there I could divide (780-15) by 16, the number of squares I want.
That isn't working, and the next step of this project is to have a button where the user could input any number of squares for the row/column and have either a larger or smaller squared grid STILL ON the 780x780 square. Does anyone have any ideas? I'm pretty stumped.
$(document).ready(function() {
var original = 16;
for (var y = 0; y < original * original; y++) {
$(".squares").width((780 - 15) / original);
$(".squares").height((780 - 17) / original);
$("<div class='squares'></div>").appendTo('#main');
}
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
});
function gridq() {
$('.squares').removeClass('hover');
$('div').remove('.squares');
var newgrid = prompt("How many squares on each side?");
var widthscreen = 192;
if (newgrid > 0) {
for (var x = 0; x < newgrid * newgrid; x++) {
$(".squares").width(widthscreen / newgrid);
$(".squares").height(widthscreen / newgrid);
$("<div class='squares'></div>").appendTo('#main');
}
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
}
}
#main {
height: 780px;
width: 780px;
background-color: antiquewhite;
position: relative;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id=main>
</div>
<button onclick="gridq()">Go Again!</button>
Try this snippet? Grid initialisation is set in the grid() function and then called later when necessary. The width is set dynamically to the 16th square's right side.and the remaining squares fill out as necessary.
var wide = (780 - 15) / 16,
tall = (780 - 17) / 16; // set the square dimensions. this can be incorporated into the grid() function with 16 replaced by 'original'
function grid(x, y) {
var original = x,
y = y;
$("#main").empty(); // empty and restart
$("#main").width(wide * (original + 1));
for (var i = 0; i < original * y; i++) {
$("<div class='squares'></div>").appendTo('#main');
}
var square = $(".squares");
square.width(wide);
square.height(tall);
var side = square.eq(original - 1).position().left + square.width() + 2; // tighten the #main width
$("#main").width(side);
$('.squares').hover(
function() {
$(this).addClass('hover');
}
)
}
grid(16, 16); // starting dimension
function gridq() {
$('.squares').removeClass('hover');
$('div').remove('.squares');
var newgrid = prompt("How many squares on each side?");
var widthscreen = 192;
if (newgrid > 0) {
grid(newgrid, newgrid);
}
}
#main {
background-color: antiquewhite;
position: relative;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id='main'>
</div>
<button onclick="gridq()">Go Again!</button>
just got beat to it...ill post this as it answers the question slightly differently and I feel is a little cleaner. Also I added in a width and a height prompt.
see the codepen here
As a side note...its good practice to make the names of your variables make sense. Also I find that breaking down your code problems into smaller more manageable chunks makes it seem less overwhelming...one step at a time :)
Enjoy and good luck!
$(document).ready(function() {
//declare the variables at the top of your functions...it enables us to change them later
var columnWidthCount = 16;
var columnHeightCount = 16;
function makeBoxes() {
//boxcount lets us set how many times we want the for loop to run...when we change the columns/rows later this variable will be updated
var boxCount = columnWidthCount * columnHeightCount;
//
for (var i = 0; i < boxCount; i++) { //loop through each box
//any code you place in here will execute each time we loop around
$("<div class='squares'></div>").appendTo('#main');
}
//we only want to declare this once so we place it after the loop
$(".squares").width((780 / columnWidthCount) - 2);
$(".squares").height((780 / columnHeightCount) - 2);
$('.squares').hover(
function() {
$(this).addClass('hover');
}
);
}
//fire the initial function
makeBoxes();
// fire function after click
$('button').on("click", function() {
$('div').remove('.squares');
var squaresHigh = prompt("How many squares high? (must be a number)");
var squaresWide = prompt("How many squares wide? (must be a number)");
//prompt returns a string...use parseInt to turn that number string into an integer
columnWidthCount = parseInt(squaresWide);
columnHeightCount = parseInt(squaresHigh);
makeBoxes();
});
});
#main {
height: 780px;
width: 780px;
background-color: antiquewhite;
position: relative;
font-size:0;
white-space:nowrap;
}
.squares {
margin: 1px;
padding: 0;
background-color: aquamarine;
display: inline-block;
float: left;
}
.hover {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id=main>
</div>
<button>Go Again!</button>