I made a little 15 puzzle which I want to be shuffled in the beginning. I start from the completed state and do 1000 random "fakeClicks" on tiles of which some are valid according to my code and most are not. The valid "fakeClicks" cause the emptyTile and the selectedTile to swap their positions by swaping their top and left values.
Everything (except the checkCompleteness() method which does not exist yet) seems to work - until one actually tries to solve the puzzle. With a small n, I reached the unsolvable game situation more than 50 percent of the time.
How is this possible when during shuffling I do valid moves only? Obviously it must be something about my code checking if a move is valid or not:
if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {
(The ^ (xor) is to prevent diagonal moves.)
Does anyone see where the problem is to be found? Or does anyone have a suggestion for a good debugging strategy? After more than an hour of debugging, I am kind of clueless.
var idList = ["t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t0"];
var tileSize = 100;
var init = function() {
// place tiles on the board and add listener
for (var column = 0; column < 4; column++) {
for (var row = 0; row < 4; row++) {
var div = document.querySelector("." + idList[row * 4 + column]);
div.style.top = row * tileSize + "px";
div.style.left = column * tileSize + "px";
if (idList[row * 4 + column] !== "t0") {
div.addEventListener("click", clickListener);
}
}
}
// shuffle tiles
for (i = 0; i < 1000; i++) {
var fakeClick = parseInt(Math.random() * 15);
swapTiles(idList[fakeClick]);
}
};
var clickListener = function(e) {
var selectedTileClass = e.target.classList[1];
swapTiles(selectedTileClass);
//checkCompleteness(); // to be done later
};
var swapTiles = function(selectedTileClass) {
// get empty tile and selected tile
var selectedTile = document.querySelector("." + selectedTileClass);
var selectedX = parseInt(selectedTile.style.left);
var selectedY = parseInt(selectedTile.style.top);
var emptyTile = document.querySelector(".t0");
var emptyX = parseInt(emptyTile.style.left);
var emptyY = parseInt(emptyTile.style.top);
// only swap tiles if selected tile "next to" empty tile
if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {
selectedTile.style.left = emptyX + "px";
selectedTile.style.top = emptyY + "px";
emptyTile.style.left = selectedX + "px";
emptyTile.style.top = selectedY + "px";
}
};
.board {
position: relative;
width: 400px;
height: 400px;
margin: auto;
background-color: firebrick;
border: 2px firebrick solid;
}
.tile {
position: absolute;
width: 100px;
height: 100px;
border: 2px firebrick solid;
box-sizing: border-box;
background-color: orange;
line-height: 100px;
font-size: 2rem;
font-weight: bold;
font-family: Arial, sans-serif;
color: firebrick;
text-align: center;
transition: all .25s linear;
cursor: pointer;
}
.t0 {
position: absolute;
width: 96px;
height: 96px;
margin: 2px;
border: 2px orange solid;
box-sizing: border-box;
pointer-events: none;
transition: all .25s linear;
}
<html>
<meta charset="utf-8">
<head>
<script type="text/javascript" src="js.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body onload="init();">
<div class="wrapper">
<div class="center">
<div class="board">
<div class="tile t1">1</div>
<div class="tile t2">2</div>
<div class="tile t3">3</div>
<div class="tile t4">4</div>
<div class="tile t5">5</div>
<div class="tile t6">6</div>
<div class="tile t7">7</div>
<div class="tile t8">8</div>
<div class="tile t9">9</div>
<div class="tile t10">10</div>
<div class="tile t11">11</div>
<div class="tile t12">12</div>
<div class="tile t13">13</div>
<div class="tile t14">14</div>
<div class="tile t15">15</div>
<div class="t0"></div>
</div>
</div>
</div>
</body>
</html>
You are right, your test is wrong.
Imagine a small board with the selected tile in the center
ooooo
ooooo
ooxoo
ooooo
ooooo
and now look at what the two truth tables of the 2 predicates give depending on where the empty tile is.
ftftf
ftftf
ftxtf
ftftf
ftftf
and
fffff
ttttt
ffxff
ttttt
fffff
mix them with an xor and you get
ftftf
tftft
ftxtf
tftft
ftftf
which means you get the correct response on the "first circle" around the tile, but you get incorrect responses farther from the tile.
Related
I made a basic javascript code so you can poke divs with you mouse.
Unfortunately I have to add them manualy but i wanna add so much of them with a pattern.
First i decided to use grid but i guessed it wont work because divs (which i call them squares from now on :D) can change their position.
So I was about to ask, how can I create a javascript code that i can spawn them until they fill the screen.
Also i have another question which is realted to this project, How can i make these squares just decors. I mean by decors i dont want them to effect the webside at all, when the blocks goes out of the screen the body starts to expend, is there any way to avoid that?
(Also it will be better if you make the snippet full screen!)
EDIT: I put the refresh-button on the top left on the main div so you can draw squares by clicking it!
let mouse = {
speedX: 0,
speedY: 0,
posX: 0,
posY: 0,
movement: 0,
speed: 0
}
//on mousemove update the moouse object
document.onmousemove = function(e) {
mouse.speedX = e.movementX;
mouse.speedY = e.movementY
mouse.posX = e.pageX;
mouse.posY = e.pageY;
}
//refresh the mouse movement and speed every 100ms
setInterval(() => {
mouse.movement =
Math.sqrt(Math.pow(mouse.speedX, 2) + Math.pow(mouse.speedY, 2));
mouse.speed = mouse.movement * 10;
}, 100);
//add a square div in parent element
function addSquare(parent) {
const newDiv = document.createElement("div");
newDiv.classList.add("square")
parent.appendChild(newDiv)
return newDiv;
}
//add squares in the parent element filling the available size
//gap is the space between squares, size is the edge of the square
//if skipbefore is false it will begin to draw the next square also if it won't fit entirely
function addSquares(parent, gap, size, skipbefore = true) {
const squares = [];
let rect = parent.getBoundingClientRect();
const availableWidth = rect.width;
const availableHeight = rect.height;
let top = 100;
while (top < availableHeight) {
let left = 0;
if (skipbefore && top + size > availableHeight)
break;
while (left < availableWidth) {
if (skipbefore && left + size > availableWidth)
break;
const square = addSquare(parent);
square.style.left = `${left}px`;
square.style.top = `${top}px`;
squares.push(square);
left += gap + size;
}
top += gap + size;
}
return squares;
}
//onmoveover event handler
const squareOnMouseOver = (event) => {
const element = event.target;
const y = mouse.speedY;
const x = mouse.speedX;
const rad = Math.atan2(y, x);
yAxis = mouse.movement * Math.sin(rad);
xAxis = mouse.movement * Math.cos(rad);
const rect = element.getBoundingClientRect();
const left = Math.round(rect.x + xAxis * 3);
const top = Math.round(rect.y + yAxis * 3);
element.style.left = `${left}px`;
element.style.top = `${top}px`;
const o = rad * (180 / Math.PI);
element.style.transform = `rotate(${o}deg)`;
}
//resets the .target parent and redraw the squares inside it
function drawSquares() {
const parent = document.querySelector('.target');
parent.innerHTML = '';
const squares = addSquares(parent, 25, 75);
const colors = [
'lightcoral',
'bisque',
'aquamarine',
'cadetblue',
'greenyellow',
'yellowgreen'
];
squares.forEach(square => {
const iColor = Math.floor(Math.random() * (colors.length - 1));
const color = colors[iColor];
square.style.background = color;
square.addEventListener('mouseover', squareOnMouseOver);
});
}
body{
margin: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: rgb(242, 239, 231);
color: rgb(10, 10, 9);
}
.square{
background-color: lightcoral;
width: 75px;
height: 75px;
position: absolute;
transform: rotate(0deg);
transition: all ease-out 0.5s;
}
.background {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.container .row .col > * {
display: inline-block;
}
.target {
display: block;
width: 100%;
height: 100%;
}
#draw {
font-size: 20px;
padding: .2em 1em;
cursor: pointer;
}
.name{
font-size: 40px;
}
#main-container{
position: absolute;
padding: 35px 45px;
width: 950px;
height: 285px;
box-shadow: 0px 2px 5px 2px rgb(191, 188, 182);
}
.links{
display: flex;
justify-content: center;
align-items: center;
}
.icons{
width: 55px;
height: auto;
margin: 0px 25px;
padding: 10px;
border-radius: 5px;
transition: all ease-in 0.2s;
}
.icons:hover{
background-color: rgb(144, 144, 144);
}
.refresh{
position: absolute;
}
.refresh-button{
width: 25px;
height: auto;
}
.btn:hover{
background-color: rgb(144, 144, 144);
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="css.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>
<div class="background">
<div class="target"></div>
<div class="container text-center" id="main-container">
<div class="">
<div class="refresh">
<button class="btn" id="draw" onclick="drawSquares()"><img class="refresh-button" src="SVG/arrow-clockwise.svg"></button>
</div>
<div class="name">Berk Efe Keskin</div>
<br>
<i>This website is working in progress right now...</i>
<br>
<i>Here is some useful links.</i>
<br>
<br>
<div class="links">
<img class="icons" src="SVG/github.svg">
<img class="icons" src="SVG/linkedin.svg">
<img class="icons" src="SVG/stack-overflow.svg">
</div>
</div>
</div>
</div>
<script type="text/javascript" src = "javascript.js"></script>
</body>
</html>
You may have a function that given a container will be filled with how many squares can fit inside as long as there is still avaiable width and available height in the target.
Here in this demo I better factored your code and added a main function called drawSquares that gets called when the button reDRAW is clicked. Each time the squares are redrawn, the target content is emptied.
I'm using a button to trigger the box drawing because the available space depends on the size of the area when the action is fired. For example you can expand the snippet and decide to redraw the squares to have the whole new area filled again.
You may decide to call the action on document ready or when the window gets resized.
let mouse = {
speedX: 0,
speedY: 0,
posX: 0,
posY: 0,
movement: 0,
speed: 0
}
//on mousemove update the moouse object
document.onmousemove = function(e) {
mouse.speedX = e.movementX;
mouse.speedY = e.movementY
mouse.posX = e.pageX;
mouse.posY = e.pageY;
}
//refresh the mouse movement and speed every 100ms
setInterval(() => {
mouse.movement =
Math.sqrt(Math.pow(mouse.speedX, 2) + Math.pow(mouse.speedY, 2));
mouse.speed = mouse.movement * 10;
}, 100);
//add a square div in parent element
function addSquare(parent) {
const newDiv = document.createElement("div");
newDiv.classList.add("square")
parent.appendChild(newDiv)
return newDiv;
}
//add squares in the parent element filling the available size
//gap is the space between squares, size is the edge of the square
//if skipbefore is false it will begin to draw the next square also if it won't fit entirely
function addSquares(parent, gap, size, skipbefore = true) {
const squares = [];
let rect = parent.getBoundingClientRect();
const availableWidth = rect.width;
const availableHeight = rect.height;
let top = 100;
while (top < availableHeight) {
let left = 0;
if (skipbefore && top + size > availableHeight)
break;
while (left < availableWidth) {
if (skipbefore && left + size > availableWidth)
break;
const square = addSquare(parent);
square.style.left = `${left}px`;
square.style.top = `${top}px`;
squares.push(square);
left += gap + size;
}
top += gap + size;
}
return squares;
}
//onmoveover event handler
const squareOnMouseOver = (event) => {
const element = event.target;
const y = mouse.speedY;
const x = mouse.speedX;
const rad = Math.atan2(y, x);
yAxis = mouse.movement * Math.sin(rad);
xAxis = mouse.movement * Math.cos(rad);
const rect = element.getBoundingClientRect();
const left = Math.round(rect.x + xAxis * 3);
const top = Math.round(rect.y + yAxis * 3);
element.style.left = `${left}px`;
element.style.top = `${top}px`;
const o = rad * (180 / Math.PI);
element.style.transform = `rotate(${o}deg)`;
}
//resets the .target parent and redraw the squares inside it
function drawSquares() {
const parent = document.querySelector('.target');
parent.innerHTML = '';
const squares = addSquares(parent, 25, 75);
const colors = [
'lightcoral',
'bisque',
'aquamarine',
'cadetblue',
'greenyellow',
'yellowgreen'
];
squares.forEach(square => {
const iColor = Math.floor(Math.random() * (colors.length - 1));
const color = colors[iColor];
square.style.background = color;
square.addEventListener('mouseover', squareOnMouseOver);
});
}
body {
margin: 0;
width: 100vw;
height: 100vh;
display: flex;
}
.square {
background-color: lightcoral;
width: 75px;
height: 75px;
position: absolute;
transform: rotate(0deg);
transition: all ease-out 0.5s;
}
#Header {
font-size: italic;
}
.background {
width: 100%;
height: 100%;
}
.target {
position: relative;
display: block;
width: 100%;
height: 100%;
z-index: -1;
}
#draw {
font-size: 20px;
padding: .2em 1em;
cursor: pointer;
}
.container .row .col > * {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link el="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<body>
<div class="background">
<span>Work in progress...</span>
<div class="container text-center">
<div class="row">
<div class="col">
<h1 id="Header">Work in progress...</h1>
<button id="draw" onclick="drawSquares()">reDRAW</button>
</div>
</div>
</div>
<div class="target"></div>
</div>
</body>
I'm doing another image zoom project and again have encountered the same error where it states it "expected an assignment or function call and instead saw an expression"in the very last line in JS code. In addition, I have received an error in codepen stating that I am missing a semicolon even though there is a semicolon (unless I'm to put it somewhere else?) Help in resolving this issue would be greatly appreciated!
It is a bit disheartening that I encountered same error twice and twice, I am unable to resolve it on my own. I would also love to hear on what I can do to resolve issues like this and anything similar on my own.
Note:
I haven't added my code for the event listeners in the snippet.
// VARIABLES
const mainPic = document.querySelector("#pic");
const mainPicContainer = document.querySelector("#mainPictureContainer");
const pic1 = document.querySelector("#pic1");
const pic2 = document.querySelector("#pic2");
const pic3 = document.querySelector("#pic3");
const pic4 = document.querySelector("#pic4");
const pic5 = document.querySelector("#pic5");
const picArr = [
pic1,
pic2,
pic3,
pic4,
pic5
];
let picActive = 1;
const hoverRect = document.querySelector("#hoverRect");
//"zoom window"
const zoom = document.querySelector('#zoom');
//"zoom ratio"
let ratio = 3;
//"coordinates of mouse cursor"
let x, y, xx, yy;
//"Width & height of main picture in px"
let w1 = mainPicContainer.offsetWidth;
let h1 = mainPicContainer.offsetHeight;
//console.log(w1, h1); //420 854
//"width & height of selector"; the hoverbox
let w2 = hoverRect.offsetWidth;
let h2 = hoverRect.offsetHeight;
//"zoom window bg-img size"
zoom.style.backgroundSize = w1 * ratio + "px " + h1 * ratio + "px ";
//"zoom window width & height"
zoom.style.width = w2 * ratio + "px";
zoom.style.height = h2 * ratio + "px";
//"1/2 the selector shows outside of main picture; need 1/2 of width & height" (1/2 of the hoverbox)
w2 = w2 / 2;
h2 = h2 / 2;
pic1.classList.add("image-active");
// FUNCTION
//change the image of the mainPic block w/ current img
function changeImage(imgSrc, n){
//"This will change the main img"
mainPic.src = imgSrc;
//"remove box-shadow style from prev active side picture"
picArr[picActive - 1].classList.remove('image-active');
//"add box shadow to active side picture"
picArr[n - 1].classList.add('image-active');
//"update active side picture"
picActive = n;
}
//"moving the selector box" (#hoverRect)
function move(event){
//"how far the mouse cursor from an element"
x = event.offsetX; //"how far the cursor from left of element"
y = event.offsetY; //" ... top of element"
// console.log(x,y);
xx = x * ratio;
yy = y * ratio;
//"keeping the selector inside the main picture"
//"left of main picture"
if(x < w2){
x = w2;
}
//"right of main picture"
if(x > w1 - w2){
x = w1 - w2;
}
//"top..."
if(y < h2){
y = h2;
}
//"bottom..."
if(y > h1 - h2){
y = h1 - h2;
}
/* NOTE TO SELF
put the if statemnts before the hoverRect.style.left etc etc
for some reason, putting it after won't make the hover box stay w/i main picture"*/
//changing position of selector
//this is what will make the gray box move & the cursor will follow
hoverRect.style.left = x + "px";
hoverRect.style.top = y + "px";
//"changing bg image of zoom window"
zoom.style.backgroundPosition = '-' + xx + 'px ' + '-' yy + 'px'; //ERROR -
}
//IMAGES
.image-container{
display: flex;
flex-wrap: wrap;
background: lightGray;
padding: 10px;
div{
margin: 10px;
//background: blue;
}
}
.pictures{
width: 64px;
}
.shoe-image{
width: 100%;
}
///////// mainPic Div
.mainPicture{
width: 500px;//420px;
height: 500px; //840px;
position: relative;
background: yellow;
}
#pic{
width: 100%;
}
/* .explanation{
position: relative;
top: -514px;
height: 100%;
width: 30px;
background: blue;
}*/
//HOVER RECT
#hoverRect{
position: absolute;
margin: 0 !important;
padding: 0;
width: 200px;
height: 150px;
background-color: gray;
transform: translate(-50%, -50%); //this will make the cursor stay in center of the block
pointer-events: none; //this will resolve the glitchy movement of cursor
opacity: 0.4; //0
}
////////////////
//Zoom
.zoom{
position: relative;
top: 100px;
left: 20px;
background-image: url("https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/c3bd9dda9fdd4a7cbc9aad1e00dd0045_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_01_standard.jpg");//pic1
box-shadow: 0 0 3px black;
}
// JS CLASS
.image-active{
box-shadow: 0 0 3px gray;
}
.hoverRect-active{
opacity: 1;
}
<header>
<div class="banner">
<span>for educational purposes only</span>
</div>
</header>
<section class="image-container">
<div class="pictures">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/c3bd9dda9fdd4a7cbc9aad1e00dd0045_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_01_standard.jpg" alt="side view of shoes" id="pic1" class="shoe-image">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/a8dd72b84eb74a86a460ad1e00dd0db5_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_02_standard_hover.jpg" alt="top view of shoes" id="pic2" class="shoe-image">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/680f4199aa6e4226b539ad1e00dd1513_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_03_standard.jpg" alt="bottom/sole of shoes" id="pic3" class="shoe-image">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/8375f145b0f1441f8c7aad1e00dd0657_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_06_standard.jpg" alt="inner side of shoes" id="pic4" class="shoe-image">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/497f4207b21b4933836bad1e00dd22d9_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_05_standard.jpg" alt="back view of shoes" id="pic5" class="shoe-image">
</div>
<div class="mainPicture" id="mainPictureContainer">
<div class="hoverRect" id="hoverRect"></div>
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto:sensitive,fl_lossy/c3bd9dda9fdd4a7cbc9aad1e00dd0045_9366/NMD_R1_Primeblue_Shoes_White_GZ9260_01_standard.jpg" alt="side view of shoes" id="pic" >
<div class="explanation"></div>
</div>
<div class="zoom" id="zoom"></div>
</section>
<button>Show Var Explanation</button>
Because your missing a + at the end before yy
zoom.style.backgroundPosition = '-' + xx + 'px ' + '-' + yy + 'px';
neater and clearer
zoom.style.backgroundPosition = `-${xx}px -${yy}px`;
I'm trying to generate 100 random coloured boxes within the div with the existing by clicking generate button that has top and left position 0-400. Also if I hover over any coloured box it disappears until the last that will give me an alert last box with last box left.
I managed to create a box that generates different colours but im not sure how to generate a 100 let alone hover over and delete the boxes when it is, how would one go about doing that?
My HTML:
<!doctype html>
<html lang="en">
<head>
<title> Generator </title>
<meta charset="utf-8">
<script src="prototype.js"></script>
<script src="task4.js"></script>
<style>
#container {
height: 500px;
}
p {
width: 70px;
height: 70px;
background-color: rgb(100, 100, 255);
border: solid 2px black;
position: absolute;
}
</style>
</head>
<body>
<div id="container">
</div>
<button id="myButton"
onclick="createBoxes()"> Generate More
</button>
</body>
</html>
My JS
window.onload = function()
{
createBoxes();
}
function createBoxes()
{
var colors = ["red", "green", "blue", "purple", "yellow"];
var newP = document.createElement("p");
var top = 10 + "px";
var left = 10 + "px";
newP.style.top = top;
newP.style.left = left;
newP.style.backgroundColor = colors[ Math.floor( Math.random() *5 )];
$("container").appendChild(newP);
}
window.onload = function() {
createBoxes();
}
Let's get this done step by step.
While creating box element, you should not use p tag, div is the best choice here.
I have implemented as far as I understood from your question.
Let me know in the comments if I missed something.
I added comments in the code, check if you get it.
window.onload = function() {
createBoxes();
}
function createBoxes() {
var left = 0;
var top = 0;
var colors = ["red", "green", "blue", "purple", "yellow"];
// create a for loop and run 99 times;
for (var i = 1; i < 100; i++) {
var newDiv = document.createElement("div");
newDiv.classList.add('box')
newDiv.style.backgroundColor = colors[Math.floor(Math.random() * 5)];
newDiv.style.top = top + 'px';
newDiv.style.left = left + 'px';
// now add the event on this one;
newDiv.addEventListener('mouseover', removeBoxes);
$("#container").append(newDiv);
left += 70; // increase left 70px each time in the loop
if (i % 5 == 0) { // if the we have 5 boxes in one row, reset left to 0px and increase top property by 70px to get another row;
left = 0;
top += 70;
}
}
}
// function to remove the boxes on hover;
function removeBoxes() {
$(this).remove();
}
// add the mouseover event listener;
$('div.box').on('mouseover', removeBoxes);
#container {
min-height: 200px;
}
div.box {
width: 70px;
height: 70px;
background-color: rgb(100, 100, 255);
border: solid 2px black;
display: inline-block;
position: absolute;
box-sizing: border-box;
}
#myButton {
position: absolute;
right: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
<button id="myButton" onclick="createBoxes()"> Generate 99 More
</button>
I'm working on this script since 9 days, I found the script online, and from there I tried to add some code.
The point of the script is to rotate the Div dynamically based on the distance they have between each other.
In a way it works, if you resize the page at some point the divs turn their Y axes.
I have mainly 2 problems, the first one is that if I add new divs they just are shown in a new line.
The second problem is that those divs position should change, they need to get closer and they should move to the left side of the div.
I hope somebody can help because I spent already 10 days on this and I can't find a solution.
Thank you so much
function myFunction(distance) {
//add browser check currently it set for safari
// Code for Safari
var degree = 0;
if (distance <= -1 && distance >= -5) {
degree = 15;
} else if (distance < -5 && distance >= -10) {
degree = 25;
} else if (distance < -10 && distance >= -15) {
degree = 30;
} else if (distance < -15 && distance >= -20) {
degree = 35;
} else if (distance < -20) {
degree = 45;
}
document.getElementById("panel").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel2").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel3").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel4").style.WebkitTransform = "rotateY(" + degree + "deg)";
// document.getElementById("panel").style.marginRight= "100px";
document.getElementById("panel2").style.marginRight = "300px";
document.getElementById("panel3").style.marginRight = "30px";
document.getElementById("panel4").style.marginRight = "30px";
// document.getElementById("panel5").style.WebkitTransform = "rotateY(45deg)";
// document.getElementById("panel6").style.WebkitTransform = "rotateY(45deg)";
// Code for IE9
// document.getElementById("asd").style.msTransform = "rotateY(20deg)";
// Standard syntax
// document.getElementById("asd").style.transform = "rotateY(20deg)";
}
function myFunctionb() {
document.getElementById("panel").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel2").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel3").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel4").style.WebkitTransform = "rotateY(0deg)";
// document.getElementById("panel5").style.WebkitTransform = "rotateY(0deg)";
// document.getElementById("panel6").style.WebkitTransform = "rotateY(0deg)";
}
// need to find a better solution
var first = document.getElementById("panel");
var second = document.getElementById("panel2");
var lastpanel = document.getElementById("panel4");
var lastbox = document.getElementById("last");
var container = document.getElementById("wrapper");
var notcongainer = container.offsetLeft;
var distance = container.offsetWidth - (lastpanel.offsetWidth + lastbox.offsetLeft + 4) + notcongainer;
console.log(distance);
var myVar;
var minDistance = 10;
function check() {
myVar = setInterval(testcheck, 100);
}
// First I check that the boxes lenght are as much as the container
// Then I check the distance between 2 boxes
function testcheck() {
if (distance < minDistance) {
myFunction(distance);
} else {
myFunctionb();
}
distance = container.offsetWidth - (lastpanel.offsetWidth + lastbox.offsetLeft + 4) + notcongainer;
/*console.log(distance)*/
}
//ADD NEW DIV
function addDiv() {
var div = document.createElement('div');
div.className = "col-box";
div.id = "newId";
div.innerHTML = '<div class="hover panel"><div id= "panel3" class="front"><div class="box1"><p>New Div</p></div></div></div>';
document.getElementById('wrapper').appendChild(div);
}
body {
background-color: #ecf0f1;
margin: 20px;
font-family: Arial, Tahoma;
font-size: 20px;
color: #666666;
text-align: center;
}
p {
color: #ffffff;
}
.col-box {
width: 22%;
position: relative;
display: inline;
display: inline-block;
margin-bottom: 20px;
z-index: 1;
}
.end {
margin-right: 0 !important;
}
/*-=-=-=-=-=-=-=-=-=-=- */
/* Flip Panel */
/*-=-=-=-=-=-=-=-=-=-=- */
.wrapper {
width: 80%;
height: 200px;
margin: 0 auto;
background-color: #bdd3de;
hoverflow: hidden;
border: 1px;
}
.panel {
margin: 0 auto;
height: 130px;
position: relative;
-webkit-perspective: 600px;
-moz-perspective: 600px;
}
.panel .front {
text-align: center;
}
.panel .front {
height: inherit;
position: absolute;
top: 0;
z-index: 900;
text-align: center;
-webkit-transform: rotateX(0deg) rotateY(0deg);
-moz-transform: rotateX(0deg) rotateY(0deg);
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
-ms-transition: all .4s ease-in-out;
-o-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}
.panel.flip .front {
-webkit-transform: rotateY(45deg);
-moz-transform: rotateY(180deg);
}
.col-box:hover {
z-index: 1000;
}
.box1 {
background-color: #14bcc8;
width: 160px;
height: 60px;
margin-left: 5px;
padding: 20px;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
<body onload="check()">
<div id="wrapper" class="wrapper">
<div id="first" class="col-box">
<div class="hover panel">
<div id="panel" class="front">
<div class="box1">
<p>Div 1</p>
</div>
</div>
</div>
</div>
<div id="second" class="col-box">
<div class="hover panel">
<div id="panel2" class="front">
<div class="box1">
<p>Div 2</p>
</div>
</div>
</div>
</div>
<div id="third" class="col-box">
<div class="hover panel">
<div id="panel3" class="front">
<div class="box1">
<p>Div 3</p>
</div>
</div>
</div>
</div>
<div id="last" class="col-box">
<div class="hover panel">
<div id="panel4" class="front">
<div class="box1">
<p>Last Div</p>
</div>
</div>
</div>
</div>
<button onclick="addDiv()">Add New Div</button>
</div>
9 days... that's too long. Time to step back and break this up into smaller things.
This isn't an 'answer' yet... but I need to post an image for you. Your question wasn't that clear, but it's not an easy thing to explain. In your case, I would show an image.
Now that I can see what you're doing - it doesn't sound like an arbitrary and completely silly task.
You have a list of 'things' or 'cards' or whatever... so, first things first... how do you insert new DOM into the page - and / into that list - and have the list all on one line. A few ways - but most likely you can just use flexbox -
https://jsfiddle.net/sheriffderek/8eLggama -> https://jsfiddle.net/sheriffderek/pztvhn3L (this is an example - but it's pretty naive - and the further you take this, the closer you'll get to building what most frameworks - like Vue could do way better... but good for learning! Start with something small - to just do that.
// will take an object with the list name and the card id
// eventuallly - you'd want the card to have more info sent in...
function addCard(infoObject) {
var targetList = document.getElementById(infoObject.list);
var li = document.createElement('li');
li.classList.add('item');
// ug! why aren't I using jQuery...
var component = document.createElement('aside');
component.classList.add('card');
var title = document.createElement('h2');
var uniqueId = idMaker.create();
var id = document.createTextNode(uniqueId);
title.appendChild(id);
component.appendChild(title)
li.appendChild(component);
targetList.appendChild(li);
// woah... this part is really boring...
// this is why templating engines and JSON are so popular
// you could also add 'remove' button etc... right?
var removeButton = document.createElement('button');
var removeText = document.createTextNode('x');
removeButton.appendChild(removeText);
removeButton.classList.add('remove-card');
component.appendChild(removeButton);
//
removeButton.addEventListener('click', function() {
var parent = document.getElementById(infoObject.list);
idMaker.removed.push(uniqueId);
parent.removeChild(li);
idMaker.read();
});
}
// start out with a few?
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});
// start a UI to add cards
var addCardButton = document.querySelector('[data-trigger="add-card"]');
addCardButton.addEventListener('click', function() {
addCard({list: 'exampleTarget'});
});
...and then you maybe absolute position the card inside of that list item? It's certainly a unique thing to do, and wont be easy. Then, you can check the number of items - of the width of each item - and make a calculation for transform based on that? Good luck!
First of all i have seen many answer in stakeoverflow but none of these helped me!!! I want to start my div from a random position and then it will move. Rather then it shows from a static position and then it comes to a random position and then it start to move. I tried to declare my top and left by javascript in
$( document ).ready(function()
but that does not help
HTML
<div class="ballarea" id="ballarea1">
<div class="circle type" id="ball"></div>
</div>
CSS
.circle{
border-radius: 50%;
border: thin;
border-color: blue;
}
.type {
width: 20px;
height: 20px;
border: 5px solid blue;
position: relative;
}
.ballarea{
width: 300px;
height: 400px;
border: solid black;
overflow: hidden;
position: relative;
}
JavaScript
var i=0;
var j=0;
function ballMove(){
var d=document.getElementById("ball");
var temp=i;
if(i<1)
{
i = Math.floor(Math.random() * (200));
j = Math.floor(Math.random() * (200));
}
for(;i<2+temp;i++,j++)
{
d.style.left=i+"px";
d.style.top=j+"px";
}
//document.getElementById('ball').style.display = 'block';
}
function timeChange()
{
setInterval( ballMove, 500);
}
Now at first it starts from a static position like the following and then it start from a random position. I want to show it from a random position not from a static position
Try hiding it at first, because your script run when your DOM is ready.
<div class="ballarea" id="ballarea1">
<div class="circle type" id="ball" style="display:none"></div>
</div>
Then when your script is running, show it
var i = 0;
var j = 0;
function randomBall(){
var d = document.getElementById("ball");
i = Math.floor(Math.random() * (200));
j = Math.floor(Math.random() * (200));
d.style.left = i+"px";
d.style.top = j+"px";
d.style.display = "block";
}
function ballMove(){
var d=document.getElementById("ball");
i += 2;
j += 2;
d.style.left = i+"px";
d.style.top = j+"px";
}
function timeChange()
{
randomBall();
setInterval( ballMove, 500);
}