Dynamically changing DIv - javascript

This is my first post here. I'm looking for some help.
I have multiple div contents which should fade in out and out dynamically. I have got this jsfiddle and made it work for 2 divs, but need it to work for multiple, for example 5 different DIVs.
Is this jsfiddle the best way to go or is there a better option. Here is the code. Here is the jquery.
var fadeinBox = $("#box2");
var fadeoutBox = $("#box1");
function fade() {
fadeinBox.stop(true, true).fadeIn(2000);
fadeoutBox.stop(true, true).fadeOut(2000, function() {
// swap in/out
var temp = fadeinBox;
fadeinBox = fadeoutBox;
fadeoutBox = temp;
// start over again
setTimeout(fade, 1000);
});
}
// start the process
fade();
Here is the html
<div id="wrapper">
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
</div>
and the CSS
.box {
position: absolute;
height: 100px;
width: 100px;
}
#wrapper {position: relative;}
#box1 {background-color: #F00;}
#box2 {background-color: #00F; display: none;}
Thank you in advance, and the link is below.
Dynamically changing DIV jsfiddle

You could use the same code but make it dynamic instead of two static elements:
var $boxes = $(".box").hide();
var current = 0;
function fade() {
$boxes.eq(current).stop(true, true).fadeOut(2000);
current = (current + 1) % $boxes.length;
$boxes.eq(current).stop(true, true).fadeIn(2000, function(){
setTimeout(fade, 1000);
});
}
fade();
http://jsfiddle.net/3XwZv/637/

What about doing it with CSS3 animations? Depending on your target browsers, this should work well:
Simplify your markup to a single div like this:
<div id="box"></div>
and then the CSS handles all the animation:
#keyframes colorCycle
{
0% {background-color:red;}
20% {background-color:orange;}
40% {background-color:yellow;}
60% {background-color:green;}
80% {background-color:blue;}
100% {background-color:purple;}
}
#-webkit-keyframes colorCycle /* Safari and Chrome */
{
0% {background-color:red;}
20% {background-color:orange;}
40% {background-color:yellow;}
60% {background-color:green;}
80% {background-color:blue;}
100% {background-color:purple;}
}
#box {
height: 100px;
width: 100px;
animation: colorCycle 10s 0s infinite;
-webkit-animation: colorCycle 10s 0s infinite;
}
Here's a Fiddle You can play with the key stops, timings, and colors to get the effect you need.

Depending on your specific application, you could toggle the fade for all boxes and use jQuery's promise() to determine when all boxes have finished fading.
HTML:
<div class="wrapper">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
<div class="wrapper">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
<div class="wrapper">
<div class="box box1"></div>
<div class="box box2"></div>
</div>
CSS:
.box {
position: absolute;
height: 100px;
width: 100px;
}
.wrapper {
position: relative;
width:100px;
height:100px;
margin-bottom:10px;
}
.box1 {
background-color: #F00;
}
.box2 {
background-color: #00F;
display: none;
}
JS:
function fade() {
jQuery('.box').stop(true, true).fadeToggle(2000);
jQuery('.box').promise().done(function(){fade();});
}
fade();
http://jsfiddle.net/3XwZv/638/

Related

Css animation does not occur when removing and adding class without setTimeout

When class .is-animated is added to the .box element it does a simple animation of changing background.
I want it to do this simple animation let's say every 2 seconds. The issue is that if it already has the .is-animated class and i remove and then add it again the animation does not happen except if i put the addition inside a setTimeout function. Why is this happening? Is the use of setTimeout mandatory in such situation?
JSFIDDLE
HTML
<div class="box box_one"></div>
<div class="box box_two"></div>
CSS
.box {
display: inline-block;
height: 50px;
width: 50px;
background: red;
}
.box.is-animated {animation: changebg 1s ease;}
.box_two { margin-left: 50px;}
#keyframes changebg {
0% {background: red;}
75% {background: green;}
100% {background: red;}
}
JS
var box_one = document.querySelector('.box_one');
setInterval(function() {
box_one.classList.remove('is-animated');
box_one.classList.add('is-animated');
}, 2000);
var box_two = document.querySelector('.box_two');
setInterval(function() {
box_two.classList.remove('is-animated');
setTimeout(function() {
box_two.classList.add('is-animated');
}, 100);
}, 2000);
You don't need js for this, just add "infinite" to the animation property.
As for the question itself, like Niet the Dark Absol pointed out, if you add and remove a class in the same iteration css never computes it, you would need to use a timeout indeed.
.box {
display: inline-block;
height: 50px;
width: 50px;
background: red;
}
.box.is-animated {animation: changebg 2s ease infinite;}
.box_two { margin-left: 50px;}
#keyframes changebg {
0% {background: red;}
50% {background: green;}
100% {background: red;}
}
<div class="box box_one"></div>
<div class="box box_two is-animated"></div>

How to make IntersectionObserver work with transform translate animations?

I want to create an animation for an element with following properties:
it animates the element when it enters the viewport
if the element left the viewport and then enters it again it should be animated again
depending on the scroll direction/intersected side (from top or bottom) the animation should be different
For this purpose I use an IntersectionObserver and I came close to the desired outcome.
The only problem I am facing is, when I translate the element in the scroll direction (which is in this case transform: translateY) during the animation. This will cause the IntersectionObserver to trigger multiple or even infinite times.
function isIntersectingFromTop(entry){
return entry.boundingClientRect.bottom != entry.intersectionRect.bottom;
}
function isIntersectingFromBottom(entry){
return entry.boundingClientRect.top != entry.intersectionRect.top;
}
var count = 0;
function incrementCounter(entry){
document.querySelector(".counter").textContent += "intersectionRation (" + count + "): " + entry.intersectionRatio + "\n";
count++;
}
let observer = new IntersectionObserver(
function (entries, observer) {
entries.forEach(function(entry){
incrementCounter(entry)
if (entry.isIntersecting) {
if(isIntersectingFromTop(entry)){
entry.target.classList.add("animated--up-in");
} else if(isIntersectingFromBottom(entry)) {
entry.target.classList.add("animated--down-in")
}
} else {
/** element is not in viewport anymore
* this will be triggered right after the animation starts
* since the translate is moving the elment out of the view
* which is causing a new intersection (isIntersecting = false)
*/
entry.target.classList.remove("animated--up-in");
entry.target.classList.remove("animated--down-in");
}
});
});
observer.observe(document.querySelector(".to-animate"));
.container {
height: 1000px;
width: 100%;
}
.box{
position: static;
width: 100px;
height: 100px;
background: red;
margin-top: 10px;
}
.to-animate{
background: blue;
opacity: 0;
}
.animated--up-in {
animation: animateUpIn 1.5s forwards ease;
}
.animated--down-in {
animation: animateDownIn 1.5s forwards ease;
}
#keyframes animateUpIn {
from {
transform: translateY(100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
#keyframes animateDownIn {
from {
transform: translateY(-100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.counter {
position: fixed;
top: 10%;
left: 30%;
color: black;
height: 80%;
width: 50%;
overflow-y: auto;
padding: 10px;
}
<div class="container">
<pre class="counter"></pre>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box to-animate"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
Question
How can I "tell" the IntersectionObserver to ignore translated position and just use the initial/original position to calculate intersections (with no extra element)? Is this even possible?
I think that in this case you need to track the position on the screen of the stationary containers in which the animated elements will be nested.
I have a similar problem with translateX on mobile device
Animation has translateX(-100% or 100%);
threshold: 0.1
Block has width 100%, but it should work with a visibility of 10% (threshold 0.1), therefore it cannot work, the animation switches back and forth, endlessly.
If it's 90%, then it will work

Infinite auto scrolling image

I want to make an auto scrolling image. Here is what I've tried.
Scrolling image
Here is my code.
<style>
.scroll_container {
width: 100%;
height: 200px;
/* background-color: #ddd; */
overflow: hidden;
}
.ads_box_holder {
width: 100%;
white-space: nowrap;
min-width:100%;
width: auto !important;
width: 100%;
}
.ads_box {
display: inline-block;
position: relative;
top: 0;
left: 0;
width: 190px;
height: 200px;
padding: 10px 10px;
margin-right: 10px;
}
.ads_box img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
animation: slide 20s infinite;
}
#keyframes slide {
0%{ transform:translateX(0px) }
10%{ transform:translateX(-200px) }
20%{ transform:translateX(-400px) }
30%{ transform:translateX(-600px) }
40%{ transform:translateX(-800px) }
50%{ transform:translateX(-1000px) }
60%{ transform:translateX(-1200px) }
70%{ transform:translateX(-1400px) }
80%{ transform:translateX(-1600px) }
90%{ transform:translateX(-1800px) }
100%{ transform:translateX(0px) }
}
<style>
<div class="scroll_container">
<div class="ads_box_holder">
<div class="ads_box"><img src="images/ads.png"></div>
<div class="ads_box"><img src="images/blur.jpg"></div>
<div class="ads_box"><img src="images/foot.jpg"></div>
<div class="ads_box"><img src="images/body.jpg"></div>
<div class="ads_box"><img src="images/s.png"></div>
<div class="ads_box"><img src="images/menu.jpg"></div>
<div class="ads_box"><img src="images/face.jpg"></div>
<div class="ads_box"><img src="images/c.jpeg"></div>
<div class="ads_box"><img src="images/foot2.jpg"></div>
<div class="ads_box"><img src="images/b.jpg"></div>
</div>
</div>
Now, I used keyframe css. So, when images move to left one after another, there has empty space in the right side as shown in below
---------
| |
| image | empty space are left here
| |
---------
In the reality, I want to add my images dynamically and images may be over 20 images. So, I'm not sure this keyframes is ok or not when images add dynamically.
I want to replace that empty space to the all of the images inside this box.
So, there is no empty space left and images are always scroll one after another.
But, I don't know how to replace images when space found inside ads_box_holder div.
And I remove css animation and also tried with javascript like this.
<script>
$(document).ready(function(){
var childCount = $(".ads_box_holder :visible").children().length;
var move = 0;
var hideImageTime = 0;
window.setInterval(function(){
hideImageTime += 1;
move += 200;
$(".ads_box_holder").css({
"margin-left":-move+"px",
});
if(hideImageTime > childCount) {
jQuery('.ads_box_holder .ads_box').each(function(){
var next = jQuery(this).next();
count += 1;
if (!next.length) {
next = jQuery(this).siblings(':first');
}
next.children(':first-child').clone().appendTo(jQuery(this));
});
}
},2000);
});
</script>
But it is the same result when I use keyframe css.
NOTE: The image moving style is ok but I just want to place all images when empty space found inside ads_box_holder.
I have no idea how to achieve what I want. I'm really appreciate for any suggestion.
Finally I got what I want. Clone first child and append at last of ads_box_holder and remove first child.
$(document).ready(function(){
function animation() {
$('.ads_box_holder').children(':first').clone().appendTo(".ads_box_holder");
$('.ads_box_holder').children(':first').css({
"margin-left":"-204px",
"-webkit-transition": "all 0.7s ease-out",
"-moz-transition": "all 0.7s ease-out",
"-ms-transition": "all 0.7s ease-out",
"-o-transition": "all 0.7s ease-out",
"transition": "all 0.7s ease-out"
});
setTimeout(function(){$('.ads_box_holder').children(':first').remove()},1500);
}
window.setInterval(animation,2000);
});
I hope it will help for someone.

transition animation to text align: center

I'm using the below; but the margin isn't nearly as approximate as text-align:center; is there anyway I could toggle text-align: center; to occur with a animation transition until it gets to the point of text-align: center; similar to that which is achieved with the below.
if ($(".resource-section").hasClass("resource-section--expanded")) {
$(".resources__header h2").animate({"marginLeft": "40%"}, "slow");
}
You can use a centering technique that allows you to horizontally center any element.
It can be animated using only CSS
.test {
position: absolute;
transform: translateX(0%);
left: 0%;
animation: center 2s infinite;
}
#keyframes center {
0%, 10% {
transform: translateX(0%);
left: 0%;
}
90%, 100% {
transform: translateX(-50%);
left: 50%;
}
}
<h1 class="test">TEST</h1>
You could animate center align using margin-left like this
var h1 = $('h1').width();
var parent = $('.container').width();
$('h1').animate({'margin-left':(parent/2-h1/2)}, 1500);
.container {
border: 1px solid black;
height: 100px;
}
h1 {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h1>Text</h1>
</div>
From what i understood if you want to use the text-align:center property something like this could be of help to you, but the text-align property can't be animated
$(function(){
$('.resources_header h2').click(function(){
$(this).toggleClass('align-center');
});
});
.align-center{
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="resources_header">
<h2>HEADER</h2>
</div>
</div>
A problem with this is the animation so if what you want to achieve is to animate from left to center then why not:
$(function(){
$('.resources_header h2').click(function(){
var windowHalfWidth = $(window).width()/2;
$(this).css('position','absolute');
var elemHalfWidth = $(this).width()/2;
var left = windowHalfWidth - elemHalfWidth;
$(this).animate({
marginLeft: left
},"slow",function(){
$(this).css('position','static');
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="resources_header">
<h2>HEADER</h2>
</div>
</div>

I want to animate image every click in css3

I want to move div when every click to change_photo button but this code run only one time ,I don't need infinite loop ,i want div moves when every click.
this is css:
<style>
#-webkit-keyframes myfirst
{
0% {left:0px}
100% {left:100%}
}
#images {
width: 1000px;
height: 300px;
overflow: hidden;
position: relative;
margin: 20px auto;
}
#im{ position:relative;}
</style>
this is html code:
<div id="images" style="">
<img id="im" src="images/banner.jpg"
style="width: 833px; height: 179px;" />
</div>
<input type="button" value="change_photo" onclick="animate();" />
</div>
<script>
function animate() {
var im = document.getElementById("im");
im.style.webkitAnimation = "myfirst 3s";
}
</script>
Use css3 transitions-
#image{
-webkit-transition:all 2s;
}
#image:hover{
left:100px;
}
Remove Javascript and the keyframes rule and this will work
EDIT:
jsfiddle using jquery.animate()
#-webkit-keyframes myfirst
{
0% {left:0}
50% {left:100%}
100% {left:0}
}

Categories

Resources