Stop line by line javascript animation from looping - javascript

I'm currently working with a piece of javascript which fades in a paragraph of text line by line.
Javascript isn't by forte and I'm struggling to stop the animation from looping.
Any help and advice on how to achieve this would be great.
Here is a link to a fiddle https://jsfiddle.net/spittman/7wpqkfhj/5
Thanks!
Javascript
$(document).ready(function() {
function fadeInLine(line){
$('<span />', {
html: line.trim(),
style: "opacity: 0"
})
.appendTo($greeting)
.animate({opacity:1}, 500);
}
function rotateLines(interval){
setTimeout(() => {
if(i >= lines.length-1){
i = 0;
interval = 1500;
setTimeout(()=>{ $greeting.empty(); }, interval)
} else {
fadeInLine(lines[i]);
i++;
interval = 1500;
}
rotateLines(interval);
}, interval);
}
const $greeting = $('div#container p');
const text = $greeting.html();
const lines = text.split("\n").filter((e) => e.replace(/\s+/, ""));
let i = 0;
$greeting.empty();
rotateLines();
});
Html
<div id="container">
<p>
There’s another side to London.<br>
Beyond the jurisdiction of The City.<br>
Undiscovered by outsiders.<br>
Loved by insiders.<br>
An ever-changing place...<br>
That teases our wildside and thrills our artside.<br>
Blurs our workside into our playside.<br>
Where we live on the brightside.<br>
And explore our darkside.<br>
Hidden in plain sight, this is Bankside.<br>
London’s other side.<br>
.
</p>
</div>

Put the scheduled call in the else clause, and delete the greeting.empty() line.
function rotateLines(interval){
setTimeout(() => {
if(i >= lines.length-1){
i = 0;
interval = 1500;
// setTimeout(()=>{ $greeting.empty(); }, interval)
} else {
fadeInLine(lines[i]);
i++;
interval = 1500;
rotateLines(interval);
}
// rotateLines(interval);
}, interval);
}
JSFiddle
The animation stops after the whole text has faded in.

Simply get rid of the if-clause that resets the element and counter.
function rotateLines(interval){
setTimeout(() => {
fadeInLine(lines[i]);
i++;
interval = 1500;
rotateLines(interval);
}, interval);
}
JSFiddle

Related

how to stop function in 5 seconds? Vue.js

this is my code
setInterval(this.randomImage, 250);
setInterval(this.randomPosition, 250);
setInterval(this.addImage, 250);
i want to stop addImage function in 5 seconds because images are adding infinitely!
i tried to do it by this way
let timesRun = 0;
const intervalAddImage = setInterval(function () {
timesRun += 1;
if (timesRun === 60) {
clearInterval(intervalAddImage)
}
this.addImage();
}, 250);
intervalAddImage();
but it doesn't work...
i am using Vue.js!
The following code runs a task every 250ms and stops after 5sec. I hope this will give you some inspiration.
var intervalId = setInterval(() => console.log("running"), 250);
setTimeout(() => clearInterval(intervalId), 5000);
So it works)
let timesRun = 0; // just change to this
function addImage(timesRun) { console.log(timesRun)}
const intervalAddImage = setInterval(function () {
timesRun += 1; // just change to this
if (timesRun === 4) {
clearInterval(intervalAddImage)
return; // add this
}
addImage(timesRun);
}, 250);
Here is your mistake: do not use this without being careful: you should take time to understand how this works in JavaScript.
In your code, you increment this.timesRun, but you test on timesRun which is never incremented.
This sample will work as you expect:
let timesRun = 0;
//const addImage = this.addImage;
const intervalAddImage = setInterval(function () {
timesRun += 1;
if (timesRun === 60) {
clearInterval(intervalAddImage);
}
//addImage();
console.log("Hello", timesRun);
}, 250);

Run a setInterval function, stop it for 3 seconds and continue running it

I have a setInterval function going trough some div classes, if it finds a div with a particular class it should stop for 3 seconds and then continue running. Notice how I am using:
clearInterval(myInterval);
but I need something else, to start the sequence again or make it to continue running from there.
e.g:
var myInterval = setInterval(function() {
move.removeClass( "girlFromRight" );
runFromRight -= 9;
move = $("#grid"+ runFromRight);
move.addClass("girlFromRight");
if (move.hasClass("man") === true ||
move.hasClass("man-right") === true ||
move.hasClass("man-left") === true )
{
clearInterval(myInterval);
move.addClass('inLove');
move.removeClass('girlFromRight');
setTimeout(function() {
move.removeClass('inLove');
move.addClass('man');
}, 3000);
}
if (c == 9){
clearInterval(myInterval);
}
}, 300);
keyPressed = false;
}, randomTime);
}
Consider using setTimeout and setting the interval (300 or 3000) after each run based on a test. That way you don't have to start and stop setInterval.
A quick example is below, it highlights each div in sequence, pausing longer on any where the text content is evenly divisible by 3 (as an example test).
function doLoop(){
var divs = document.querySelectorAll('div');
var i = 0;
function loop(){
var selected = document.querySelectorAll('.selected');
[].forEach.call(selected,function(el) {
el.className = 'notSelected';
});
divs[i].className = 'selected';
setTimeout(loop, divs[i].textContent % 3? 300 : 3000);
i = ++i % (divs.length - 2);
}
loop();
}
window.onload = doLoop;
.notSelected{}
.selected{
background-color: blue;
}
<div class="notSelected">0</div>
<div class="notSelected">1</div>
<div class="notSelected">2</div>
<div class="notSelected">3</div>
<div class="notSelected">4</div>
<div class="notSelected">5</div>

how to make hide/show text javascript smoother?

I am using this script to hide and show text however, I want to make the transition smoother but I am not sure how to. Here's a demo of it: http://jsfiddle.net/LnE5U/.
Please help me change it to make it smoother.
hide/show text
<div id="showOrHideDiv" style="display: none">hidden text</div>
<script language="javascript">
function showOrHide()
{
var div = document.getElementById("showOrHideDiv");
if (div.style.display == "block")
{
div.style.display = "none";
}
else
{
div.style.display = "block";
}
}
</script>
Here is an example using jQuery's fadeToggle (a shortcut for a more complicated animate)
// assuming jQuery
$(function () { // on document ready
var div = $('#showOrHideDiv'); // cache <div>
$('#action').click(function () { // on click on the `<a>`
div.fadeToggle(1000); // toggle div visibility over 1 second
});
});
HTML
<a id="action" href="#">hide/show text</a>
<div id="showOrHideDiv" style="display: none;">hidden text</div>
DEMO
An example of a pure JavaScript fader. It looks complicated because I wrote it to support changing direction and duration mid-fade. I'm sure there are still improvements that could be made to it, though.
function generateFader(elem) {
var t = null, goal, current = 0, inProgress = 0;
if (!elem || elem.nodeType !== 1) throw new TypeError('Expecting input of Element');
function visible(e) {
var s = window.getComputedStyle(e);
return +!(s.display === 'none' || s.opacity === '0');
}
function fader(duration) {
var step, aStep, fn, thisID = ++current, vis = visible(elem);
window.clearTimeout(t);
if (inProgress) goal = 1 - goal; // reverse direction if there is one running
else goal = 1 - vis; // else decide direction
if (goal) { // make sure visibility settings correct if hidden
if (!vis) elem.style.opacity = '0';
elem.style.display = 'block';
}
step = goal - +window.getComputedStyle(elem).opacity;
step = 20 * step / duration; // calculate how much to change by every 20ms
if (step >= 0) { // prevent rounding issues
if (step < 0.0001) step = 0.0001;
} else if (step > -0.0001) step = -0.0001;
aStep = Math.abs(step); // cache
fn = function () {
// console.log(step, goal, thisID, current); // debug here
var o = +window.getComputedStyle(elem).opacity;
if (thisID !== current) return;
if (Math.abs(goal - o) < aStep) { // finished
elem.style.opacity = goal;
if (!goal) elem.style.display = 'none';
inProgress = 0;
return;
}
elem.style.opacity = (o + step).toFixed(5);
t = window.setTimeout(fn, 20);
}
inProgress = 1; // mark started
fn(); // start
}
return fader;
}
And using it
window.addEventListener( // this section matches the code above
'load',
function () {
var fader = generateFader(document.getElementById('showOrHideDiv'));
document.getElementById('action').addEventListener(
'click',
function () {
fader(1000);
}
);
}
);
DEMO of this
This is quite simple. I have just made a demo and i used setInterval
Here's how it works
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
}
}, 50);
};
JSFiddle Demo Link
Steps
Create a function that accepts a DOM element
Set the opacity of the element to 1
Create a function that loops every 50ms
If the opacity is greater than 0 -> continue
Take away 0.01 from the opacity
if it's less than 0 the animation is complete and hide it completely
Note this is a really simple example and will need a bit of work
You can use somthing like this
$('.showOrHideDiv').toggle(function() {
$('showOrHideDiv').fadeIn('slow', function() {
//fadeIn or fadeOut, slow or fast, all the stuffs you want to trigger, "a function to execute every odd time the element is clicked," says the [jquery doc][1]
});
}, function() {
//here comes "additional handlers to cycle through after clicks," says the [jquery doc][1]
});
I used OPACITY to make it show/hide. See this Example, Full code (without jQuery):
Click here
<div id="MyMesage" style="display:none; background-color:pink; margin:0 0 0 100px;width:200px;">
blablabla
</div>
<script>
function ShowDiv(name){
//duration of transition (1000 miliseconds equals 1 second)
var duration = 1000;
// how many times should it should be changed in delay duration
var AmountOfActions=100;
var diiv= document.getElementById(name);
diiv.style.opacity = '0'; diiv.style.display = 'block'; var counte=0;
setInterval(function(){counte ++;
if ( counte<AmountOfActions) { diiv.style.opacity = counte/AmountOfActions;}
},
duration / AmountOfActions);
}
</script>
I followed iConnor solution and works fine but it had a small issue setInterval will not stop after the element be hidden I added stop interval to make it better performance
var fadeout = function( element ) { // 1
element.style.opacity = 1; // 2
let hidden_process = window.setInterval(function() { // 3
if(element.style.opacity > 0) { // 4
element.style.opacity = parseFloat(element.style.opacity - 0.01).toFixed(2); // 5
} else {
element.style.display = 'none'; // 6
console.log('1');
clearInterval(hidden_process);
}
}, 50);
};

need to reset the function how do i do it

I want to reset this flash in between so that i need not have to wait till the end to restart the flash, how do i reset this?
function flash() {
var arrayId = 0,
splitSet = $('#text_original').html().split(" "),
splitSetLength = splitSet.length;
function flashWord() {
$("#flash_word").html(splitSet[arrayId]);
arrayId += 1;
var t = setTimeout(remove, 1000);
}
function remove() {
if (arrayId < splitSetLength) {
$("#flash_word").html(" ");
flashWord();
} //else reset_flash();
}
flashWord(); }
please see the http://jsfiddle.net/HcDfS/
Make the timer variable a global one and cancel the time-out on it (with clearTimeout()). Then, hide #flash_word.
I took the liberty of re-implementing your fiddle:
var timer, words;
function startFlashing() {
words = $("#source").text().split(" ");
showNextWord(0);
}
function stopFlashing() {
clearTimeout(timer);
$("#banner").text("");
}
function showNextWord(index) {
$("#banner").text(words[index]);
index++;
if (index < words.length) timer = setTimeout(function () {
showNextWord(index);
}, 1000);
else $("#banner").text("");
}
​
With HTML:
<p id="source">This is the text to be flashed.</p>
<button onclick='startFlashing()'>Start Flashing!</button>
<button onclick='stopFlashing()'>Stop Flashing!</button>
<p id="banner"></p>​
And it's here: http://jsfiddle.net/CZnVc/6/

jQuery pause function on hover?

I have a jQuery/JS function that is using setInterval to loop through some image slides I have. It just flips through every 5 seconds...
Now I want it to pause if my mouse is hovered over it. How do I go about doing that on the setInterval function?
var current = 1;
function autoAdvance() {
if (current == -1) return false;
jQuery('#slide_menu ul li a').eq(current % jQuery('#slide_menu ul li a').length).trigger('click', [true]);
current++;
}
// The number of seconds that the slider will auto-advance in:
var changeEvery = jQuery(".interval").val();
if (changeEvery <= 0) {
changeEvery = 10;
}
var itvl = setInterval(function () {
autoAdvance()
}, changeEvery * 1000);
Something like this would work assuming interval is defined in an outer scope:
$('.slideshow img').hover(function() {
interval = clearInterval(interval);
}, function() {
interval = setInterval(flip, 5000);
});
(function () {
var imgs = $('#your_div img'), index = 0, interval,
interval_function = function () {
imgs.eq(index).hide();
index = (index + 1) % imgs.length;
imgs.eq(index).show();
};
imgs.eq(0).show();
interval = setInterval(interval_function, 5000);
$('#your_div').hover(function () {
clearInterval(interval);
}, function () {
interval = setInterval(interval_function, 5000);
});
}());
Example: http://jsfiddle.net/Zq7KB/3/
I reused some old code I wrote for a question the other day, but I figured it didn't matter that much. The trick is to store your interval in a variable that you keep in the background. Then, when you hover over the container, clear the interval. When you hover out of the container, re-set the interval. To get a better feel of how this works, change those 5000s to 1000s so it passes more quickly for testing.
Hope this helps.

Categories

Resources