Fade in new background and fade out after 10s - javascript

I've tried to make my website change background every 10 seconds. It was successful. Now, I want to fade them in and fade them out, so they will appear smoothly. I've searched other forumpages and found related questions, but I wasn't able to understand the answers well.
Javascript:
function run(interval, frames) {
var int = 1;
function func() {
document.body.id = "b"+int;
int++;
if(int === frames) { int = 1; }
}
var swap = window.setInterval(func, interval);
}
run(10000, 6); //milliseconds, frames
CSS:
#b1 { background-image: url("standaard01.jpg"); }
#b2 { background-image: url("standaard02.jpg"); }
#b3 { background-image: url("standaard03.jpg"); }
#b4 { background-image: url("standaard04.jpg"); }
#b5 { background-image: url("standaard05.jpg"); }
#b6 { background-image: url("standaard06.jpg"); }
#b7 { background-image: url("standaard07.jpg"); }
#b8 { background-image: url("standaard08.jpg"); }
#b9 { background-image: url("standaard09.jpg"); }
#b10 { background-image: url("standaard10.jpg"); }

Unfortunately it's not possible to transition between two images set to the background of a single element. (correction: it is, by animating the background-image property of an element - given browser support)
However, you can fade one element out while another element lays behind it.
Jquery has a method called .fadeToggle() that you could use in this case.
Set up a "stack" of img elements or divs with bg images, positioned on top of eachother, with the position:absolute, left, and top CSS properties.
Then, in your javascript loop, every 10 seconds, .fadetoggle() the currently visible div, revealing the next image. You could keep track of the state with an index variable.
Upon reaching the final element, fade the top image again. Then before the second element fades, .show() the remaining elements so they once again visible for the revealing.
A note about z-index: The CSS property z-index will position elements either in front, or behind other elements. So it would be wise to set the correct z-index of each item either in it's css class, or programmatically on loading the page.
Image size note: If the images or divs are different dimensions, you would fade one in, while fading the other out. From here we can talk about different crossfading methods but that's beyond the scope of this discussion
Good luck :)

Related

How to start another animation on current position?

So this is my box
<div class="mybox"></div>
And i have a animation
.mybox{
animation:right 5s;
animation-fill-mode:forwards;
padding:50px;
width:0px;
height:0px;
display:block;
background-color:black;
}
#keyframes
right{from{left:0px;}to{left:300px
;}}
#keyframes
left{from{right:0px;}to{right:300p
x;}}
And i have two button
<button onclick="leftFunction">left</button>
<button onclick="rightFunction">right</button>
Then if i click left it will go left while it is going left then i click right i want to stop the left animation and go right but the right animation must start on current position and not teleport and go right.
Please help :(
Im new to stack overflow
Here is the js
function leftFunction() {
document.getElementById("myDIV").style.animation
= "left 4s";
}
function rightFunction() {
document.getElementById("myDIV").style.
animation = "right 4s";
}
There were a number of issues I found with the code that you posted, but you were on the right track.
Your DOM method was looking for an element with an ID of myDIV which does not exist, I changed it to document.querySelector(".mybox") since that is the class name of your div.
You weren't invoking the function call on your onclick handler, not sure you were getting anything to happen at all... Add the () invoke it onclick.
Your code layout was not following normal spacing conventions, but it is difficult to write code into stack overflow, so I understand. I made the changes I saw necessary.
You were setting position values to your div, but there was no position property declared. Position is static by default which doesn't respond to left or right. I used relative as that will keep the div in the document flow.
Changing left on one animation and right on another will maintain the previous left or right values, respectively and could cause your div to shrink or grow unexpectedly. I changed it to only affect the left property.
And now for the solution
Change your keyframes to only update the left property. Call the function from onclick and pass in the event object. This will allow you to have just one function to handle the change in animation, and can take the event target's innerHTML to set the name of the animation desired.
Make use of CSS custom properties, so that value can be mutated in javascript, and make your from properties start at the custom property. In this case --cur-pos.
When the function is called, get the div element, and find it's computed left value with document.getComputedStyle(), then update the custom property --cur-pos with that value. That way the animation always starts where the div is currently positioned.
Et voila! You should be good to go. You might have to tweak the starting --cur-pos value to have the div start where you want, and also update the to values to end where you want, just make sure to choose either left or right for updating horizontal position, not both.
function changeAnimation(e) {
const box = document.querySelector(".mybox")
const pos = window.getComputedStyle(box).left
box.style.setProperty("--cur-pos", pos)
box.style.animationName = e.target.innerHTML
}
.mybox {
--cur-pos: 150px;
width: 100px;
height: 100px;
background-color: black;
position: relative;
animation: right 4s forwards;
}
#keyframes right {
from { left: var(--cur-pos); }
to { left: 300px; }
}
#keyframes left {
from { left: var(--cur-pos); }
to { left: 0px; }
}
<div class="mybox"></div>
<button onclick="changeAnimation(event)">left</button>
<button onclick="changeAnimation(event)">right</button>

Fading div in and out on center slider item

I'm trying to fade a div in/out on a center slider item.
I'm using owl-slider, the center slide/item gets assigned the class .center by the slider.
Each slide has a div called Age, and I'm trying to make it so this Age div is hidden on all slides which don't have the .center class, and it fades in on the center slide.
The center slide is navigated by the owl-prev/owl-next controls, so this is what I was thinking to trigger the change.
Is it a more efficient way to do this?
Example:
The issue I'm having is how to test for the presence of the .center class on document load, and also how to initially set the Age div not visible on load also.
I've tried $(".item-age").hide(); and it works, but when I click the next control all Age divs appear, not just the one associated with .center.
This is what I'm trying: `
$(".owl-next").click(function(){
if ($('.owl-item').hasClass('center')){
$('.item-age').fadeIn();
}
});`
I think the best way is to use CSS with Transitions.
Define the two states for the age div:
.age {
opacity: 0; /* transparent = invisible */
}
.center .age {
opacity: 1; /* opaque = visible */
}
This already does the trick for hiding/showing the age div. To get the fading effekt, add css transition properties:
.age {
opacity: 0; /* transparent = invisible */
transition: opacity 1s; /* fade out transition */
}
.center .age {
opacity: 1; /* opaque = visible */
transition: opacity 500ms; /* fade in transition */
}
The transition is always defined in the target state of the transition. To get a better understanding of the transition-property refer to this MDN article.
I think you are trying to do something like this
$(".next").click(function(){
if ($('.sliderItem').hasClass('center')){
$('.age').fadeIn();
}
});
You can use the .fadeIn() function on the element that has the .center class directly by changing your selector target to .owl-item.center.
Try changing your code to:
$(".owl-next").click(function () {
$('.owl-item.center .item-age').fadeIn();
});

CSS :hover works only when mouse moves

I created a very basic sample:
HTML
<div id="bla"></div>
CSS
#bla {
width:400px;
height:400px;
background-color:green;
display:none;
}
#bla:hover{
background-color:red;
}
As you can see it's a DIV that is initially hidden and changes color when mouse hovers over it.
This JavaScript unhides it after 2 seconds
setTimeout(function() {
document.getElementById('bla').style.display="block";
},2000)
But if you place your mouse over location where the DIV is about to appear - when it appears - it appears in unhovered state. Only when you actually move the mouse - hover effect takes place.
Here's a demo. Run it and immediately place mouse over result pane.
Is this by design? Is there a way (without JS preferable) to detect that DIV is hovered?
While you can use opacity, #BrianPhillips mentioned, it doesn't work in IE 8. I don't know of a pure CSS solution, but here's a concise enough Javascript workaround:
window.onmousemove=function(event){
ev = event || window.event;
if (event.pageX <= 400 && event.pageY <= 400){
document.getElementById('bla').style.backgroundColor= "red";
} else {
document.getElementById('bla').style.backgroundColor= "green";
}
}
setTimeout(function() {
document.getElementById('bla').style.display="block";
},2000)
Demo
When you set display to none the image takes up no space meaining there is nowhere to hover over.
I would set the background-image in you css to rgba(0 0 0 0); making it invisible but still in the dom. You can then change your javascript to
setTimeout(function() {
document.getElementById('bla').style.backgroundColor="green";
},2000);
http://jsfiddle.net/euT7k/3
You could try using CSS opacity along with setting it to position: absolute to prevent it from taking up flow on the page. This appears to work properly:
CSS:
#bla {
width:400px;
height:400px;
background-color:green;
opacity: 0;
position: absolute;
}
JS:
setTimeout(function() {
document.getElementById('bla').style.opacity="1";
document.getElementById('bla').style.position="relative";
},2000)
Demo
The key here is that elements with opacity respond to events (click, hover, etc), while elements with visibility: hidden and display:none do not. (source)
Note that opacity isn't available in IE 8 and below.

Crossfading Background Images

I am trying to crossfade and cycle through a series of 5 images which is a full screen background image.
I am applying the following css class to body.
body {
display: table;
margin:0px;
height:100%;
background-image:url('images/image1.jpg') ;
background-size: 1500px auto;
-webkit-font-smoothing: subpixel-antialiased !important;
}
I would like to replace background-image with the next image in sequence i.e. images/image2.jpg, images/image3.jpg, every 8 seconds, with the prior image fading out and the new image fading in, and being able to control the speed of fading.
I was wondering what the best way is to go about doing this. I tried using Jquery Cycle but it didn't fit my needs since this is a full-screen background image.
This link was the most helpful so far.
http://css3.bradshawenterprises.com/cfimg/#cfimg1
images = ["https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Solid_blue.svg/225px-Solid_blue.svg.png",
"https://i.kinja-img.com/gawker-media/image/upload/s--XkYSDzxz--/c_scale,fl_progressive,q_80,w_800/hflvykipmc5g22mc3m0m.jpg",
"https://vignette2.wikia.nocookie.net/symbolism/images/4/43/Orange.png/revision/latest?cb=20140818120046",
"https://vignette4.wikia.nocookie.net/joke-battles/images/0/0e/Green.jpg/revision/latest?cb=20170111231844"];
// These are just placeholder images, replace the URLs with anything you desire.
bgNum = 0;
setInterval(changeBackground,5000); // Change to the number of milliseconds desired between frame changes
changeBackground();
function changeBackground() {
c = document.getElementById('bgContainer');
c.removeChild(c.childNodes[0]);
bg2 = document.createElement('img');
bg2.src = images[bgNum];
bg2.classList.add('bg');
bg2.style.opacity = '0';
bg2.onload = setTimeout(changeOpacity,100); // For some reason, updating the opacity does not work immediately after inserting the element
c.appendChild(bg2);
bgNum++;
bgNum %= images.length; // Reset image counter
}
function changeOpacity() {
c = document.getElementById('bgContainer');
c.childNodes[0].style.opacity = '0';
c.childNodes[1].style.opacity = '1';
}
#bgContainer img {
transition: opacity 1.5s;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -2;
}
<div id='bgContainer'><img><img></div>
test text
I could not find any way to replicate this using background-image, but I believe this replicates the behavior you are looking forward to. In order to use it, simply change the interval time and image list, as necessary.
I attempted this by having only two images on the page at a time, stacked on top of each other. However, I believe that having all images together at once and alternating opacity values may be cleaner and remove the need for the setTimeout() call. Oddly, calling console.log() also works instead of setting a delay, but it clutters the console if left running for a long period of time.

Can I animate the opacity of a CSS background-image?

CSS/Javascript is not my strong point so I would like to ask if is possible to change the background-image opacity to, let's say, 0.5.
I have a div with
background-image: url(images/nacho312.png);
background-position: -50px 0px;
background-repeat: no-repeat no-repeat;
but when I load a certain view it does not look very good, so I want to have a "half-disolve" effect when that view is shown. Is it possible?
Thanks
Here is a start.
var element = document.getElementById('hello'),
targetOpacity = 0.5,
currentOpacity,
interval = false,
interval = setInterval(function() {
currentOpacity = element.getComputedStyle('opacity');
if (currentOpacity > targetOpacity) {
currentOpacity -= 0.1;
element.style.opacity = currentOpacity;
} else {
clearInterval(interval);
}
}, 100);
See it on jsFiddle.
Run this on window.onload = function() { } or research cross browser on DOM ready events.
Of course, it is much easier with a library like jQuery.
$(function() {
$('hello').fadeTo('slow', 0.5);
});
This relies on your container's children inheriting the opacity. To do it without affecting them is a bit of a pain, as you can't reset children's opacity via opacity: 1.
If you want to animate smoothly and without doing too much extra work - this is a good task for jQuery (or another, similar library).
With jQuery you could do:
$('#id_of_div').fadeTo('fast', 0.5);
To get a fast animated fade effect on the relevant DIV.
Update: if you want to actually fade the background image, but not any foreground contents of the DIV, this is a lot harder. I'd recommend using one container DIV with position:relative and two inner DIVs with position:absolute; . The first of the inner DIVs can have the background image and a lower z-index than the second of the DIVs, and the second DIV would contain any text, etc. to show in foreground. When needed you can call $('#id_of_first_div').fadeTo('fast', 0.5); to fade just the DIV containing the background image.
By the way, the literal answer to your question is "No, you cannot animate the opacity of a CSS background image" - you can only (currently) animate the opacity of a DOM element, not its attributes, thus the need for the above hack.
Other Update: if you want to avoid using any third-party library, you can handle the fade of the background DIV using approach in Alex's answer.
background-image: url(images/nacho312.png);
background-position: -50px 0px;
background-repeat: no-repeat no-repeat;
opacity:0.5; //for firefox and chrome
filter:alpha(opacity=50); //for IE

Categories

Resources