How do I make this fade in/out infinite? - javascript

this code fades in and fades out the div #shape while the start variable is true.
when i call the "start" method from event "click" the browser stops working because the while inside method is infinitive and "click" event does not finish until "start" method is done.
i want the method to run after the "click" event is finished.
what should i do?
CSS
#shape {
background-color:red;
width:100px;
height:100px;
display:none;
}
HTML
<div id="shape"></div>
<button id="startButton">start game!</button>
JS
var start = false;
$("#startButon").click(function () {
start = true;
startGame();
});
function startGame() {
while (start == true) {
$("#shape").fadeIn(1000).delay(1000).fadeOut(1000);
}
}

You don't need the flag, just make a recursive function. I changed the time to 300 milliseconds so you can see it easier
http://jsfiddle.net/zfbptz9c/
$("#startButton").click(function () {
startGame();
});
function startGame() {
$("#shape").fadeIn(300, function () {
$("#shape").fadeOut(300, function () {
startGame();
});
});
}
The div will fade in and on complete of the fade in, it will fade out then call the startGame function again and the entire process will repeat infinitely.
Alternatively, this can be achieved with css only if you only need to target modern browsers. I will put this fiddle link here, it is from a different question. I won't paste the code since you did not tag the question with css but the fiddle shows everything. I take no credit for it.
How can I create a looping fade-in/out image effect using CSS 3 transitions?
http://jsfiddle.net/FTLJA/261/

JavaScript runs in a single threaded environment, meaning once you enter an infinite loop, you can only quit the loop from within it. In synchronous execution, like the one you have here, no code outside the loop can affect the loop condition.
As far as your problem, people suggested solutions such as making a recursive function or using CSS3 transitions.
Another possible way could be to use timing functions like setTimeout and/or setInterval
The code bellow will make the fadeIn/Out happen after every second, after start button is clicked and until stop button is clicked.
var toggle = true; // flag for animation direction
var shape = $("#shape"); // so we don't select the shape each time we animate
var duration = 1000; // animation duration
var delay = 1000; // delay between animations
var timerId; // timer id returned by setInterval
// start animating the shape after the delay
$("#startButton").click(function() {
timerId = setInterval(animate, delay);
});
// stop animating the shape and hide it
$("#stopButton").click(function() {
clearInterval(timerId);
shape.css('display', 'none');
});
// function that animates the shape depending on the toggle flag
function animate() {
if (toggle) {
shape.fadeIn(duration);
toggle = false;
} else {
shape.fadeOut(duration);
toggle = true;
}
}
#shape {
background-color: red;
width: 100px;
height: 100px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="shape"></div>
<button id="startButton">start game!</button>
<button id="stopButton">stop game!</button>

Related

onmousedown/onmouseup function not working

I have a rectangle I am trying to move using javascript. I can get it to move left and right using functions, but when I hold the mouse down it doesn't continue to move. Here is my html code:
<button onmousedown="moveLeft();" onmouseup="stopMove();">LEFT</button>
<button onmousedown="moveRight();"
onmouseup="stopMove();">RIGHT</button><br><br>
Here is my javascript code (the conditional statements are just so the rectangle doesn't move off of the canvas):
function moveLeft () {
xx-=20;
if (xx<0) {
xx=0;
}
}
function moveRight() {
xx+=20;
if (xx>400) {
xx=400;
}
}
function stopMove () {
xx+=0;
}
When you press a mouse button, the mousedown event will fire just once. It does not continuously fire while you have the button held down. What you'll need to do is use a timer to begin the movement and then, on mouseup, stop the timer.
Also, don't use inline HTML event handlers (onmouseover, onmouseout, etc.). Here's why.
Lastly, since your moveLeft and moveRight functions are essentially the same thing, they can be combined into one function that simply takes in an argument that determines the direction.
Here's a working example:
// Get references to the HTML elements you'll need to interact with:
var btnLeft = document.getElementById("btnLeft");
var btnRight = document.getElementById("btnRight");
var box = document.getElementById("box");
// Set up event handlers for the HTML elements in JavaScript, using modern
// standards, not in the HTML. Both the left and right buttons need to
// call the same function, but with a different argument value. This is
// why the events are being bound to another function that wraps the actual
// call to the move function (so that an argument can be passed).
btnLeft.addEventListener("mousedown", function(){ move(-20); });
btnRight.addEventListener("mousedown", function(){ move(20); });
btnLeft.addEventListener("mouseup", stopMove);
btnRight.addEventListener("mouseup", stopMove);
// The counter needs to be accessible between calls to move
var xx = 0;
// We'll start an automatic timer, but we'll need to stop it later
// so we need a variable set up for that.
var timer = null;
// Only one function is needed to address the move operation
// The argument is what determines the direction
function move(amount) {
// Stop any previous timers so that we don't get a runaway effect
clearTimeout(timer);
xx += amount;
// Check the new position to see if it is off the visible page
if (xx < 0){
xx = window.innerWidth;
} else if(xx > window.innerWidth){
xx = 0;
}
// Just displaying the current value
box.textContent = xx;
// Move the box to the new location
box.style.left = xx + "px";
// Run the timer after a 250 millisecond delay and have
// it call this function again. Assign the variable to
// the timer.
timer = setTimeout(function() { move(amount) }, 250);
}
function stopMove () {
xx += 0;
// Stop the timer
clearTimeout(timer);
}
#box {
background-color:blue;
border:2px solid black;
color:yellow;
text-align:center;
font-weight:bold;
padding-top:.5em;
margin-top:3em;
/* Everything above is just for display and not actually needed.
But in order to move the box and to be able to have a consistent
size for it, the following is required: */
position:absolute;
height:50px;
width:50px;
}
<button id="btnLeft">LEFT</button>
<button id="btnRight">RIGHT</button>
<div id="box"></div>
Since the mouse evet does not fire while it is down, you need to fire the event manually until you detect the other event. So to do this, you need to either use setInterval or setTimeout
var moveTimer,
xx = 200;
function move (dir) {
xx+=20*dir;
if (xx<0) {
xx=0;
} else if (xx>400) {
xx=400
}
stopMove()
moveTimer = window.setTimeout(move.bind(this,dir), 100)
document.getElementById("out").value = xx;
}
function stopMove () {
if(moveTimer) window.clearTimeout(moveTimer);
moveTimer = null
}
window.addEventListener("mouseup", stopMove)
<button onmousedown="move(-1);">LEFT</button>
<button onmousedown="move(1);">RIGHT</button>
<input type="number" id="out"/>

How to show divs when the mouse moves anywhere on screen, not just the element itself?

I managed to hide and show my classes when the user moves his mouse over the specific element. But what I would actually like is that these show when the user moves his mouse anywhere on the screen, not just the selected div's.
This is my current code:
$(window).on('mousemove', function () {
$('.barhide').addClass('show');
try {
clearTimeout(timer);
} catch (e) {}
timer = setTimeout(function () {
$('.barhide').removeClass('show');
}, 1000);
});
And my css:
.barhide {
background: #333;
color: #fff;
display: block;
opacity: 0;
transition: all 1.5s ease;
}
.barhide.show {
opacity: 1;
display: none;
}
So what I would like is that after 3 seconds, the classes with .barhide get hidden and if the user moves his mouse anywhere in screen, they show up again, instead of just when they move over the element.
Also I was wondering if it's not a lot easier to do these things with React?
I have restructured the code a bit and added some comments explaining what's happening and when. Also, lose the try since attempting to clear a timer will never throw an exception.
Keep in mind that mouseover type events are an issue on mobile devices. These two articles may help in that regard:
JQuery's Virtual Mouse Events
Simulated Mouse Events using JQuery
$(function(){
// When page loads, wait 3 seconds and hide all elements with .barhide class:
setTimeout(toggle, 3000);
});
var timer = null;
// General function for adding/removing the "hide" class.
// This is used when the page first loads and each time
// the mouse moves on the page. We're not calling toggle()
// here because a flicker effect can happen which would leave
// the elements showing instead of being hidden.
function toggle(){
$('.barhide').toggleClass('hide');
}
$(window).on('mousemove', function(){
// When anywhere on page is moused over bring back .barhide
// elements for 3 seconds. Removing "hide" simply restores
// the original CSS & layout
$('.barhide').removeClass('hide');
// Kill any previous timers
clearTimeout(timer);
// Wait 3 seconds and hide again
timer = setTimeout(toggle, 3000)
});
.barhide { background-color:blue; }
.hide { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="barhide">ONE</div>
<div class="show">TWO</div>
You just count the nr of timers running and when the last finishes you hide the bar.
var count = 0;
$(window).mousemove(function( event ) {
$('.barhide').show();
count += 1;
setTimeout(function() {
if (count == 1) {
$('.barhide').hide();
}
count -= 1;
}, 3000);
});

How to Delay The First FadeIn Event On Slider

I am currently modifying this piece of code as apart of a project, it works fine for what I need it to do, however I want a relatively short transition period,but the initial div element only display for a brief moment and the fade process starts.
I was wondering if anyone could help me to correct this. Ideally I would like to set the initial slider timeframe or delay it from triggering the process,
var divs = $('.fade');
function fade() {
var current = $('.current');
var currentIndex = divs.index(current),
nextIndex = currentIndex + 1;
if (nextIndex >= divs.length) {
nextIndex = 0;
}
var next = divs.eq(nextIndex);
current.stop().fadeOut(500, function() {
$(this).removeClass('current');
setTimeout(fade, 5000);
});
next.stop().fadeIn(500, function() {
$(this).addClass('current');
});
}
fade();
To delay the function fade() from starting right away just do:
var divs = $('.fade');
function fade() {
....
}
setTimeout(fade, 5000); //here is the only change
At the end of your code fade() is executed right away. Just add a timeout to it. 5000 is in milliseconds, just switch that to the delay time you want.
Apart from your question, if you wanted to apply the fade function to objects only after you clicked them, you could do this.
$('.fade').on('click',function(){//instead of click you could use any event ex. mouseover
fade();//call fade function
});

One div to start contents to fadeToggle and another div to stop fadeToggle animation using javascript setInterval Function

My Fiddle:
http://jsfiddle.net/tmanundercover/62ap2/
CSS
#targetedDiv, #otherDiv {
border: 1px solid;
}
HTML
<div id="targetedDiv">&nbsp<span id="fakeCursor">|</span></div>
<br>
<div id="otherDiv">click here to stop</div>
Javascript
var fakeCursorInterval;
function startCursor(){
fakeCursorInterval = setInterval(function() {
$("#fakeCursor").fadeToggle("slow","swing");},20);
console.log("starting",fakeCursorInterval);
}
function stopCursor() {
clearInterval(fakeCursorInterval);
console.log("stopping",fakeCursorInterval);
}
$("#targetedDiv").click(function(){fakeCursorInterval = startCursor()});
$("#otherDiv").click(function(){stopCursor()});
console.log("outside",fakeCursorInterval);
My issue is that the console.log in stopCursor shows the interval as undefined.
I have looked at this post:
clear interval doesn't work
so i'm pretty sure this is a scope issue but I cannot figure it out my specific problem.
You're overriding the interval variable in your click handler.
$("#targetedDiv").click(function(){fakeCursorInterval = startCursor()});
This alone should work:
$("#targetedDiv").click(startCursor);
$("#otherDiv").click(stopCursor);
In addition to the issue mentioned by #koala_dev, the setInterval interval was 20, the fadeToggle interval was slow (which is 600). So, if you call stopCursor() after 1 second (1000 milliseconds), the fadeToggle would have been called 50 times. In that case, the fade animation will still last for 30 seconds (even that the setInterval have already been cleared). To resolve that issue, just use the same duration for both fadeToggle and setInterval (eg. 400 milliseconds). Additionally, you can call .stop() to stop the fade animation at the stopCursor(), and guarantee that it will really stop.
var fakeCursorInterval;
function startCursor() {
$("#fakeCursor").show().fadeToggle(400, "swing");
fakeCursorInterval = setInterval(function() {
$("#fakeCursor").fadeToggle(400,"swing");
}, 400);
console.log("starting", fakeCursorInterval);
}
function stopCursor() {
clearInterval(fakeCursorInterval);
$("#fakeCursor").hide().stop();
console.log("stopping", fakeCursorInterval);
}
$("#targetedDiv").click(startCursor);
$("#otherDiv").click(stopCursor);
console.log("outside", fakeCursorInterval);
See fiddle here.

How to use fadeOut jQuery property with Javascript Text Snippet

http://api.jquery.com/fadeOut/ <- fadeOut api
I'm trying to learn Javascript and I've been playing with a snippet I found on Codepen.
I'm having trouble trying to get the random text array snippet to have the text fadeOut when it transitions away to another text object. Right now, the array cycles through and randomly selects a string from the array using the Math.Random function (5*1) and it fades in each time a new text object loads in, however I want it to fade out and I don't think I'm utilizing the .fadeOut property properly. How can I get it so that the text fadesOut, so the text does fadeIn fadeOut, instead of fadeIn, insta kill?
var textTimer;
var inTransition = false;
startTimer();
function startTimer() {
clearTimeout(textTimer);
textTimer = setTimeout(changeTitle, 3500);
}
changeTitle();
var titleNumber = Math.floor(Math.random() * 5) + 1;
function changeTitle() {
var titleArray = [
"Test1",
"Test2",
"Test3",
"Test4",
"Test5"
];
var tempTitleLength = titleArray.length - 1;
if (inTransition == false) {
inTransition = true;
titleNumber++;
if (titleNumber > tempTitleLength){
titleNumber = 0
}
$('.text').html('');
$('.text').css({opacity: '0'});
$('.text').html(titleArray[titleNumber]);
$('.text').fadeOut();
$('.text').stop().delay(0).animate({
opacity: 1
}, 1500, function() {
inTransition = false;
startTimer.()
});
}
}
Thanks! :D
The HTML is pretty straight forward
<div class="text"></div>
Multiple problems:
$('.text').html('');
$('.text').css({opacity: '0'});
$('.text').html(titleArray[titleNumber]);
You are already removing the text in html('') without fading out,
setting css opacity to 0 without any delay, setting html new text without any animation.
There is a syntax error also startTimer.() I guess is typo.
Remove first 2 lines and set new text after fade out is done.
You also need to wait for fadeOut to finish before doing fadeIn.
So, sequence: fadeOut, set new text, fadeIn.
Like this:
$('.text').fadeOut(1500, function () {
$('.text').html(titleArray[titleNumber]);
$('.text').fadeIn(1500, function () {
inTransition = false;
startTimer()
});
});
JSFiddle: http://jsfiddle.net/Dzyzw/
You have syntax errors in your code: you have startTimer.() should be startTimer() and you did not close your startTimer function with a }. I corrected this for you and set up a sample JSFiddle for you review. Seems to be working otherwise.
Here is the sample JSFiddle: CLICK HERE
Here's what I think you're going for--
Set initial text.
Fade out your text.
Change the text.
Fade in the new text.
Wait a while, then return to step 2.
I would drop all the transition flags and use the optional callback functions that are fired when fadeOut and fadeIn complete to move from step to step, e.g.
$('.text').fadeOut(1000, function() {
$('.text').html(get_next_word());
$('.text').fadeIn(500);
});
Just fire that off on a timer that is 1500 milliseconds + the time you want the text to be fully visible.

Categories

Resources