Currently I have a simple fire animation. It just show two flames tongues in same place and show hide within 0.3s. Right now I want set delays. After few milliseconds, stop the loop and start again like that. I tried with javascript setInterval but it's continuously running.
var $wrapper = $('.wrapper');
setInterval(function() {
$wrapper.toggleClass("alt");
}, 300);
.wrapper {
text-align: center;
position: relative;
}
.flames,
.wrapper-img,
.show-1,
.show-2 {
position: absolute;
}
.flames {
display: none;
}
.flame-1 {
left: 38px;
top: 32px;
}
.flame-2 {
left: 67px;
top: 40px;
}
.flame-2 img {
top: 220px;
}
.wrapper-img {
top: 220px;
}
.wrapper .flame-1 {
display: block;
}
.wrapper .flame-2 {
display: none;
}
.wrapper.alt .flame-1 {
display: none;
}
.wrapper.alt .flame-2 {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="flame-1 flames">
<img src="https://i.imgur.com/0Pfsrdh.png" alt="">
</div>
<div class="flame-2 flames">
<img src="https://i.imgur.com/EypytyC.png" alt="">
</div>
<div class="wrapper-img">
<img src="https://i.imgur.com/moNtPwG.png" class="wrap-img" alt="">
</div>
</div>
Any solution? Jsfiddle
As far as I see you need soething like this
var $wrapper = $('.wrapper');
function flamebaby(){
$wrapper.toggleClass("alt");
setTimeout(function() {
$wrapper.toggleClass("alt");
setTimeout(function() {
flamebaby();
},600)
}, 200);
}
flamebaby();
https://jsfiddle.net/uy43w5qq/7/
You are probably looking for CSS keyframe animations which will let you run keyframe based transitions/animations without the need of JavaScript. This will also ensure that the browser can do optimizations for your animations, they will probably run smoother.
JS based answers are already provided so I'm not going in there except for a small sidenote on setInterval.
Using setInterval() is not recommended since the body function theoretically may take longer than the interval causing a stackoverflow. A better way is to use setTimeout to call a function, which at the end of executions schedules a new timeout for itself.
const foo = () => {
console.log('bar');
setTimeout(foo, 300);
}
setTimeout(foo, 300);
Also, when animating is may be useful to first use pen and paper to write down how the animations should behave, this may help when writing the code to implement them.
I'm not sure, if i understand correctly, but what you want is this ?
var $wrapper = $('.wrapper');
function startAnimation () {
var animationCount = 4
var iterationCount = 0
var intervalValues = {
animation: 300,
loops: 900
}
function toggleAlt () {
$wrapper.toggleClass("alt");
iterationCount++
if (iterationCount > 0 && iterationCount % animationCount === 0) {
setTimeout(toggleAlt, intervalValues.loops)
} else {
setTimeout(toggleAlt, intervalValues.animation)
}
}
toggleAlt();
}
startAnimation()
i've tried to keep simple, Fiddle: https://jsfiddle.net/50gemkrk/
Toggle class few times with interval of few ms.
Wait for few ms.
Repeat first step: Toggle class few times with interval of few ms
IMHO,
I might be wrong, but setIntervals is not recommended in most of cases, it's easy to lose control
Also, i agree with Sven's answer, CSS3 Animation is cool, i recomend it !
Related
This is a very basic question, and for some reason I am having a hard time wrapping my brain around it. I am new and learning so bear with me please.
Here is a progress bar: https://codepen.io/cmpackagingllc/pen/ZNExoa
When the bar has loaded completely it adds the class completed as seen on js line 41.
progress.bar.classList.add('completed');
So say once completed I want to add an Alert that say's "completed". I assume this would be an easy task but because of the way the code is written with the loop seen on line 46/47
loop();
}, randomInterval);
I am unable to incorporate the Alert properly without an alert loop even when I used return false to stop the loop afterwards.
So the route I am trying to take now is to add the alert prompt to the success function found on line 21-25
function success() {
progress.width = progress.bar.offsetWidth;
progress.bar.classList.add('completed');
clearInterval(setInt);
alert("Completed!");
}
But now I am stuck trying to format it correctly so when the if is called on line 36
if (progress.width >= progress.bar.offsetWidth) {
When the if is called on line 36 I want to to jump to the success function instead. No matter how I try it the code fails to execute. How would I format this correctly so it jumps to my function instead of looping after completed?
I would greatly appreciate some assistance with this. I am trying to understand if there is a better way to add the alert. Thank you much.
I read your code with special attention because recently I have been working with some loading bars (but not animated ones).
The problem is that you are using setTimeout() and not setInterval(), so calling clearInterval() has no effect at all. And you really don't need setInterval() because you're already making recursive calls (looping by calling the same function from its body).
I've took the liberty of rewriting your code for you to analyse it. Please let me know if you have any doubts.
NOTE: It's easier in this case to use relative units for the width! So you don't have to calculate "allowance".
let progress = {
fill: document.querySelector(".progress-bar .filler"),
bar: document.querySelector(".progress-bar"),
width: 0
};
(function loop() {
setTimeout(function () {
progress.width += Math.floor(Math.random() * 50);
if (progress.width >= 100) {
progress.fill.style.width = '100%';
progress.bar.classList.add('completed');
setTimeout(function () {
alert('COMPLETED!');
}, 500);
} else {
progress.fill.style.width = `${progress.width}%`;
loop();
}
}, Math.round(Math.random() * (1400 - 500)) + 500);
})();
Like a comment said, there are several timers in your code. Also, success was never executed. Here you have a version that works.
If you are learning, try to make your code as simple as possible, use pseudocode to see in wich step there is an error and try debugging from there.
var progress = {
fill: document.querySelector(".progress-bar .filler"),
bar: document.querySelector(".progress-bar"),
width: 0 };
function setSize() {
var allowance = progress.bar.offsetWidth - progress.width;
var increment = Math.floor(Math.random() * 50 + 1);
progress.width += increment > allowance ? allowance : increment;
progress.fill.style.width = String(progress.width + "px");
}
function success() {
progress.width = progress.bar.offsetWidth;
progress.bar.classList.add('completed');
alert("Completed!");
}
(function loop() {
var randomInterval = Math.round(Math.random() * (1400 - 500)) + 500;
var setInt = setTimeout(function () {
setSize();
if (progress.width >= progress.bar.offsetWidth) {
success();
} else {
loop();
}
}, randomInterval);
})();
.progress-bar {
height: 10px;
width: 350px;
border-radius: 5px;
overflow: hidden;
background-color: #D2DCE5;
}
.progress-bar.completed .filler {
background: #0BD175;
}
.progress-bar.completed .filler:before {
opacity: 0;
}
.progress-bar .filler {
display: block;
height: 10px;
width: 0;
background: #00AEEF;
overflow: hidden;
transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);
}
.progress-bar .filler:before {
content: '';
display: block;
background: repeating-linear-gradient(-45deg, #00AEEF, #00AEEF 10px, #23c3ff 10px, #23c3ff 20px);
height: 10px;
width: 700px;
border-radius: 5px;
animation: fill 10s linear infinite;
}
#keyframes fill {
from {
transform: translatex(-350px);
}
to {
transform: translatex(20px);
}
}
<div class="progress-bar">
<span class="filler"></span>
</div>
take a time To look at this website http://www.thejewelrysource.net/ and stay for like 7 seconds in the bottom left corner there is a small pop up that will appear and disappear again I want to do something like that using Jquery.
I know I could use Slideup and SlideDown Method but the problem I am facing is that How could traverse to the Given data in an Array so that I will Pop up the Data One at a Time. I am using only Static Data. Thank you for your Help in Advance! may someone help me! Thank You So Much
I couldn't understand much from your description. By any chance is this what are you looking are?
I have used setTimeout and setInterval to simulate this and a closure variable to keep track of the next item to display.
$(document).ready(function() {
var $popup = $(".popup"),
aMessages = ["Hello", "This is alert", "Is this what are you look for?"],
counter = 0;
$(".popup").hide();
var interval = setInterval(showMessage, 3000);
function showMessage() {
var iMessageId = counter % aMessages.length;
$popup.text(aMessages[iMessageId]);
$popup.show();
counter++
setTimeout(hideMessage, 1000);
}
function hideMessage() {
$(".popup").fadeOut(100);
}
setTimeout(function() {
clearInterval(interval);
}, 10000);
});
.popup {
width: 200px;
height: 100px;
background-color: yellow;
border-radius: 50px;
padding: 20px;
position: fixed;
left: 10px;
bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="popup"></div>
I am working with jquery on my page, I want when ever user click on a button an image will show loading for 1 second before the main content appears
Here is my code:
<script>
$(document).ready(function(){
$("#UseractivityLog").click(function(){
$(".UserProfileLogs-cont").html("<img src='image/loading.gif'/>");
//Then for 1/2 seconds this UserProfileLogs will display
$(".UserProfileLogs").toggle();
});
$("#IdealLog").click(function(){
$(".UserProfileLogs-con").toggle();
});
});
</script>
Here is my HTML part
Logs
<div id="UserProfileLogs-cont">
<div id="IdealLog"></div>
<div id="UserProfileLogs"></div>
</div>
Please i will appreciate jsfiled sample
You have some selector inconstancies, make sure you are watching those (# instead of .).
For the pause, use setTimout():
$(document).ready(function(){
$("#UseractivityLog").click(function(){
$("#UserProfileLogs-cont").html("Loading...");
setTimeout(function() {
$("#UserProfileLogs-cont").html("<img src='http://placehold.it/350x150'>");
}, 1000);
//Then for 1/2 seconds this UserProfileLogs will display
$(".UserProfileLogs").toggle();
});
$("#IdealLog").click(function(){
$("#UserProfileLogs-cont").toggle();
});
});
Fiddle: https://jsfiddle.net/Lqgum8hu/
For your comment:
//Then for 1/2 seconds this UserProfileLogs will display
Use another timeout:
setTimeout(function() {
// Whatever...
}, 500);
I changed your HTML a little to present the examples, but it can be changed to however you want it without changing the Javascript.
You can use setTimeout to update the image source after n seconds.
Also you can achieve this using single div and an nested img without using separate container for loading icon and image.
Hope this below snippet will be useful
HTML
Logs
<div id="UserProfileLogs-cont">
<img src="">
</div>
JS
$(document).ready(function(){
var _gif = "http://assets.motherjones.com/interactives/projects/features/koch-network/shell19/img/loading.gif";
var _forest="http://www.discovertheforest.org/images/hero/home/6.jpg";
$("#UseractivityLog").click(function(){
$("#UserProfileLogs-cont img").attr("src",_gif);
setTimeout(function(){
$("#UserProfileLogs-cont img").attr("src",_forest);
},3000)
});
});
Check this jsfiddle
You can wait until the body is ready:
function onReady(callback) {
var intervalID = window.setInterval(checkReady, 1000);
function checkReady() {
if (document.getElementsByTagName('body')[0] !== undefined) {
window.clearInterval(intervalID);
callback.call(this);
}
}
}
function show(id, value) {
document.getElementById(id).style.display = value ? 'block' : 'none';
}
onReady(function () {
show('page', true);
show('loading', false);
});
#page {
display: none;
}
#loading {
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100vw;
height: 100vh;
background-color: rgba(192, 192, 192, 0.5);
background-image: url("http://i.stack.imgur.com/MnyxU.gif");
background-repeat: no-repeat;
background-position: center;
}
Here is a JSFiddle that demonstrates this technique.
I am currently learning JavaScript and all the solutions that I've come across use the jQuery library. Is there a way to do it, just using pure JavaScript?
The idea is to have something like:
function passed(element) {if passed: do something}
Listen for the scroll event. To find the current scroll position, you can call the scollY method.
To get the Y coordinate of the top of an element, you can use the element's offsetTop. Because the element has a height, we want to add the height to our calculation.
That's it.
window.addEventListener("scroll", function() {
var elementTarget = document.getElementById("section-2");
if (window.scrollY > (elementTarget.offsetTop + elementTarget.offsetHeight)) {
alert("You've scrolled past the second div");
}
});
.section-1 {
height: 400px;
width: 100%;
background: green;
}
.section-3 {
height: 400px;
width: 100%;
background: orange;
}
<div class="section-1"></div>
<div id="section-2">Scroll past this div</div>
<div class="section-3"></div>
You should be able to use the following:
if(window.scrollY >(element.offsetHeight + element.offsetTop)){
// do something
}
With https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop you can get the Y coordinate of an element.
With https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY you can get the current Y coordinate of the scroll.
With https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight you get the height of an element.
So the only thing that remains to do is to check if scrollY > (offsetHeight + offsetTop). If this is true, you passed the element with the scroll.
I leave to you the implementation, as a practice to learn Javascript ;)
if (element.getBoundingClientRect().y < 0) {
// do something
}
This can be achieved with the IntersectionObserver API without having to rely on scroll events at all.
const elementTarget = document.getElementById("section-2");
// skip first callback when first observing
let firstCallback = true;
const observer = new IntersectionObserver(entries => {
if (!entries[0].isIntersecting) {
if (firstCallback) {
firstCallback = false;
} else {
alert("You've scrolled past the second div");
}
}
});
observer.observe(elementTarget);
// remember to unobserve when done
.section-1 {
height: 1000px;
width: 100%;
background: green;
}
.section-3 {
height: 1000px;
width: 100%;
background: orange;
}
<div class="section-1"></div>
<div id="section-2">Scroll past this div</div>
<div class="section-3"></div>
I have a kiosk application running on Ubuntu server 14.04.3 and chrome. Currently I have some code which hides the mouse if there was no movement for 2 seconds and once the user attempts to move the mouse again it shows up again. The trick is by using a cursor:none and adding an overlay:
js:
var body = $('body');
function hideMouse() {
body.addClass("hideMouse");
body.on('mousemove', function(){
if(window.hiding) return true;
window.hiding = true;
body.removeClass("hideMouse");
$('div.mouseHider').remove();
clearTimeout(window.hideMouse);
window.hideMouse = setTimeout(function(){
body.addClass("hideMouse");
$('<div class="mouseHider"></div>').css({
position: 'fixed',
top: 0,
left: 0,
height: '100%',
width: '100%',
zIndex: 99999
}).appendTo(body);
redraw(document.body);
setTimeout(function(){
window.hiding = false;
}, 100);
}, 4000);
});
}
function redraw(e) {
e.style.display = 'none';
e.offsetHeight;
e.style.display = 'block';
}
css:
body.hideMouse *, body.hideMouse{
cursor: none;
}
body.hideMouse *{
pointer-events: none !important;
}
This code works perfectly fine but there is only 1 caveat. When the page first loading it attempts to hide the mouse with the same trick but the mouse is still sticking there since it just didn't repainted the layer I guess. If I want it to work, I have to move the mouse a little bit and from then on it will work as expected and hide the mouse. The thing is that the kiosk application is restarting every day which means I boot the X display again and the mouse is being reset to the middle of the screen and it just sticks there until I move it a little bit. I hope you understand what I mean.
Do you guys have any idea how I can fix this?
You don't need all that code to do what you want. You could do:
Create a setTimeout to hide the cursor after 2s as soon as the page is loaded
When someone moves the mouse, you:
2.1. Show the cursor again
2.2. Clear the current setTimeout
2.3. And create the setTimeout to hide the cursor after 2s again.
The code below should work for you:
document.addEventListener('DOMContentLoaded', function() {
var cursorNone = document.getElementById('cursor-none');
var t = setTimeout(hideMouse, 2000);
document.addEventListener('mousemove', function(e) {
showMouse();
clearTimeout(t);
t = setTimeout(hideMouse, 2000);
});
function hideMouse() {
cursorNone.classList.remove('hidden');
}
function showMouse() {
cursorNone.classList.add('hidden');
}
});
#cursor-none {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
cursor: none;
background-color: transparent;
}
.hidden {
display: none;
}
<body>
<div id="cursor-none" class="hidden"></div>
</body>