I am working on a whack-a-mole game for a school assignment and I can't get it to work.
The full code can be found on jsfiddle (https://jsfiddle.net/Lc30u5h7/5/) to make this question shorter.
Whenever I load the code my "moles" (black square divs) disappear. By turning parts of my code in to comments I nailed down the error to this part of the code:
function showMole(tile) {
if (gameRunning) {
$(this).css({"background-color": "green"});
$(tile).data('mole', true);
randomInt(400, 1200) {hideMole(this)};
};
};
function hideMole(tile) {
$(tile).css({"background-color": "black"});
$(tile).data('mole', false);
randomInt(4000,48000) {showMole(this)};
};
More specifically the error is located witht the function randomInt() which uses the following code:
function randomInt(min, max){
return Math.ceil(Math.random() * (max - min) ) + min;
};
The functions are supposed to represent the different states of the moles. After a random interval a mole will switch from hideMole() to showMole() and it will turn green and reward a point if clicked (which is handled by another piece of code).
I appreciate any help I can get.
I have tried to get you started with some example code. This code uses a handful of times to help manage the game.
var game = function() {
var gameBoard_Selector = "#gameBoard";
var tile_Selector = ".tile";
var mole_ClassName = "mole";
var $gameBoard = $(gameBoard_Selector);
var $gameTiles = $gameBoard.find(tile_Selector);
var gameTime = 20 * 1000;
var turnTime = 1000;
var moleInterval;
var moleLifeMin = 1000;
var moleLifeMax = 3 * 1000;
var gameScore = 0;
var getRandomIntInclusive = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// ------------------------
// Add a click handler to the board
// This could be added and removed at start and end as an alternative.
// or added to each individual tile if you liked that strategy.
// ------------------------
$gameBoard.on("click", ".tile", function() {
var $this = $(this);
// -------------------------
// if this is not a mole do nothing...
// -------------------------
if (!$this.hasClass(mole_ClassName)) { return; }
// -------------------------
// -------------------------
// "hide" this mole and increment the score
// -------------------------
$this.removeClass(mole_ClassName);
gameScore += 1;
// -------------------------
});
// ------------------------
var startGame = function() {
gameScore = 0;
// -------------------------
// Every turnTime, spawn a new mole.
// Record moleInterval so we can cancel it when the game ends.
// -------------------------
moleInterval = setInterval(spawnMole, turnTime);
// -------------------------
// -------------------------
// The game ends in gameTime
// -------------------------
setTimeout(endGame, gameTime);
// -------------------------
}
var endGame = function() {
// -------------------------
// Stop spawning new moles
// -------------------------
clearInterval(moleInterval);
// -------------------------
// -------------------------
// "hide" any existing moles.
// -------------------------
$gameTiles.removeClass(mole_ClassName);
// -------------------------
alert("Game Over! Score: " + gameScore);
}
var spawnMole = function(timeToLive) {
// -------------------------
// Select a random tile to set as a mole.
// You might adjust to only spawn moles where there are none already.
// -------------------------
var $targetTile = $($gameTiles[getRandomIntInclusive(0, $gameTiles.length - 1)]);
// -------------------------
// -------------------------
// Moles shall live for a random amount of time
// -------------------------
var timeToLive = getRandomIntInclusive(moleLifeMin , moleLifeMax);
// -------------------------
// -------------------------
// "show" the mole
// -------------------------
$targetTile.addClass(mole_ClassName);
// -------------------------
// -------------------------
// after timeToLive, automatically "hide" the mole
// -------------------------
setTimeout(function() { $targetTile.removeClass(mole_ClassName); }, timeToLive);
// -------------------------
}
return {
startGame
};
}();
game.startGame();
#gameBoard {
margin: auto;
margin-top: 75px;
width: 250px;
height: 250px;
}
#gameBoard .tile {
background-color: black;
height: 20%;
width: 20%;
margin: 2px;
display: inline-block;
}
#gameBoard .tile.mole {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="gameBoard">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
I created my own version of this game to help you out.
Breakdown
Start by creating variables to store the user's score, level and how many lives they have. Also create a boolean variable for whether or not the game is in progress. This prevents accidental re-clicks of the start game button.
We will be incrementing the score quite a bit, so it is best to create a re-usable function for that. In my example, this is the displayScore() function. In my game, as you gain points, you will level up, so the view needs to be updated to relect that. That's where the levelUp() function comes in handy.
In the game board there are 16 cells, arranged in a 4 x 4 matrix. We can query the collection of all the cells with document.querySelectorAll(".cell"). To make the game fun, it's better not to know which cell will pop-up. That's why a cell will randomly light up in the randomCell() function.
Throughout the game, there are multiple times when the script needs to check if the player has lost. Because of that, I created a reusable gameOver() function that counts the player's lives. If the player has no lives remaining, the interval will be cleared, the playing status will be reset to not playing and the variables will be reset.
Try it out here.
var score = 0;
var level = 1;
var lives = 5;
var playing = false;
var start = document.getElementById("start");
var scoreDisplay = document.getElementById("score-display");
var cells = document.querySelectorAll(".cell");
function displayScore() {
levelUp();
scoreDisplay.innerHTML = "Score: " + score + "<span id='level-display'> Level: " + level + "</span><span id='lifes-display'> Lives: " + lives + "</span>";
}
function levelUp() {
level = Math.max(Math.floor(score / 10), 1);
}
function randomCell() {
return Math.floor(Math.random() * 16);
}
function gameOver() {
if (lives === 0) {
clearInterval(getCells);
score = 0;
level = 1;
lives = 5;
playing = false;
}
}
function highlightCell() {
var target = randomCell();
var prevScore = score;
cells[target].style.background = "green";
setTimeout(function() {
cells[target].style.background = "red";
if (score === prevScore) {
lives--;
displayScore();
gameOver();
}
}, 1000)
}
start.addEventListener("click", function() {
if (!playing) {
playing = true;
displayScore();
getCells = setInterval(function() {
highlightCell();
}, 1500);
}
});
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", function() {
if (playing) {
var cell = this;
if (this.style.background === "green") {
score++;
}
else {
lives--;
gameOver();
}
displayScore();
}
})
}
#game-board {
height: 330px;
width: 330px;
margin: 0 auto;
border: 1px solid black;
}
.cell {
display: inline-block;
width: 21%;
margin: 4px;
height: 21%;
border: 1px solid black;
background: red;
}
#game-info {
height: 40px;
width: 330px;
margin: 0 auto;
background: lightblue;
}
#level-display, #lifes-display {
margin-left: 30px;
}
#start {
margin: 10px 37%;
}
<div id="game-info">
<p id="score-display"></p>
</div>
<div id="game-board">
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
<div class="cell"></div>
</div>
<button id="start">Start Game</button>
Related
[image of a mole to be placed randomly in the squares created][1
**
I am trying to code the game called 'Whack-a-mole'. I created h1 and div elements to be placed on screen using javascript . Then I wanted to place an image inside the squares to appear randomly, but it does not appear in the squares. Could you please help me with where I went wrong ?
Thank You
. I add
// MY CODE
// const h1 = document.createElement('h1');
// h1.textContent = 'Your Score: ';
// h1.id = 'score';
// document.body.append(h1);
// const time = document.createElement('h1');
// time.textContent = 'Time Left: ';
// time.id = 'time';
// document.body.append(time);
// const grid = document.createElement('div');
// grid.className = 'grid';
// document.body.append(grid);
// for (let i = 0; i < 8; i++) {
// let square = document.createElement('img');
// square.className = 'square';
// square.id = ('data-id', i+1);
// grid.append(square);
// };
// const result = document.querySelector('#score');
// const left = document.querySelector('#time');
// const boxes = document.querySelectorAll('.square');
// const images = document.querySelector('.mole');
// function randomMole() {
// boxes.forEach(box => {
// box.classList.remove('images');
// });
// let randomSquare = boxes[Math.floor(Math.random() * 8)];
// randomSquare.classList.add('images');
// };
// randomMole();
// Ania code
const squares = document.querySelectorAll('.square')
const mole = document.querySelector('.mole')
const timeLeft = document.querySelector('#time-left')
const score = document.querySelector('#score')
let result = 0
let hitPosition
let currentTime = 60
let timerId = null
function randomSquare() {
squares.forEach(square => {
square.classList.remove('mole')
})
let randomSquare = squares[Math.floor(Math.random() * 9)]
randomSquare.classList.add('mole')
hitPosition = randomSquare.id
}
randomSquare();
squares.forEach(square => {
square.addEventListener('mousedown', () => {
if (square.id == hitPosition) {
result++
score.textContent = result
hitPosition = null
}
})
})
function moveMole() {
timerId = setInterval(randomSquare, 500)
}
moveMole()
function countDown() {
currentTime--
timeLeft.textContent = currentTime
if (currentTime == 0) {
clearInterval(countDownTimerId)
clearInterval(timerId)
alert('GAME OVER! Your final score is ' + result)
}
}
let countDownTimerId = setInterval(countDown, 1000)
.grid {
width: 600px;
height: 300px;
display: flex;
flex-wrap: wrap;
}
.square {
width: 135px;
height: 135px;
border: solid rgb(11, 8, 8) 1px;
}
.mole {
background-image: url('images/mole.jpg');
background-size: cover;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="style.css" rel="stylesheet">
</head>
<body>
<h2>Your score:</h2>
<h2 id="score">0</h2>
<h2>Time Left:</h2>
<h2 id="time-left">60</h2>
<div class="grid">
<div class="square" id="1"></div>
<div class="square" id="2"></div>
<div class="square" id="3"></div>
<div class="square" id="4"></div>
<div class="square" id="5"></div>
<div class="square" id="6"></div>
<div class="square" id="7"></div>
<div class="square" id="8"></div>
<div class="square" id="9"></div>
</div>
<script src="Ania JS/Ania game 3.js"></script>
</body>
</html>
**
I suppose you need the .mole class to display the image. Here's a a minimal reproducable example for your code.
Play with it by forking this stackblitz project.
Or play the game itself 🙃
document.addEventListener(`click`, evt =>
evt.target.id === `redo` && randomMole());
document.body.insertAdjacentHTML(
`beforeend`, `<div class="grid">${
[...Array(8)].map((_, i) => `<img class="square" data-id=${i}>`)
.join(``) }</div>`);
document.querySelector(`#redo`).click();
function randomMole() {
const mole = document.querySelector(`.mole`);
mole && mole.classList.remove('mole');
document.querySelectorAll('.square')[Math.floor(Math.random() * 8)]
.classList.add(`mole`);
};
.grid {
width: 600px;
height: 300px;
display: flex;
flex-wrap: wrap;
}
.square {
width: 64px;
height: 64px;
border: solid rgb(11, 8, 8) 1px;
margin-right: 2px;
}
.mole {
background-image: url('//cdn.pixabay.com/photo/2012/05/02/17/24/ground-45742_960_720.png');
background-size: cover;
}
<p><button id="redo">random mole position</button></p>
I have two functions (one that runs)
I'm wanting to use these and create two player turn variables to switch between each other marking an X or an O when it's each players turn. I'm wanting to keep it as simple as possible but cannot even fathom where to go. I know it's not great but if I can I would like to keep these functions or something close to it.
<section class="allBoxes">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
<div class="box5"></div>
<div class="box6"></div>
<div class="box7"></div>
<div class="box8"></div>
<div class="box9"></div>
<script src="tictac.js"></script>
</section>
function clickBoxPlayerOne(event) {
var boxClicked = event.target;
if ((boxClicked.textContent = " ")) boxClicked.textContent = "X";
}
var allBoxes = document.querySelector(".allBoxes");
allBoxes.addEventListener("click", clickBoxPlayerOne);
function clickBoxPlayerTwo(event) {
var boxClicked = event.target;
if (boxClicked.textContent != "X") boxClicked.textContent = "O";
}
var allBoxes = document.querySelector(".allBoxes");
allBoxes.addEventListener("click", clickBoxPlayerTwo);
I think what you need is a global variable to keep the current player state and update it whenever the user clicks on any box. Like in the Tic-tac-toe :)
Adding a sample working code for reference to see how the usage is.
const player1 = "X", player2 = "O";
let currentPlayer = player1;
const elements = document.getElementsByClassName("tile");
// Click handler
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', playMe, false);
}
function playMe(event) {
if(event.target.innerText == "") {
event.target.innerText = currentPlayer;
currentPlayer = currentPlayer == player1 ? player2 : player1;
}
}
.tile {
padding: 10px;
border: 1px solid #CCC;
width: 40px;
display: inline-block;
text-align: center;
margin-right: 10px;
}
.row {
margin: 10px;
}
<div>
<div class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
<div class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
<div class="row"><span class="tile"></span><span class="tile"></span><span class="tile"></span></div>
</div>
To remove the need for global variables I would use the function that's called from addEventListener to set up those variables, and return a new function (closure) that is the function that's returned to the listener. The closure maintains the variables in its local lexical environment so it can update them.
I would also use CSS Grid to handle the display.
const allBoxes = document.querySelector('.allboxes');
allBoxes.addEventListener('click', handleClick(), false);
function handleClick() {
// Initialise the player variable
let player = 1;
// Return the function that will be used
// when the listener is called
return function (e) {
// Get the text content of the clicked element
const { textContent } = e.target;
if (!textContent) {
// Update the content of the square, and
// then swap the player
const content = player === 1 ? 'X' : 'O';
e.target.textContent = content;
player = player === 1 ? 2 : 1;
}
}
}
.allboxes { width: 50%; display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5em; }
.allboxes div { display: flex; border: 1px solid black; height: 2em; width: 2em; align-items: center; justify-content: center;}
<div class="allboxes">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Hello I have a number animation on my web page and I dont want the animation to start until it is in the middle of the web page. I tried to google onscroll and other options but I could not get this to work properly.
I prefer for the animation not to start until the visitor has scrolled down to 472px. As of right now as soon as the web page loads the number animation starts automatically. Any help I would really appreciate it.
// 472 px - Starts Yellow Counter Section
const counters = document.querySelectorAll('.counter');
const speed = 200; // The lower the slower
counters.forEach(counter => {
const updateCount = () => {
const target = +counter.getAttribute('data-target');
const count = +counter.innerText;
// Lower inc to slow and higher to slow
const inc = target / speed;
// console.log(inc);
// console.log(count);
// Check if target is reached
if (count < target) {
// Add inc to count and output in counter
counter.innerText = count + inc;
// Call function every ms
setTimeout(updateCount, 1);
} else {
counter.innerText = target;
}
};
updateCount();
});
.bg-yellow-white {
background: #f7c51e;
color: white;
}
.container {
max-width: 1404px;
margin: auto;
padding: 0 2rem;
overflow: hidden;
}
.l-heading {
font-weight: bold;
font-size: 4rem;
margin-bottom: 0.75rem;
line-height: 1.1;
}
/* Padding */
.py-1 {
padding: 1.5rem 0;
}
.py-2 {
padding: 2rem 0;
}
.py-3 {
padding: 3rem 0;
}
/* All Around Padding */
.p-1 {
padding: 1.5rem;
}
.p-2 {
padding: 2rem;
}
.p-3 {
padding: 3rem;
}
/* ======================== Red Block ======================== */
.red-block {
height: 472px;
width: 100%;
background-color: red;
}
/* ======================== PROJECS COMPLETED ======================== */
#projects-completed .container .items {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
#projects-completed .container .items .item .circle {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
<div class="red-block">
<p>red block</p>
</div>
<section id="projects-completed" class="counters bg-yellow-white">
<div class="container">
<div class="items">
<div class="item text-center p-3">
<div class="circle">
<div class="counter l-heading" data-target="1750">500</div>
</div>
<h2 class="py-2">Projects Completed</h2>
</div>
<div class="item text-center p-3">
<div class="circle py-2">
<div class="l-heading counter" data-target="5">500</div>
</div>
<h2 class="py-2">Staff Members</h2>
</div>
<!-- <div class="item text-center p-3">
<div class="circle">
<h3 class="l-heading ">1750</h3>
</div>
<h2 class="py-2">Projects Completed</h2>
</div>
<div class="item text-center p-3">
<div class="circle py-2">
<h3 class="l-heading">5</h3>
</div>
<h2 class="py-2">Staff Members</h2>
</div> -->
</div>
</div>
</section>
wesbos has great video on this https://www.youtube.com/watch?v=uzRsENVD3W8&list=PLu8EoSxDXHP6CGK4YVJhL_VWetA865GOH&index=14&t=0s
Basically what you need to do is listen for scroll and check where user currently is compared to desired place in px
you can check code here and adjust it to your needs https://github.com/wesbos/JavaScript30/blob/master/13%20-%20Slide%20in%20on%20Scroll/index-FINISHED.html
Try getBoundingClientRect(). document.querySelector( 'some element' ).getBoundingClientRect() will give you the properties of the specific element
for Example if you want to start an animation when an element is visible to user on his screen ( in the visible viewport ), you can use this to call the function and start the animation
let calledStatus = 0; // some flag variable to remember if function is called
window.onscroll = function(){
element = document.querySelector( '.some element' );
clientRect = element.getBoundingClientRect();
if( clientRect.top < window.innerHeight && clientRect.top > ( clientRect.height * -1) && calledStatus == 0){
//call your function or do other stuff
console.log('called' )
calledStatus = 1;
}
}
By using jquery , first add this reference script above your js code or referenece script
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></scrip>
....
</head>
if you want the code to launch specifically after 472 px:
js
$(document).ready(function () {
Let initialScroll = true;
//you can decrease or increase 472 depending on where exactly
//you want your function to be called
$(document).scroll(function () {
if (($(document).scrollTop() > 472)&& initialScroll) {
//call your function here
console.log( "reached 472")
InitialScroll=false;
}
});
});
if you want your function to start after reaching the middle
of the document
you place a div where the middle of the html code is :
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
...
<div id="middle"></div>
...
</body>
</html>
js
$(document).ready(function () {
Let initialScroll=true
$(document).scroll(function () {
if (($(document).scrollTop() >=$('#middle').position().top)&&initialScroll) {
//call your function here
console.log( "reached middle")
InitialScroll=false;
}
});
});
There is a native javascript API for "listetning" where the user currently is on the page called Intersection Observer. Basically you set a callback which should execute once the desired content scrolls into view.
It's used for all those fancy page animations where cards appear once you start scrolling to the bottom of the page since it's far more efficient than listening on the scroll event.
Kevin Powell did a great video about this topic.
Hope it helps!
Here's a code copy pasted, but it should give you a clue on how it should work:
document.addEventListener("DOMContentLoaded", function() {
let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
let active = false;
const lazyLoad = function() {
if (active === false) {
active = true;
setTimeout(function() {
lazyImages.forEach(function(lazyImage) {
if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove("lazy");
lazyImages = lazyImages.filter(function(image) {
return image !== lazyImage;
});
if (lazyImages.length === 0) {
document.removeEventListener("scroll", lazyLoad);
window.removeEventListener("resize", lazyLoad);
window.removeEventListener("orientationchange", lazyLoad);
}
}
});
active = false;
}, 200);
}
};
document.addEventListener("scroll", lazyLoad);
window.addEventListener("resize", lazyLoad);
window.addEventListener("orientationchange", lazyLoad);
});
I have a grid of 9 divs nested in columns of three. When the grid (#left) is clicked , 2 divs from the middle row, row="1" should have the class .show randomly applied to it, in the column where the no class was applied the div on the bottom row, row="2" should have the class '.show' applied. The attached picture shows the possible random outcomes. The same outcome should never appear consecutively.
I attached a code snippet of my code, currently, my index selection is not working as desired and I have struggled to find the reason why.
var obj = {
bindEvents: function() {
var _this = this;
$('#left').on("click", $.proxy(_this.interaction, _this));
},
interaction: function() {
var selector = this.randomGenerator(0, 3);
console.log('selector = ' + selector());
var $midRow = $('#left').find('div[row=1]');
var $bottomRow = $('#left').find('div[row=2]');
$midRow.removeClass('show');
$bottomRow.removeClass('show');
$midRow.not(':eq(' + selector() + ')').addClass('show');
$bottomRow.eq(selector()).addClass('show');
},
randomGenerator: function(min, max) {
var last;
console.log('last = ' + last);
return function () {
var random;
do {
random = Math.floor(Math.random() * (max - min)) + min;
} while (random === last);
last = random;
return random;
};
},
}
obj.bindEvents();
#left {
display: flex;
}
div[row] {
border: 1px solid black;
width: 20px;
background-color: yellow;
}
.show {
background-color: red !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="left">
<div col="0">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="1">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="2">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
</div>
You do not pass any element to the functions.
There is no this... You have to provide it.
EDIT
When you call selector(), you are aware that it is a function... And that a new number is produced each time you call the function.
If you want the same "number" to be used in both .eq() statement, run the function just once and keep the number in a variable.
See changes in code.
var obj = {
bindEvents: function(el) { // pass an element!
//var _this = this;
//$('#left').on("click", $.proxy(_this.interaction, _this));
el.on("click", $.proxy(obj.interaction(el), el)); // Call the obj function.
},
interaction: function(el) { // pass an element again!
var selector = obj.randomGenerator(0, 3); // Call the obj function.
// Get a number
var number = selector();
console.log('selector = ' + number);
var $midRow = $('#left').find('div[row=1]');
var $bottomRow = $('#left').find('div[row=2]');
$midRow.removeClass('show');
$bottomRow.removeClass('show');
$midRow.not(':eq(' + number + ')').addClass('show');
$bottomRow.eq(number).addClass('show');
},
randomGenerator: function(min, max) {
var last;
console.log('last = ' + last);
return function () {
var random;
do {
random = Math.floor(Math.random() * (max - min)) + min;
} while (random === last);
last = random;
return random;
};
},
}
obj.bindEvents($("#left"));
#left {
display: flex;
}
div[row] {
border: 1px solid black;
width: 20px;
background-color: yellow;
}
.show {
background-color: red !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="left">
<div col="0">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="1">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
<div col="2">
<div row="0">0</div>
<div row="1">1</div>
<div row="2">2</div>
</div>
</div>
I need to make an infinite wall which will pull text from database and show it on the wall. I have written this code -
$(function() {
var x = 0;
var y = 100.0;
var z=0;
setInterval(function() {
x -= 0.1;
y -= 0.1;
z++;
if (x <= -100.0){
$("#h1d1").html("loop div 1 :" + z);
x = 0;
}
if (y <= 0){
$("#h1d2").html("loop div 2 :" + z);
y = 100.0;
}
$('#movimg1').css('left', x + "%");
$('#movimg2').css('left', y + "%");
}, 10);
$("#stopbutton").click(function() {
$('#movimg1').stop();
});
})
But the text are not behaving as I wanted it to behave. It changes in the middle of the screen which I don't want. I need the text to change when it is out of view.
https://jsfiddle.net/oa0wdxcx/2/
A couple more things- I want to add a play/pause button. Any advice on how I could achieve that would be much appreciated. Also I want the divs to be inside #wrap div, but if I change the position attribute to relative, the divs don't remain together.
Thanks in advance.
The problem was in the conditions.
if (x <= -100.0) {
z++;
$("#h1d1").html("loop div 1 :" + z);
x = 100; /* change this line */
}
if (y <= -100.0) { /* change this line */
w++;
$("#h1d2").html("loop div 2 :" + w);
y = 100;
}
the conditions says that if any of these two divs reaches left:-100% then the element must place at the end of queue at left:100%.
And one other thing you can combine these if statements and only use x to do the transition.
For start and stop button to work, you should kill the simulation to stop by using clearInterval() function, and call doSimulate() to start again:
var started = true;
$("#stopbutton").click(function () {
if(started) {
clearInterval(sim);
$(this).html('Start');
started = false;
}else{
doSimulate();
$(this).html('Stop');
started = true;
}
});
Here is jsFiddle With Start/Stop Working.
Look at this JSFiddle, i added one more to get a smooth transition back to start.. The third should contain same message as first.
HTML
<body>
<div class="row">
<div class="col-xs-1"></div>
<div id="wrap" class="col-xs-10">
<div class="movimg message1" id="movimg1">
<h1 class="header">start div 1</h1>
</div>
<div class="movimg message2" id="movimg2">
<h1 class="header">start div 2</h2>
</div>
<div class="movimg message1" id="movimg3">
<h1 class="header">start div 1</h1>
</div>
</div>
<div class="col-xs-1"></div>
</div>
<div class="row">
<button class="button" id="startbutton" style="display:none;">Start</button>
<button class="button" id="stopbutton">Stop</button>
</div>
</body>
JavaScript
$(function () {
var x = 200.0;
var interval;
function start(){
interval = setInterval(function () {
x -= 0.1;
if (x <= 0.0) {
x = 200;
}
$('#movimg1').css('left', (x-200) + "%");
$('#movimg2').css('left', (x-100) + "%");
$('#movimg3').css('left', x + "%");
}, 10);
}
start();
$("#stopbutton").click(function () {
window.clearInterval(interval);
$(this).hide();
$("#startbutton").show();
});
$("#startbutton").click(function () {
start();
$(this).hide();
$("#stopbutton").show();
});
})
CSS
body {
overflow: hidden;
}
#wrap {
width: 80%;
left: 10%;
}
.movimg{
position: absolute;
height: 600px;
width: 100%;
background-image: url('https://s-media-cache-ak0.pinimg.com/736x/89/ed/e5/89ede56bcc8243787e55676ab28f287f.jpg');
}
#movimg1 {
left: 0%;
}
#movimg2 {
left: 100%;
}
#movimg3 {
left: 200%;
}
.header {
text-align: center;
}
.button{
top: 600px;
position: relative;
}
UPDATE
Now with Stop and Start buttons: JSFiddle