why grid cells wont go below 32px width and height? - javascript

im trying to make static grid with a button that can change number of boxes in it (from 16x16 to 64x64 and anything between). Grid is 40rem x 40rem, when i try to change manually number of boxes in makeGrid() function it works fine up to 20 (boxes change size accordingly), but anything above 20 stays the same size and gets cutoff from my grid. If there is no grid css overflow property stated, grid width change depending on number of boxes but boxes themself won't shrink
my code:
size button is not working yet, grid size need to be changed mannualy in makeGrid function
const grid = document.getElementById('grid');
const size = document.getElementById('size');
const eraser = document.getElementById('eraser');
const color = document.getElementById('color');
const gridBorder = document.getElementById('grid-borders');
const clear = document.getElementById('clear');
// grid
function makeGrid(number) {
number = number || 16;
let cellWidth = 40 / number + 'rem';
let cellHeight = 40 / number + 'rem';
grid.style.gridTemplateColumns = `repeat( ${number}, 1fr)`;
grid.style.gridTemplateRows = `repeat(${number}, 1fr)`;
for (let i = 0; i < number * number; i++) {
let cell = document.createElement('div');
grid.appendChild(cell).id = 'box';
cell.classList.add('border');
cell.classList.add('box');
cell.style.backgroundColor = 'white';
cell.style.width = cellWidth;
cell.style.height = cellHeight;
}
size.textContent = `${number} x ${number}`;
}
makeGrid();
// drawing on hover
color.addEventListener('click', function () {
grid.addEventListener('mouseover', function (e) {
e.target !== grid ? (e.target.style.backgroundColor = 'black') : null;
});
});
function changeColor(event) {
event.target.style.backgroundColor = 'black';
}
// erase functionality
eraser.addEventListener('click', function () {
grid.addEventListener('mouseover', function (e) {
e.target !== grid ? (e.target.style.backgroundColor = 'white') : null;
});
});
// grid borders
const allBoxes = document.querySelectorAll('.box');
gridBorder.addEventListener('click', function () {
allBoxes.forEach((box) => {
box.classList.toggle('no-border');
box.classList.toggle('border');
});
});
// clear button
clear.addEventListener('click', function () {
allBoxes.forEach((box) => {
box.style.backgroundColor = 'white';
});
});
// size button
// size.addEventListener('click', function () {
// let number = prompt(`Enter grid size less or equal to 100`);
// if (number !== Number.isInteger()) {
// return;
// } else if (number > 100) {
// number = prompt(`Enter grid size greater or equal to 100`);
// }
// });
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background-color: aquamarine;
}
#grid {
display: grid;
justify-content: center;
border: 1px solid #ccc;
width: 40rem;
height: 40rem;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.box {
padding: 1em;
}
#title {
display: flex;
align-items: flex-end;
justify-content: center;
height: 180px;
}
#container {
display: flex;
height: 60%;
width: 1259px;
align-items: flex-start;
justify-content: flex-end;
gap: 20px;
padding-top: 20px;
}
#menu {
display: flex;
flex-direction: column;
gap: 10px;
}
.border {
outline: 1px solid black;
}
.no-border {
outline: none;
}
.black-bg {
background: black;
}
.white-bg {
background: white;
}
<!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>Etch-a-Sketch</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div id="title">
<h1>Etch-a-Sketch</h1>
</div>
<main id="container">
<div id="menu">
<button id="size"></button>
<button id="color">Color</button>
<button id="eraser">Eraser</button>
<button id="clear">Clear</button>
<button id="grid-borders">Grid Borders</button>
</div>
<div id="grid"></div>
</main>
</body>
</html>

"Why won't my grid cells go below 32px?" - have you checked your padding (hint: 32px is exactly equal to 2 * 16px which in turn is exactly equal to your padding of 1em with most browsers implementing a default font-size of 16px). –
David Thomas
box padding was set to 1em which caused my problem, after deleting it my grid worked as intended

Related

Why does my anime.js animation's not working everytime?

I got a problem with Anime.js, I got a project to do about a game with a dice and 2 players on the same screen. I would like to animate the background color and position depending on the active player (left or right). So I've made a div with a background, a negative z-index and a width of 50vw so it takes half of the screen. I placed the animation play() and reverse() into my switchPlayer function. My problem is that the background animation makes one "dead time" beetween 2 switch of player and I don't understand why.
Thanks for the help !
Here is my html
<!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">
<link rel="stylesheet" href="style.css">
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> -->
<title>Dice Game</title>
</head>
<body>
<div id="player-background"></div>
<!-- This is whre the whole game is contained -->
<div class="gameContainer">
<!-- Player one content -->
<div id="player1">
<h2>PLAYER 1</h2>
<span class="score" id="globalP1">0</span>
<div class="current">
<span class="cText">Current :</span>
<span id="roundP1">0</span>
</div>
</div>
<!-- Center content -->
<div id="center">
<button class="NewGame" id="new-game" type="button">NEW GAME</button>
<img alt="Dice" id="img" src="./images/1.png">
<button class="roll-dice" id="roll" type="button">ROLL DICE !</button>
<button id="hold" type="button">HOLD</button>
</div>
<!-- Player two content -->
<div id="player2">
<h2>PLAYER 2</h2>
<span class="score" id="globalP2">0</span>
<div class="current">
<span class="cText">Current :</span>
<span id="roundP2">0</span>
</div>
</div>
</div>
<script src="./node_modules/animejs/lib/anime.min.js"></script>
<script src="./script.js"></script>
</body>
</html>
My css
#import url('https://fonts.googleapis.com/css2?family=Lato:wght#300;400&display=swap');
body {
margin: 0px;
overflow: hidden;
font-family: 'Lato', sans-serif;
/* background-image: url(images/GameBackground.png);
background-size: cover;
background-position: center; */
}
img {
height: 300px;
width: 300px;
padding: 200px 0px 150px 0px;
}
button {
background: none;
border: 0;
font-size: 50px;
}
.roll-dice {
padding-bottom: 25px;
}
.gameContainer {
display: flex;
justify-content: space-around;
align-items: center;
align-content: center;
height: 100vh;
width: 100vw;
z-index: 5;
}
#player-background {
position: absolute;
height: 100vh;
width: 50vw;
background: paleturquoise;
z-index: -5;
}
#player1, #player2, #center {
font-size: 50px;
font-weight: 300;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.score {
color: red;
font-size: 100px;
font-weight: 300;
display: flex;
margin-bottom: 250px;
}
.cText {
font-size: 30px;
}
.current {
display: flex;
align-items: center;
justify-content: space-evenly;
background: rgb(226, 226, 187);
height: 125px;
width: 350px;
}
And my JS
//------------------------ Get element variables ---------------
let newGame = document.getElementById("new-game");
let roll = document.getElementById("roll");
let hold = document.getElementById("hold");
let img = document.getElementById("img");
let globalP1 = document.getElementById("globalP1");
let roundP1 = document.getElementById("roundP1");
let globalP2 = document.getElementById("globalP2");
let roundP2 = document.getElementById("roundP2");
let backgroundTarget = document.getElementById("player-background");
//----------------------- Game variables ---------------
let activePlayer = 1;
//----------------------------Anime JS---------------------
let background = anime({
targets: backgroundTarget,
translateX: "50vw",
autoplay: false,
backgroundColor: "#676790",
});
//------------------ Functions used later ---------------
// Switch the player display depending on the situation
function switchPlayer() {
if (activePlayer == 1) {
background.reverse();
player1.style.opacity = "1";
player2.style.opacity = "0.3";
} else {
background.play();
player1.style.opacity = "0.3";
player2.style.opacity = "1";
}
}
let gameReset = () => {
// rewrite everything to "0"
roundP1.textContent = "0";
globalP1.textContent = "0";
roundP2.textContent = "0";
globalP2.textContent = "0";
// Force player one display
activePlayer = 1;
switchPlayer();
};
//--------------------- Main functions ----------------------
// Roll logic
let rollfunction = () => {
// Generates a random number between 1 to 6
let diceNumber = Math.floor(Math.random() * 6) + 1;
// Generate a string with the img path, including a random number between then display the img
let randomImg = "images/" + diceNumber + ".png";
// Used to get the img element then set the src attribute to randomImg (= images/1.png or any other numbers)
document.querySelector("img").setAttribute("src", randomImg);
if (activePlayer == 1 && diceNumber > 1) {
roll.textContent = "ROLL DICE !";
// puts the number into the current score
let totalCurrentP1 = roundP1.textContent;
// I had to put a "+" to make the addition possible beacause rounsP2.textContent is a string, the + is here to convert a string into a number
roundP1.textContent = +totalCurrentP1 + +diceNumber;
switchPlayer();
} else if (activePlayer == 1 && diceNumber == 1) {
// Switch player if dice = 1
roll.textContent = "NEXT PLAYER";
roundP1.textContent = "0";
activePlayer = activePlayer + 1;
switchPlayer();
} else if (activePlayer == 2 && diceNumber > 1) {
// Put score into P2 section
roll.textContent = "ROLL DICE !";
let totalCurrentP2 = roundP2.textContent;
roundP2.textContent = +totalCurrentP2 + +diceNumber;
} else {
// Switch to player 1 if player 2 get "1"
roundP2.textContent = "0";
roll.textContent = "NEXT PLAYER";
activePlayer = activePlayer - 1;
}
};
// Hold ogic
let holdFunction = () => {
let totalGlobalP1 = globalP1.textContent;
let totalGlobalP2 = globalP2.textContent;
let numberRoundP1 = roundP1.textContent;
let numberRoundP2 = roundP2.textContent;
if (activePlayer == 1 && +totalGlobalP1 + +numberRoundP1 < 100) {
globalP1.textContent = +totalGlobalP1 + +roundP1.textContent;
roundP1.textContent = "0";
activePlayer = 2;
switchPlayer();
// background.play();
} else if (activePlayer == 1 && +totalGlobalP1 + +numberRoundP1 >= 100) {
activePlayer = 1;
alert("P1 t'as gagné mon pote !");
gameReset();
// background.reverse();
} else if (activePlayer == 2 && +totalGlobalP2 + +numberRoundP2 < 100) {
globalP2.textContent = +totalGlobalP2 + +roundP2.textContent;
roundP2.textContent = "0";
activePlayer = 1;
switchPlayer();
// background.reverse();
} else if (activePlayer == 2 && +totalGlobalP2 + +numberRoundP2 >= 100) {
activePlayer = 2;
alert(
"Le joueur 2 a gagné cette manche ! (De toute façon c'était mon préféré"
);
gameReset();
}
};
//--------------------- Buttons ----------------------------
// Every buttons holding every functions
hold.addEventListener("click", () => {
holdFunction();
});
roll.addEventListener("click", () => {
rollfunction();
});
newGame.addEventListener("click", () => {
gameReset();
});
Tried :
Looked on stack overflow to see if someone else had this problem
Tried to look more in depth into the anime.js doc
Also tried to do a blank project only with this function but still this issue
Expecting :
Move the div left and right depending on the active player to see who's playing

Why is my cursor and my line of draw are in diffrent sides?

I am attempting to create a drawing app in JS, however, whenever anything is drawn, it is positioned away from my cursor depending on where it is on the canvas, when I am on the furthest left/bottom side of the canvas, you can draw where your cursor is, but the further right/up I move, the more the brush begins to "drift" and go further than where my cursor is.
const canvas = document.getElementById("canvas");
const increaseBtn = document.getElementById("increase");
const decreaseBtn = document.getElementById("decrease");
const sizeEl = document.getElementById("size");
const colorEl = document.getElementById("color");
const clearEl = document.getElementById("clear");
//Core Drawing Functionality (with some research)
const ctx = canvas.getContext("2d");
let size = 5;
let isPressed = false;
let color = "black";
let x;
let y;
let fakeSize = 1;
canvas.addEventListener("mousedown", (e) => {
isPressed = true;
x = e.offsetX;
y = e.offsetY;
});
canvas.addEventListener("mouseup", (e) => {
isPressed = false;
x = undefined;
y = undefined;
});
canvas.addEventListener("mousemove", (e) => {
if (isPressed) {
const x2 = e.offsetX;
const y2 = e.offsetY;
drawCircle(x2, y2);
drawLine(x, y, x2, y2);
x = x2;
y = y2;
}
});
function drawCircle(x, y) {
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
}
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = color;
ctx.lineWidth = size * 2;
ctx.stroke();
}
function updateSizeOnScreen() {
sizeEl.innerHTML = fakeSize;
}
increaseBtn.addEventListener("click", () => {
size += 5;
fakeSize++;
if (fakeSize > 10) {
fakeSize = 10;
}
if (size > 50) {
size = 50;
}
updateSizeOnScreen();
});
decreaseBtn.addEventListener("click", () => {
size -= 5;
fakeSize--;
if (fakeSize < 1) {
fakeSize = 1;
}
if (size < 5) {
size = 5;
}
updateSizeOnScreen();
});
colorEl.addEventListener("change", (e) => {
color = e.target.value;
});
clearEl.addEventListener("click", () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
//Eraser and Pencil Actions (my own algorithm)
const eraser = document.getElementById("eraser");
const pencil = document.getElementById("pencil");
eraser.addEventListener("click", () => {
localStorage.setItem("colorEl", JSON.stringify(color));
color = "#fff";
colorEl.disabled = true;
canvas.classList.add("eraseractive");
eraser.classList.add("eraseractive");
colorEl.classList.add("eraseractive");
canvas.classList.remove("pencilactive");
eraser.classList.remove("pencilactive");
colorEl.classList.remove("pencilactive");
});
pencil.addEventListener("click", () => {
JSON.parse(localStorage.getItem("colorEl"));
color = colorEl.value;
colorEl.disabled = false;
canvas.classList.remove("eraseractive");
eraser.classList.remove("eraseractive");
colorEl.classList.remove("eraseractive");
canvas.classList.add("pencilactive");
eraser.classList.add("pencilactive");
colorEl.classList.add("pencilactive");
});
// Dark/Light Mode
const darkMode = document.getElementById("darkMode");
const lightMode = document.getElementById("lightMode");
const toolbox = document.getElementById("toolbox");
darkMode.addEventListener("click", () => {
darkMode.classList.add("mode-active");
lightMode.classList.remove("mode-active");
lightMode.classList.add("rotate");
darkMode.classList.remove("rotate");
toolbox.style.backgroundColor = "#293462";
document.body.style.backgroundImage =
"url('/assets/images/darkModeBackground.svg')";
document.body.style.backgroundSize = "1920px 1080px";
canvas.style.borderColor = "#293462";
toolbox.style.borderColor = "#293462";
});
lightMode.addEventListener("click", () => {
lightMode.classList.add("mode-active");
darkMode.classList.remove("mode-active");
darkMode.classList.add("rotate");
lightMode.classList.remove("rotate");
toolbox.style.backgroundColor = "#293462";
document.body.style.backgroundImage =
"url('/assets/images/lightModeBackground.svg')";
document.body.style.backgroundSize = "1920px 1080px";
canvas.style.borderColor = "#293462";
toolbox.style.borderColor = "#293462";
});
* {
box-sizing: border-box;
font-size: 20px !important;
}
body {
background: url("https://drawing-app-green.vercel.app/assets/images/lightModeBackground.svg");
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
margin: 0;
position: relative;
max-height: 100vh;
overflow: hidden;
}
::selection {
background: transparent;
}
::-moz-selection {
background: transparent;
}
.mode {
display: flex;
position: absolute;
top: 10px;
right: 25px;
cursor: pointer;
}
.light-mode {
color: yellow;
}
.dark-mode {
color: #16213e;
}
.container {
display: flex;
flex-direction: column;
max-width: 1200px;
width: 100%;
max-height: 600px;
height: 100%;
}
canvas {
display: flex;
border: 2px solid #293462;
cursor: url("https://drawing-app-green.vercel.app/assets/images/pencilCursor.png") 2 48, pointer;
background-color: #fff;
margin-top: 3rem;
width: 100%;
height: 600px;
}
.toolbox {
background-color: #293462;
border: 1px solid #293462;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
padding: 0.2rem;
}
.toolbox > * {
background-color: #fff;
border: none;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 2rem;
height: 30px;
width: 30px;
margin: 0.25rem;
padding: 0.25rem;
cursor: pointer;
}
.toolbox > *:last-child {
margin-left: auto;
}
canvas.eraseractive {
cursor: url("https://drawing-app-green.vercel.app/assets/images/eraserCursor.png") 2 48, pointer;
}
#color.eraseractive {
cursor: not-allowed;
}
canvas.pencilactive {
cursor: url("https://drawing-app-green.vercel.app/assets/images/pencilCursor.png") 2 48, pointer;
}
.mode-active {
visibility: hidden;
}
.rotate {
transform: rotate(360deg);
transition: transform 1s linear;
}
<!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>Drawing App</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"
integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
</head>
<body>
<i class="fa-solid fa-moon dark-mode fa-2x mode" id="darkMode"></i>
<i
class="fa-solid fa-sun light-mode fa-2x mode mode-active"
id="lightMode"
></i>
<div class="container">
<canvas id="canvas" width="1024" height="600"></canvas>
<div class="toolbox" id="toolbox">
<button id="decrease">-</button>
<span id="size">1</span>
<button id="increase">+</button>
<input type="color" id="color" />
<button id="pencil">
<img src="assets/images/pencilCursor.png" alt="" />
</button>
<button id="eraser">
<img src="assets/images/eraserCursor.png" alt="" />
</button>
<button id="clear">X</button>
</div>
</div>
<script src="assets/js/script.js"></script>
</body>
</html>
Your problem is that your canvas dimentions don't match with the dimentions of the HTML element that contains it. You see: your canvas has a fixed width="" and height="" attributes set. But in your HTML your canvas element has a width of 100%. So that means that the container vairies in dimentions but the canvas inside it not. This result in the canvas trying to resize to show inside the container thus giving you issues with calculating exacly what pixel you are clicking.
You have two options:
Option 1: calculate your click position taking into account canvas deformation
If you want your canvas to resize, then calculate the real position using a simple ratio formula. If for example your canvas has a width of 100 but right now its container is 10px wide, then if you click on pixel 5 you expect a dot to be drawn at pixel 50. In other words if your canvas is smaller by a factor of 10 then you need to multiply your position by a factor of 10.
In your code it would look something like this:
// this is your same code in lines 33 ana34 but see that I added a multiplication by the ratio between the canvas size and the canvas container
const x2 = e.offsetX * (canvas.width / ctx.canvas.getBoundingClientRect().width);
const y2 = e.offsetY * (canvas.height / ctx.canvas.getBoundingClientRect().height);
Option #2: Dont allow your canvas to deform
Remove the container class, and remove the width:100% from your canvas css. Your canvas will overflow and cause a scrollbar but the positions will be calculated properly with your code.

how can I let 3 div elements being resizable

what I want to see the result is 2 set of split view screen (or more), one is vertical, one is horizontal, but in the same javascript file. If it's possible to do in a single JavaScript file will be good
I tried to use this one to make it but it seems like not how to make that.
Here's the code I'm trying to make two div elements and its vertical
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>my app</title>
<style>
.container {
width: 202px;
height: 406px;
border: 1px solid black;
display: flex;
flex-direction: column;
}
.top {
width: 200px;
height: 200px;
border: 1px solid red;
min-height: 100px;
}
.resizer {
width: 202px;
height: 2px;
background-color: green;
}
.resizer:hover {
cursor: ns-resize;
}
.bottom {
width: 200px;
height: 200px;
border: 1px solid blue;
flex: 1 1 0%;
min-height: 100px;
}
</style>
</head>
<body>
<div class="container">
<div class="top" id="top">
something here
</div>
<div class="resizer" id="resizer"></div>
<div class="bottom" id="bottom">
something too
</div>
</div>
<script>
const resizer = document.getElementById('resizer');
const topSection = document.getElementById('top');
const bottomSection = document.getElementById('bottom');
let x = 0;
let y = 0;
let topSectionHeight = 0;
const mouseDownHandler = function (e) {
x = e.clientX;
y = e.clientY;
topSectionHeight = topSection.getBoundingClientRect().height;
document.addEventListener('mousemove', mouseMoveHandler);
document.addEventListener('mouseup', mouseUpHandler);
}
resizer.addEventListener('mousedown', mouseDownHandler);
const mouseMoveHandler = function (e) {
const dx = e.clientX - x;
const dy = e.clientY - y;
const newtopSectionHeight = ((topSectionHeight + dy) * 100) / resizer.parentNode.getBoundingClientRect().height;
topSection.style.height = `${newtopSectionHeight}%`;
resizer.style.cursor = 'ns-resize';
document.body.style.cursor = 'ns-resize';
topSection.style.userSelect = 'none';
topSection.style.pointerEvents = 'none';
bottomSection.style.userSelect = 'none';
bottomSection.style.pointerEvents = 'none';
}
const mouseUpHandler = function () {
resizer.style.removeProperty('cursor');
document.body.style.removeProperty('cursor');
actionBasic.style.removeProperty('user-select');
actionBasic.style.removeProperty('pointer-events');
bottomSection.style.removeProperty('user-select');
bottomSection.style.removeProperty('pointer-events');
document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
}
</script>
</body>
</html>
thank you for reading so far, please help me if you're able to! If any information is needed, please tell me below and I'll provide it as soon as possible.

How can you force nested flexboxes to fill a desired space?

var tag = document.createElement("div");
var element = document.getElementById("container");
for(let i = 1; i<17; i++){
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for(let j = 1; j<17; j++){
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
elements.appendChild(tags)
elements.removeAttribute("id")
//console.log(elements)
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
//console.log(selectedCell.getAttribute('parent'))
//console.log(typeof selectedCell.getAttribute('parent'))
if(typeof selectedCell.getAttribute('parent') === 'string'){
selectedCell.setAttribute('selected', 'true')
//console.log(selectedCell)
}
})
#container {
display: flex;
flex-wrap: wrap;
align-items: baseline;
align-content: stretch;
height: 960px;
width: 960px;
}
div[tag]{
display: flex;
flex-direction: row;
height: 60px;
width: 100%;
flex-grow: 1;
}
[tag] > [id]{
display: flex;
height: 60px;
flex-direction: row;
flex-grow: 1;
}
div[selected]{
background-color: black;
}
<!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>Document</title>
<link rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div id="container">
</div>
<script src = "app.js"></script>
</body>
</html>
I am currently on the tail end of the introductory front-end course from OdinProject, however, I am stuck on the etch-a-sketch assignment. The CSS (located below) will only fill out properly if I set a fixed height in pixels.
div#container {
border-color: red;
height: 960px;
width: 960px;
flex-direction: row;
}
div[tag*="parent"]{
display: flex;
flex-direction: row;
height: auto;
width: 100%;
flex-grow: 1;
}
div[cell*="yes"]{
display: flex;
height: auto;
flex-direction: row;
flex-grow: 1;
}
div[selected]{
background-color: black;
}
If I set the height to auto (as present in the current styling), the width is fine, which is 960 pixels, but the height of the rows and the cells will be 0 pixels. Setting the height as a fixed height is okay in this scenario which is a 16x16 etch-a-sketch, however, I am planning to allow the user to select the number of cells, which would require the height to be dynamic. I have tried everything and nothing seems to work. This is my first question here, so I don't know if you will require the other code, so I will just paste it below.
var tag = document.createElement("div");
var element = document.getElementById("container");
for(let i = 1; i<17; i++){
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for(let j = 1; j<17; j++){
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
elements.appendChild(tags)
elements.removeAttribute("id")
console.log(elements)
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
//console.log(selectedCell.getAttribute('parent'))
console.log(typeof selectedCell.getAttribute('parent'))
if(typeof selectedCell.getAttribute('parent') === 'string'){
selectedCell.setAttribute('selected', 'true')
console.log(selectedCell)
}
})
<!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>Document</title>
<link rel="stylesheet" href="stylesheet.css">
</head>
<body>
<div id="container">
</div>
<script src = "app.js"></script>
</body>
</html>
I changed the height and width on div#container to 100vh and 100vw. This is so that the container fills the whole viewport, which is what you want as I understand.
I removed the height:auto on the parent and cell classes and I also removed width:100%
I created a variable called gridSize with let. I replaced the 17 with this variable gridSize in the two loops and I added the following to calculate the height of the cell:
let cellHeight = Math.floor((100 / gridSize) * 1000) / 1000 + "vh";
And, then I set the height of the cell dynamically with:
tags.style.height = gridSize
which effectively is the same as:
tags.style.height = "10vh" // if gridSize is 10
tags.style.height = "5vh" // if gridSize is 20
You should be able to implement the functionality to allow the user to dynamically select the grid size. This demo should show you the way forward.
var tag = document.createElement("div");
var element = document.getElementById("container");
let gridSize = 17;
let cellHeight = Math.floor((100 / gridSize) * 1000) / 1000 + "vh";
for (let i = 1; i < gridSize; i++) {
var tag = document.createElement("div");
tag.setAttribute('id', `row`)
tag.setAttribute('tag', `parent`)
element.appendChild(tag);
var elements = document.getElementById(`row`)
for (let j = 1; j < gridSize; j++) {
var tags = document.createElement("div");
tags.setAttribute('id', `${j}`)
tags.setAttribute('cell', `yes`)
tags.setAttribute('parent', `${i}`)
tags.style.height = cellHeight;
elements.appendChild(tags)
elements.removeAttribute("id")
}
}
var cells = document.querySelectorAll('parent')
addEventListener('mouseover', function(e) {
const selectedCell = e.path[0]
if (typeof selectedCell.getAttribute('parent') === 'string') {
selectedCell.setAttribute('selected', 'true')
}
})
div#container {
border-color: red;
height: 100vh;
width: 100vw;
flex-direction: row;
}
div[tag*="parent"] {
display: flex;
flex-direction: row;
flex-grow: 1;
}
div[cell*="yes"] {
display: flex;
flex-direction: row;
flex-grow: 1;
}
div[selected] {
background-color: black;
}
<div id="container"></div>

How to make the button to clear up the sketch?

I'm doing a project to make an etch-a-sketch every time I hover on the grid. What I'm trying to do is to make a button to clear up all the colors made.
The sketch picture.
I guess what I need to do is to remove the style elements while clicking the button. But I'm just note sure how to link the button with the style elements.
const container = document.querySelector(".container");
// const table = document.createElement('div');
// table.classList.add('grid-square');
// table.textContent = 'hello';
// container.appendChild(table);
function makeTable(rows, cols) {
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (i = 0; i < (rows * cols); i++){
const cell = document.createElement('div');
// cell.innerText = (i + 1);
container.appendChild(cell).className = "table";
};
};
makeTable(16, 16);
// const container = document.querySelector('.container')
const grids = document.querySelectorAll('.table')
grids.forEach(element => {
element.addEventListener('mouseover', (e) => {
e.target.style.backgroundColor = randomColor();
console.log(e)
})
});
function randomColor() {
var generateColor = '#' + Math.floor(Math.random()*16777215).toString(16);
return generateColor;
}
function resizeGrid() {
sketchSize = prompt("Enter 1 to 100 to resize sketch");
return sketchSize;
}
// const button = document.querySelector('button')
// button.addEventListener('click', (e) => {
// });
:root {
--grid-rows: 1;
--grid-cols: 1;
}
.container {
display: grid;
/* grid-gap: 1em; */
grid-template-rows: repeat(var(--grid-rows), 1fr);
grid-template-columns: repeat(var(--grid-cols), 1fr);
/* border: 1px solid black; */
width: 50%;
size: 960px;
}
.table {
padding: 1em;
border: 1px solid coral;
text-align: center;
/* border: none; */
}
header {
display: flex;
justify-content: center;
margin: 20px;
gap: 10px;
}
<!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>Etch-A-Sketch</title>
<script src="index.js" defer></script>
<link rel="stylesheet" href="index.css">
</head>
<body>
<header>
<button class="clear-button">Clear</button>
<button class="resize">Resize</button>
</header>
<div class="container"></div>
</body>
</html>
Cheers!!
To answer my own question, I figured how to do it.
const clear = document.querySelector('.clear-button')
clear.addEventListener('click', () => {
grids.forEach(element => {
element.style.backgroundColor = null;
})
})
I was struggling earlier because I'm not sure how to put other elements (e.g. grids) to the new eventListener.

Categories

Resources