Why Is My Function Alternating Between Working and Then Not Javascript - javascript

This is my very first ever question asked here, so I do apologise in advance if I am not following correct guidelines.
Basically what I'm trying to do is to manually code side-section navigating in Javascript. The navigating itself is working just fine, one can click either left or right and the sections will scroll left and right endlessly in a carousel. But when I try to set the previous pages scrollTop back to 0 once the user has moved off the section I run into problems.
If I scroll through each section and scroll a bit of the way down on each, when I return to the first page and cycle through them again, they seem to alternate as to whether their scrollTop was actually set to 0.
HTML body:
<div class="Arrow" id="arrowLeft"></div>
<div class="Arrow" id="arrowRight"></div>
<section class="Page" id="page1"><div class="PageContent"></div></section>
<section class="Page" id="page2"><div class="PageContent"></div></section>
<section class="Page" id="page3"><div class="PageContent"></div></section>
<section class="Page" id="page4"><div class="PageContent"></div></section>
<section class="Page" id="page5"><div class="PageContent"></div></section>
<section class="Page" id="page6"><div class="PageContent"></div></section>
<section class="Page" id="page7"><div class="PageContent"></div></section>
<section class="Page" id="page8"><div class="PageContent"></div></section>
<script src="JavaScript/scroller.js"></script>
Javascript:
//initialising variables and populating arrays
var currentPage = 0;
var previousPage = 0;
var pages = document.getElementsByClassName("Page");
var sections = [];
for (i=0;i<pages.length;i++) {
sections.push(pages[i]);
}
var pageOffSets = [0, 100, 200, 300, 400, -300, -200, -100];
var zOffSets = [0,-1,-2,-3,-4,-3,-2,-1];
for (i = 0;i<sections.length;i++) {
sections[i].style.left = pageOffSets[i] + "vw";
sections[i].style.zIndex = zOffSets[i];
}
//Navigate function
function slidePage(direction) {
previousPage = currentPage;
if (direction=="right") {
currentPage+=1;
if (currentPage>7) {
currentPage = 0;
}
var hold = sections.shift();
sections.push(hold);
for (i=0;i<sections.length;i++) {
sections[i].style.left = pageOffSets[i] + "vw";
sections[i].style.zIndex = zOffSets[i];
}
}
if (direction=="left") {
currentPage-=1;
if (currentPage<0) {
currentPage = 7;
}
var hold = sections.pop();
sections.unshift(hold);
for (i=0;i<sections.length;i++) {
sections[i].style.left = pageOffSets[i] + "vw";
sections[i].style.zIndex = zOffSets[i];
}
}
//!!!
//This is the part that is supposed to set the scrollTop back to 0
//!!!
setTimeout(function(){
sections[previousPage].scrollTop = 0;
}, 1000);
}
//Event listeners for when the user clicks
document.getElementById("arrowLeft").addEventListener("click", function(){
slidePage("left");
});
document.getElementById("arrowRight").addEventListener("click", function(){
slidePage("right");
});
I would really appreciate if someone could point out what I'm doing wrong.
Edit:
Here is the CSS if you need it:
body {
overflow-x: hidden;
overflow-y: scroll;
}
section {
width: 100vw;
height: 100vh;
position: fixed;
-webkit-transition-duration: 0.4s;
transition-duration: 0.4s;
overflow: scroll;
}
.Arrow {
position: absolute;
z-index: 1;
width: 50px;
height: 50px;
background-color: black;
top: 48%;
}
.Arrow:hover {
cursor: pointer;
}
#arrowRight {
right: 0;
}
#page1 {
background-color: #c81996;
}
#page2 {
background-color: #64324b;
}
#page3 {
background-color: #1996c8;
}
#page4 {
background-color: #324b64;
}
#page5 {
background-color: #96c819;
}
#page6 {
background-color: #4b6432;
}
#page7 {
background-color: #f0fa1e;
}
#page8 {
background-color: #fa1ef0;
}
.PageContent {
height: 8000px;
width: 90vw;
margin: 5vw;
background-image: -webkit-gradient(linear, left top, left bottom, from(red), to(yellow));
background-image: linear-gradient(red, yellow);
position: absolute;
}

There are two problems:
You are rotating the sections array inside your function, so the previousPage index is no longer correct once your anonymous function is fired.
The previousPage variable referenced when setting scrollTop after the timeout can change before the timeout elapses.
The simplest fix would be to rotate pageOffSets and zOffSets arrays instead:
if (direction == "right") {
currentPage++;
if (currentPage >= sections.length) {
currentPage = 0;
}
// rotate pageOffsets
{
var x = pageOffSets.pop();
pageOffSets.unshift(x);
}
// rotate zOffsets
{
var x = zOffSets.pop();
zOffSets.unshift(x);
}
for (i=0;i<sections.length;i++) {
sections[i].style.left = pageOffSets[i] + "vw";
sections[i].style.zIndex = zOffSets[i];
}
} else {
currentPage--;
if (currentPage < 0) {
currentPage = sections.length - 1;
}
// rotate pageOffsets
{
var x = pageOffSets.shift();
pageOffSets.push(x);
}
// rotate zOffSets
{
var x = zOffSets.shift();
zOffSets.push(x);
}
for (i=0;i<sections.length;i++) {
sections[i].style.left = pageOffSets[i] + "vw";
sections[i].style.zIndex = zOffSets[i];
}
}
And you need to capture a copy of the previousPage variable:
// capture a copy of the index so that it doesn't change
var prev = previousPage;
setTimeout(function() {
sections[prev].scrollTop = 0;
}, 500);

Related

Collision detection using pure jQuery is not giving desired output

I am trying to develop a very simple game where the ship (red box) will move left-right when user clicks on playground.
There are some moving walls (black boxes) as obstacles that the ship should avoid colliding with.
If any collision happens, the walls will stop moving and a text will be printed out in console.
I have succeeded to get this as close as I can. But its working sometime, not always. You can see it in the code below, try to collide with wall. Sometime it will stop them and print text, sometime it will just ignore the collision as if nothing happens.
I have no clue why this is happening.
Here is the code.
$('document').ready(function() {
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
return $collide;
}
var $wallTimer = setInterval(function() {
$('.wall').each(function(i, obj) {
var $status = moveWall($(this));
if ($status == true) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision(wallObj) {
var $ship = $('.ship');
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
var $wall = wallObj;
var $wallWidth = wallObj.width();
var $wallHeight = wallObj.height();
var $wallLeft = wallObj.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = wallObj.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft >= $wallRight ||
$shipRight <= $wallLeft ||
$shipTop >= $wallBottom ||
$shipBottom <= $wallTop
) {
return false;
} else {
console.log("dhumm!");
return true;
}
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, 500, "linear");
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, 500, "linear");
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As freefomn-m already said.
Check for collision in the animation cycle of the ship, not the walls.
For this I use the second type of parameters for jQuery's .animate method
.animate( properties, options )
I use the "progress" option to check the collision in every movement cycle of the ship.
console.clear();
$('document').ready(function() {
var collided = false;
var collidedWith = null;
var $ship = $('.ship');
var $walls = $('.wall')
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
// var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
// return $collide;
}
var $wallTimer = setInterval(function() {
$walls.each(function(i, obj) {
moveWall($(this));
if (collided) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision() {
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
$('.wall').each(function(i) {
var $wall = $(this);
var $wallWidth = $wall.width();
var $wallHeight = $wall.height();
var $wallLeft = $wall.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = $wall.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft < $wallRight &&
$shipRight > $wallLeft &&
$shipTop < $wallBottom &&
$shipBottom > $wallTop
) {
console.log("dhumm!");
collided = true;
collidedWith = $wall
$wall.addClass('crashed')
$ship.addClass('crashed')
$ship.stop();
return false;
}
})
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .wall.crashed {
background: red;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: orange;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.outer .inner .ship.crashed {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As a recommendation how I would do this from scratch.
Use an update cycle that is called by either setInterval or setTimeout, or even better with requestAnimationFrame. The updatecycle would be responsible for the time progress and orchestrate the different objects. The structure would be like this.
jQuery(function($) { // same as $('document').ready()
var ship = ...;
var boundaries = ...;
var walls = ...;
var clickEvents = [];
document.addEventListener('click', function(e) {clickEvents.push(e)})
var handleEvents = function() {}
var setupWalls = function () {}
var setupShip= function () {}
var moveWalls = function () {}
var moveShip = function () {}
var checkCollision() {}
var setup = function() {
setupWalls();
setupShip();
// set the initial positions of the ships and the walls
}
var update = function() {
handleEvents();
moveWalls();
moveShips();
var collided = checkCollision();
if (!collided) {
setTimeout(update, 30);
}
}
setup();
update();
})

Hide scroll bar when page preloader loads

I want to hide scroll bar while preloader is loading the scroll bar will not show until unless preloader disappears which means the user can't able to scroll the page while preloader is loading here I'm using canvas as a preloader. I tried by using body overflow: hidden and some CSS also but unable to achieve the result here I used canvas effect as a preloader. Can anyone point me in the right direction what I'm doing wrong?
/* Preloader Effect */
var noise = function(){
//const noise = () => {
var canvas, ctx;
var wWidth, wHeight;
var noiseData = [];
var frame = 0;
var loopTimeout;
// Create Noise
const createNoise = function() {
const idata = ctx.createImageData(wWidth, wHeight);
const buffer32 = new Uint32Array(idata.data.buffer);
const len = buffer32.length;
for (var i = 0; i < len; i++) {
if (Math.random() < 0.5) {
buffer32[i] = 0xff000000;
}
}
noiseData.push(idata);
};
// Play Noise
const paintNoise = function() {
if (frame === 9) {
frame = 0;
} else {
frame++;
}
ctx.putImageData(noiseData[frame], 0, 0);
};
// Loop
const loop = function() {
paintNoise(frame);
loopTimeout = window.setTimeout(function() {
window.requestAnimationFrame(loop);
}, (1000 / 25));
};
// Setup
const setup = function() {
wWidth = window.innerWidth;
wHeight = window.innerHeight;
canvas.width = wWidth;
canvas.height = wHeight;
for (var i = 0; i < 10; i++) {
createNoise();
}
loop();
};
// Reset
var resizeThrottle;
const reset = function() {
window.addEventListener('resize', function() {
window.clearTimeout(resizeThrottle);
resizeThrottle = window.setTimeout(function() {
window.clearTimeout(loopTimeout);
setup();
}, 200);
}, false);
};
// Init
const init = (function() {
canvas = document.getElementById('noise');
ctx = canvas.getContext('2d');
setup();
})();
};
noise();
$(document).ready(function(){
$('body').css({
overflow: 'hidden'
});
setTimeout(function(){
$('#preloader').fadeOut('slow', function(){
$('body').css({
overflow: 'auto'
});
});
}, 5000);
});
#preloader {
position: fixed;
height: 100vh;
width: 100%;
z-index: 5000;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
/* change if the mask should have another color then white */
z-index: 10000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="preloader">
<canvas id="noise" class="noise"></canvas>
</div>
Try these Codes, If it works for you. I found this on StackOverflow. Source: Disable scrolling when preload a web page
Js Code
$(window).load(function() {
$(".preloader").fadeOut(1000, function() {
$('body').removeClass('loading');
});
});
Css Code
.loading {
overflow: hidden;
height: 100vh;
}
.preloader {
background: #fff;
position: fixed;
text-align: center;
bottom: 0;
right: 0;
left: 0;
top: 0;
}
.preloader4 {
position: absolute;
margin: -17px 0 0 -17px;
left: 50%;
top: 50%;
width:35px;
height:35px;
padding: 0px;
border-radius:100%;
border:2px solid;
border-top-color:rgba(0,0,0, 0.65);
border-bottom-color:rgba(0,0,0, 0.15);
border-left-color:rgba(0,0,0, 0.65);
border-right-color:rgba(0,0,0, 0.15);
-webkit-animation: preloader4 0.8s linear infinite;
animation: preloader4 0.8s linear infinite;
}
#keyframes preloader4 {
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
#-webkit-keyframes preloader4 {
from {-webkit-transform: rotate(0deg);}
to {-webkit-transform: rotate(360deg);}
}
Code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body class="loading">
<div class="preloader">
<div class="preloader4"></div>
</div>
//Code
</body>
You need to set overflow: hidden and height: 100vh both on the body and the html tags.
/* Preloader Effect */
var noise = function(){
//const noise = () => {
var canvas, ctx;
var wWidth, wHeight;
var noiseData = [];
var frame = 0;
var loopTimeout;
// Create Noise
const createNoise = function() {
const idata = ctx.createImageData(wWidth, wHeight);
const buffer32 = new Uint32Array(idata.data.buffer);
const len = buffer32.length;
for (var i = 0; i < len; i++) {
if (Math.random() < 0.5) {
buffer32[i] = 0xff000000;
}
}
noiseData.push(idata);
};
// Play Noise
const paintNoise = function() {
if (frame === 9) {
frame = 0;
} else {
frame++;
}
ctx.putImageData(noiseData[frame], 0, 0);
};
// Loop
const loop = function() {
paintNoise(frame);
loopTimeout = window.setTimeout(function() {
window.requestAnimationFrame(loop);
}, (1000 / 25));
};
// Setup
const setup = function() {
wWidth = window.innerWidth;
wHeight = window.innerHeight;
canvas.width = wWidth;
canvas.height = wHeight;
for (var i = 0; i < 10; i++) {
createNoise();
}
loop();
};
// Reset
var resizeThrottle;
const reset = function() {
window.addEventListener('resize', function() {
window.clearTimeout(resizeThrottle);
resizeThrottle = window.setTimeout(function() {
window.clearTimeout(loopTimeout);
setup();
}, 200);
}, false);
};
// Init
const init = (function() {
canvas = document.getElementById('noise');
ctx = canvas.getContext('2d');
setup();
})();
};
noise();
$(document).ready(function(){
$('body, html').css({
overflow: 'hidden',
height: '100vh'
});
setTimeout(function(){
$('#preloader').fadeOut('slow', function(){
$('body, html').css({
overflow: 'auto',
height: 'auto'
});
});
}, 5000);
});
#preloader {
position: fixed;
height: 100vh;
width: 100%;
z-index: 5000;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
/* change if the mask should have another color then white */
z-index: 10000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div id="preloader">
<canvas id="noise" class="noise"></canvas>
</div>
Set the position of body as fixed and when the page is loaded, remove that.
document.body.style.position = "fixed";
window.addEventListener("load", () => {
document.body.style.position = "";
document.querySelector(".preloader").style.display = "none";
});

Full page view on single scroll move to next section

I have tried to create single scroll and move to next section, I have using javascript, It is not working fine, The window top distance not giving properly, I need to div fullscreen moved to next screen, Please without jquery, Please help
if (window.addEventListener) {window.addEventListener('DOMMouseScroll', wheel, false);
window.onmousewheel = document.onmousewheel = wheel;}
function wheel(event) {
var delta = 0;
if (event.wheelDelta) delta = (event.wheelDelta)/120 ;
else if (event.detail) delta = -(event.detail)/3;
handle(delta);
if (event.preventDefault) event.preventDefault();
event.returnValue = false;
}
function handle(sentido) {
var inicial = document.body.scrollTop;
var time = 500;
var distance = 900;
animate({
delay: 0,
duration: time,
delta: function(p) {return p;},
step: function(delta) {
window.scrollTo(0, inicial-distance*delta*sentido);
}
});
}
function animate(opts) {
var start = new Date();
var id = setInterval(function() {
var timePassed = new Date() - start;
var progress = (timePassed / opts.duration);
if (progress > 1) {progress = 1;}
var delta = opts.delta(progress);
opts.step(delta);
if (progress == 1) {clearInterval(id);}}, opts.delay || 10);
}
body{
width: 100%;
height: 100%;
margin:0;
padding:0;
}
.wrapper{
width: 100%;
height: 100%;
position: absolute;
}
section{
width: 100%;
height: 100%;
}
.pg1{
background: green;
}
.pg2{
background: blue;
}
.pg3{
background: yellow;
}
<div class="wrapper" id="myDiv">
<section class="pg1" id="sec1"></section>
<section class="pg2"></section>
<section class="pg3"></section>
</div>
Return the height of the element and store it in distance variable, instead of giving it a static 900.
From this:
var distance = 900;
To this:
var distance = document.getElementById('sec1').clientHeight;

How to reset a webpage with a button

I am having trouble with some programming that I want to perform..
On my page there is a button called "resetButton" and it is invisible button in the middle of the page. It is using: z-index: 100 to be place in front of the images that appear behind it to appear to have the effect that you are actually clicking the image to perform the action.
This buttons functionality is to reset the entire race, including: the stoplight switching back to red, the winner image going away, and the two participants in the race begin again at the starting position.
I feel as I am just overthinking this problem and cannot figure it out and would appreciate being led in the right direction.
// script to show and hide winner
function showFish() {
document.getElementById('bluefishwin').style.visibility = "visible";
}
function showTurtle() {
document.getElementById('turtlewins').style.visibility = "visible";
}
function showFishText() {
document.getElementById('fishwins').style.visibility = "visible";
}
function showTurtleText() {
document.getElementById('turtlewinss').style.visibility = "visible";
}
// script to call both functions to start race
function letsRace() {
startTimer();
myMove();
}
// script for stoplight
function displayNextImage() {
document.getElementById("stoplight").src = images[1];
}
function startTimer() {
setInterval(displayNextImage);
}
var images = [],
x = -1;
images[0] = "http://www.drivingtesttips.biz/images/traffic-light-red.jpg";
images[1] = "http://www.drivingtesttips.biz/images/traffic-lights-green.jpg";
// script for race
function myMove() {
var elemBluefish = document.getElementById("bluefish");
var elemTurtle = document.getElementById("turtle");
var posBluefish = 0;
var posTurtle = 0;
var id = setInterval(frame, 5);
function frame() {
if (posBluefish >= 1150 && posTurtle >= 1150) {
clearInterval(id);
return;
}
if (posBluefish < 1140) {
posBluefish += Math.round(Math.random() * 5);
if (posBluefish > 1140) {
posBluefish = 1140;
}
elemBluefish.style.left = posBluefish + 'px';
}
if (posTurtle < 1140) {
posTurtle += Math.round(Math.random() * 5);
if (posTurtle > 1140) {
posTurtle = 1140;
}
elemTurtle.style.left = posTurtle + 'px';
}
if (posBluefish >= 1140 || posTurtle >= 1140) {
clearInterval(id);
if (posBluefish >= 1140 && posTurtle < 1140) {
showFish();
showFishText();
} else if (posBluefish < 1140 && posTurtle >= 1140) {
showTurtle();
showTurtleText();
} else {
window.alert("Tie");
}
return;
}
}
}
#racePrompt {
position: absolute;
left: 10pc;
font-size: 20px;
}
.raceButton {
position: absolute;
width: 5pc;
right: 82pc;
height: 10pc;
z-index: 100;
background: transparent;
border: none !important;
font-size: 0;
}
body {
overflow: hidden;
}
#myStoplight {
position: absolute;
width: 10pc;
}
#bluefish {
position: absolute;
top: 31pc;
width: 17pc;
left: -.5pc;
}
#turtle {
position: absolute;
width: 15pc;
top: 20pc;
left: .5pc;
}
body {
background-image: url("http://www.hpud.org/wp-content/uploads/2015/08/WaterBackground2.jpg")
}
.finishline {
position: absolute;
right: -12pc;
top: 18pc;
}
#stoplight {
position: absolute;
width: 10pc;
}
#bluefishwin {
position: absolute;
right: 31pc;
top: 12pc;
visibility: hidden;
}
#turtlewins {
position: absolute;
width: 20pc;
right: 35pc;
top: 15pc;
visibility: hidden;
}
#fishwins {
font-size: 3pc;
position: absolute;
right: 35pc;
top: 25pc;
visibility: hidden;
}
#turtlewinss {
font-size: 3pc;
position: absolute;
right: 34pc;
top: 26pc;
visibility: hidden;
}
<input type="button" onclick="letsRace()" class="raceButton">
<img id="stoplight" src="http://www.drivingtesttips.biz/images/traffic-light-red.jpg" />
<p id="fishwins">The Fish Wins!</p>
<p id="turtlewinss">The Turtle Wins!</p>
<p id="racePrompt">Click anywhere on the light to start the race!</p>
<img id="bluefish" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtle" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<img src="https://t1.rbxcdn.com/877010da8ce131dfcb3fa6a9b07fea89" class="finishline">
<img id="bluefishwin" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtlewins" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<div id="container">
<div id="animate"></div>
Any ideas on how to create a function so when I call it with an onClick I can reset everything back to as if I just rendered the page, similar to hitting the refresh button on the web browser.
Well, this practically impossible.
In order to make this work you would have to move state out of the DOM.
To do that, you must specified the Model of you application and just let the UI to render around it. You can imagine it like this:
var ui = createDOM(state)
body.innerHTML = ''
body.appendChild(ui)
//and you state might look like
var state = {
players: [{id: 'turle', winner: true}]
}
//in createDOM fn
function createDOM(state) {
var turtleWinnerDiv = document.createElement('div')
if (state.players[0].winner) {
turtleWinnerDiv.style.visibility = 'visible'
}
return turtleWinnerDiv
}
This is like "nic" way of doing this.
Uglier one might be something like this:
// save original app DOM
var defaultHTML = document.body.innerHTML
// at the end
document.body.innerHTML = defaultHTML
// voila App is back to default state

Empty space appearing at the end of my carousel

I have used this script to create an infinite carousel on my website here. It's been customized with CSS so the first and last items are displayed half way.
If you keep clicking the right arrow, you will end up hitting an empty space at the end. So far I haven't been able to fix this. Can anybody offer any solutions?
Here is the relevant script:
/**
* #author Stéphane Roucheray
* #extends jquery
*/
jQuery.fn.simplecarousel = function(previous, next, options){
var sliderList = jQuery(this).children()[0];
if (sliderList) {
var increment = jQuery(sliderList).children().outerWidth(true),
elmnts = jQuery(sliderList).children(),
numElmts = elmnts.length,
sizeFirstElmnt = increment,
shownInViewport = Math.round(jQuery(this).width() / sizeFirstElmnt),
firstElementOnViewPort = 1,
isAnimating = false;
for (i = 0; i < shownInViewport; i++) {
jQuery(sliderList).css('width',(numElmts+shownInViewport)*increment + increment + "px");
jQuery(sliderList).append(jQuery(elmnts[i]).clone());
}
jQuery(previous).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort == 1) {
jQuery(sliderList).css('left', "-" + numElmts * sizeFirstElmnt + "px");
firstElementOnViewPort = numElmts;
}
else {
firstElementOnViewPort--;
}
jQuery(sliderList).animate({
left: "+=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
jQuery(next).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort > numElmts) {
firstElementOnViewPort = 2;
jQuery(sliderList).css('left', "0px");
}
else {
firstElementOnViewPort++;
}
jQuery(sliderList).animate({
left: "-=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
}
};
#home-carousel-container {
position: relative;
}
#home-carousel {
overflow: hidden;
}
#home-carousel ul {
margin-left: -143px;
padding: 0;
position: relative;
}
#home-carousel li {
float: left;
height: 645px;
list-style: none outside none;
margin: 0 3px;
width: 256px;
}
As per my comment.
You have set a negative left-margin on your carousel causing it to hide half of an image. As a result when you click next/previous, it shows where an image is moved to create the continuous affect.
Witihin your css, I changed
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -143px;
}
to
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -3px;
}
And had no problems what so ever.

Categories