So far, i've been able to make it such that when the cursor hovers over the div a background image in the body appears. I need to add a fade in animation to this. Ive been looking for solutions here but havent been able to work around it. I don't have any experience in javascript.
enter code here
<script>
changeBgImage = () => {
document.body.style.backgroundImage = "url('../Images/Background/wraithback.jpg')";
console.log("working")
}
ogBgImage = () => {
document.body.style.backgroundImage = "url('../Images/Background/black.jpg')";
console.log("working")
}
</script>
<style>
body {
background-image: url('../Images/Background/black.jpg');
}
</style>
<body>
<div class="gwraith"><a href="../Legends/wraith.html ">
<img src="../Images/Legends_pics/wraithchibi.png" width="130vw" class="wraith"
onmouseover="changeBgImage();" onmouseout="ogBgImage();">
</a>
</body>
Add a transition rule to the body tag. The same can be done in css, without javascript.
function changeBgImage() {
document.body.style.backgroundImage = "url('https://s1.1zoom.ru/big0/284/Summer_Pond_Fence_Trees_496376.jpg')";
}
function ogBgImage() {
document.body.style.backgroundImage = "url('https://pristor.ru/wp-content/uploads/2017/02/leto12.jpg')";
}
body {
background-image: url('https://pristor.ru/wp-content/uploads/2017/02/leto12.jpg');
background-repeat: no-repeat;
background-size: cover;
transition: all 0.7s linear;
}
<body>
<div class="gwraith">
<a href="../Legends/wraith.html">
<img src="https://begin-english.ru/img/word/refresh.jpg" width="130vw" class="wraith"
onmouseover="changeBgImage();" onmouseout="ogBgImage();">
</a>
</div>
</body>
I didn't manage to do it with body. But you can stretch the underlying div and change its opacity.
const appDiv = document.getElementById("app");
appDiv.addEventListener("mouseover", showBodyBackground);
appDiv.addEventListener("mouseout", hideBodyBackground);
function showBodyBackground() {
document.getElementById("bg").classList.add("hidden");
}
function hideBodyBackground() {
document.getElementById("bg").classList.remove("hidden");
}
.visible {
background: url('https://www.bouwendnederland.nl/media/6502/rijnhaven-impressie-602-x-402.jpg');
transition: opacity 1.5s linear;
opacity: 1;
}
.hidden {
opacity: 0;
}
.stretched {
position: absolute;
width: 100%;
height: 100%;
}
#app {
width: 100px;
height:50px;
background: lightblue;
text-align: center;
margin: 0 auto;
position: relative;
}
<body>
<div class="stretched visible" id="bg"></div>
<div id="app">Hover me!</div>
</body>
Be aware, that everything will disappear in the element with opacity: 0. It means, your button and other elements you want to keep on the screen shouldn't be children of that div.
We can't just fade body, or indeed any wrapper div which may replace it, as that would fade everything. We also can't directly fade a background image as CSS doesn't have that ability. But we can put the two background images into the two pseudo elements, before and after, of body and these can then be animated to fade in and out. The code wants to fade in one background on mouseover, and fade it out on mouseout.
There are two background images used, one called black. The code here fades that out as the other image fades in, but that can be easily removed if required.
Mouse over the gear image to fade in the second image, and mouseout of the gear to fade it out.
<!DOCTYPE html>
<html>
<head>
<script>
changeBgImage = () => {
<!--document.body.style.backgroundImage = "url('../Images/Background/wraithback.jpg')";-->
document.body.classList.toggle('showbefore');
document.body.classList.toggle('showafter');
console.log("working")
}
ogBgImage = () => {
<!--document.body.style.backgroundImage = "url('christmas card 2020 front.jpg')";-->
document.body.classList.toggle('showbefore');
document.body.classList.toggle('showafter');
console.log("working")
}
</script>
<style>
body {
position: relative;
height: 100vh; /* I added this just to cover the whole window you may not want it */
}
body:before, body:after {
opacity: 0;
content: ' ';
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
background-size:cover; /* I added this just to get the background over the whole window - you may or may not want it */
background-repeat: no-repeat no-repeat;
background-position: center center;
animation-duration: 2s; /* change to what you want it to be */
animation-fill-mode: forwards;
}
body:before {
background-image: linear-gradient(black, black); /*change this to url('your background image');*/
animation-name: shown;
}
body:after {
background-image: url('https://ahweb.org.uk/christmas card 2020 front.jpg');
animation-name: unshown;
}
body.showbefore:before, body.showafter:after {
animation-name: show;
}
body.showafter:before, body.showbefore:after {
animation-name: unshow;
}
#keyframes unshown {
from {
opacity: 0;
}
to {
opacity: 0;
}
}
#keyframes shown {
from {
opacity: 1;
}
to {
opacity: 1;
}
}
#keyframes unshow {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
#keyframes show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
</head>
<body class="showbefore">
<div class="gwraith"><!--<a href="../Legends/wraith.html ">-->
<!--<img src="../Images/Legends_pics/wraithchibi.png" width="130vw" class="wraith"
onmouseover="changeBgImage();" onmouseout="ogBgImage();">-->
<img src="https://ahweb.org.uk/gear.jpg" width="130vw" class="wraith"
onmouseover="event.preventDefault();event.stopPropagation();changeBgImage();" onmouseout="event.preventDefault();event.stopPropagation();ogBgImage();">
<!--</a>-->
</body>
</body>
</html>
Related
I want my background-image with a smooth transition. When it has a different aspect-ratio predecessor. Here you'll see a example of this stretching effect.
toggle = true
jQuery(document).ready(function() {
jQuery(".button").on("click", function() {
if (toggle) {
jQuery(".test").css("background-image", "url('https://images.pexels.com/photos/4534200/pexels-photo-4534200.jpeg?cs=srgb&dl=pexels-arthouse-studio-4534200.jpg&fm=jpg')")
toggle = false
} else {
jQuery(".test").css("background-image", "url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg')")
toggle = true
}
})
})
* {
margin: 0;
padding: 0;
}
.test {
width: 100vw;
height: 100vh;
background-image: url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg');
transition: background-image 0.5s;
-webkit-transition: background-image 0.5s;
-o-transition: background-image 0.5s;
-moz-transition: background-image 0.5s;
-ms-transition: background-image 0.5s;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
}
.button {
padding: 2px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="test">
<input class="button" type="button" value="change">
</div>
If anyone could show me an option, where I can still use background-size: cover;, and a background-image transition, it would help me a lot.
Instead of toggling the background image you can have multiple elements with a background and show the active element based on an index.
The remainder operator (%) for the (active) index makes sure we always have a valid index that never exceeds the amount of backgrounds we have.
let active = 0; // First element is active
jQuery(document).ready(function($) {
$(".button").on("click", function() {
// Update active index
active = (active + 1) % $(".bg").length;
// Show active background
$(".bg").each(function(index) {
if(index === active) {
$(this).addClass("bg-active");
}else{
$(this).removeClass("bg-active");
}
});
})
})
* {
margin: 0;
padding: 0;
}
.test {
width: 100vw;
height: 100vh;
position: relative;
}
.test > * {
position: relative; /* Make sure elements inside `.test` dont disappear behind the background(s) */
}
.bg {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
opacity: 0;
transition: opacity 0.5s;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
}
.bg-nature {
background-image: url('https://images.pexels.com/photos/4534200/pexels-photo-4534200.jpeg?cs=srgb&dl=pexels-arthouse-studio-4534200.jpg&fm=jpg');
}
.bg-art {
background-image: url('https://images.unsplash.com/photo-1547922374-968968e3f658?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=bosco-shots-SlR66yjPsoI-unsplash.jpg');
}
.bg-active {
opacity: 1;
}
.button {
padding: 2px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="test">
<div class="bg bg-nature bg-active"></div>
<div class="bg bg-art"></div>
<input class="button" type="button" value="change">
</div>
I have this situation:
setTimeout(function() {
// Set BG image
var bg_content = document.querySelector('.content_top');
bg_content.style.background = "linear-gradient(0deg,#000 0,rgba(0,0,0,.7) 35%,rgba(0,0,0,.4) 50%,rgba(0,0,0,0) 100%),url(https://upload.wikimedia.org/wikipedia/commons/8/8f/Example_image.svg) no-repeat";
bg_content.style.backgroundSize = "cover";
bg_content.style.backgroundPosition = "center";
bg_content.classList.add("fade-in");
}, 1500);
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.main_header {
color: blue;
text-align: center;
font-size: 30px;
}
.content_top {
height: 300px;
}
<div class="content_top">
<div class="main_header"><span class="vertical_line"></span>
<p data-transkey="main_header_notrans"><span class="tino">Some header</span> <br> some text</p>
</div>
</div>
.content_top has a background-image, which I want to fade in when the page loads, but I do not want the .main_header to be affected aswell. Currently this leads to a flicker effect of the text in .main_header and looks bad.
Here is a working example: JsFiddle
Move the background to a new div inside of the .content_top element. This will create a new layer which we can animate without affecting the content.
Give .content_top and .main_header a position: relative value. This will make the .content_top a relative container, and give .main_header the possibility to use the z-index.
In the snippet below I've added a new element: .main_bg. This element will get the background image and the animation.
Give the .main_bg element a position: absolute;. This will allow you to overlay elements on top of each other, in this case .main_bg and .main_header.
setTimeout(function() {
// Set BG image
var bg_content = document.querySelector('.main_bg');
bg_content.style.background = "linear-gradient(0deg,#000 0,rgba(0,0,0,.7) 35%,rgba(0,0,0,.4) 50%,rgba(0,0,0,0) 100%),url(https://upload.wikimedia.org/wikipedia/commons/8/8f/Example_image.svg) no-repeat";
bg_content.style.backgroundSize = "cover";
bg_content.style.backgroundPosition = "center";
bg_content.classList.add("fade-in");
}, 1500);
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.main_bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.main_header {
position: relative;
color: blue;
text-align: center;
font-size: 30px;
z-index: 1;
}
.content_top {
height: 300px;
position: relative;
}
<div class="content_top">
<div class="main_bg"></div>
<div class="main_header"><span class="vertical_line"></span>
<p data-transkey="main_header_notrans"><span class="tino">Some header</span> <br> some text</p>
</div>
</div>
I'm going to change back ground an element in a setInterval function. the background is getting changed imediately, but I would like to make it transited in couple of seconds.
var act = true;
setInterval(function(){
if (act) {
$("div").addClass("back2")
$("div").removeClass("back")
act = false
} else {
$("div").addClass("back")
$("div").removeClass("back2")
act = true
}
}, 10000)
.back{
width:100px;
height:100px;
background-image:url("https://www.skoobe.de/static/v/7b2334ac8a86ab5d764bc6e94df87df4aa5b4e2adc78c783e73ae2cbaf613745.jpg");
display:block;
transition: .5s ;
}
.back2{
width:100px;
height:100px;
background-image:url("https://www.skoobe.de/static/v/a5c0d3825217f88c4c893e7b630c4f1c5eb4c9bec834e1112383614270b5d583.jpg");
display:block;
transition: .5s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="c">tz</div>
background-image is not an animatable property. As you can see in this list on the mozilla dev page, this is not possible: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
What you can do is have two divs with one background image each overlapping each other and then make one of them transparent to create a blending effect.
I made a fiddle to illustrate the idea:
https://jsfiddle.net/Lpduw3mq/
// find elements
var firstDiv = $("#first")
var secondDiv = $("#second")
// Swap backgrounds
var act = true;
setInterval(function(){
if (act) {
firstDiv.addClass("transparent")
secondDiv.removeClass("transparent")
act = false
} else {
firstDiv.removeClass("transparent")
secondDiv.addClass("transparent")
act = true
}
}, 5000)
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
.base {
position: absolute;
top: 0;
left: 0;
}
.back {
width: 100px;
height: 100px;
background-image: url("https://www.skoobe.de/static/v/7b2334ac8a86ab5d764bc6e94df87df4aa5b4e2adc78c783e73ae2cbaf613745.jpg");
display: block;
opacity: 1;
transition: opacity 0.5s;
}
.back2 {
width: 100px;
height: 100px;
background-image: url("https://www.skoobe.de/static/v/a5c0d3825217f88c4c893e7b630c4f1c5eb4c9bec834e1112383614270b5d583.jpg");
display: block;
opacity: 1;
transition: opacity 0.5s;
}
.transparent {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="first" class="base back"></div>
<div id="second" class="base back2 transparent"></div>
You can use an unordered list of two items absolutely styled with the image backgrounds and use keyframe animation to change between these two items while smoothly changing a background opacity. Check this out http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/
So i made a svg logo preloader, made some css animations for it also. But my main problem is how do i make the preloader load different animation on refresh/new page loading using javascript. Like for example on one page loading the logo should use the bounce animation and upon a page refreh or on another tab opening the preloader to use the rotate animation i made, etc.
var strings = [
'animation1.',
'animation2.',
'animation3.'
];
var rand = strings[Math.floor(Math.random() * strings.length)];
document.getElementById('loading-animation').innerHTML = rand;
.loading {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
background: #ddd;
padding-top: 200px;
}
.svg {
display: block;
width: 80px;
height: 80px;
background: #aaa;
margin: 10px auto;
}
.animation1 {
just an example
}
.animation2 {
just an example
}
.animation2 {
just an example
}
<div id="container" class='loading' >
<div id='loading-animation' class='loading-animation'>Processing</div>
<svg>just an example svg in inserted in the html, no external src link to it</svg>
</div>
I'm pretty sure that .innerHTML shouldn't be there since the javascript file will be external linked in the head section. And i know i haven't linked all of the codes used just because it's to much code to paste here so i made a mini example, hope i can make myself understood. Thanks.
You can use JavaScript to randomly assign a CSS class to the element you want to animate. Here is an example.
var animationClasses = [
'animation1',
'animation2',
'animation3'
];
var choosenAnimation = animationClasses[~~(Math.random() * animationClasses.length)];
document.getElementById('elementToAnimate').classList.add(choosenAnimation);
#keyframes grow {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#keyframes fade {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes fly-down {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
}
.animation1 {
width: fit-content;
animation: grow 1s;
}
.animation2 {
animation: fade 1s;
}
.animation3 {
animation: fly-down 1s;
}
<div id="elementToAnimate">This will get a random animation</div>
A random class in the array animationClasses is assigned to elementToAnimate. Each class contains CSS for a different animation, allowing for a random animation each time.
I've created a background body slider which will switch through body backgrounds with 'next' and 'back' buttons. Live example here:
https://ts564737-container.zoeysite.com/lookbook
This functions perfectly (ignore the large images causing it to load slowly), but I can't seem to add a crossfade effect like on this website:
http://northamerica.triangl.com/pages/lookbook-swimwear
I tried this with CSS transition: all 0.5s ease-out but the transition is poor and loaded horribly.
Could anybody please advise where I can add a crossfade to this so that it's like the website above? Thank you for your help and time.
HTML & jQuery etc.
<!-- Remove header from lookbook page only and add background1 -->
<script>
jQuery(document).ready(function() {
if (top.location.pathname === '/lookbook')
{
jQuery("#root-header-cp-41e961ff2cbb3d4e6ae72927272f2db5").addClass("removeheader");
jQuery("body").addClass("background1");
}
});
</script>
<!-- Change background -->
<script>
jQuery(document).ready(function() {
var current = 1; // current background index
var max_backgrounds = 3; // number of backgrounds it will work with any number
jQuery(".next").click(function() {
jQuery("body").removeClass("background" + current);
// next background index or first one if it's the last one
current++;
if (current > max_backgrounds) {
current = 1;
}
// change background to background1, background2 ...
jQuery("body").addClass("background" + current);
});
jQuery(".back").click(function() {
jQuery("body").removeClass("background" + current);
// previous background index or last one if current is the first one
current--;
if (current < 1) {
current = max_backgrounds
}
// change background to background1, background2 ...
jQuery("body").addClass("background" + current);
});
});
</script>
<!-- Container plus images -->
<div id="toggle" width="100%">
<img src="/media/import/icons/back.png" class="back">
<img src="/media/import/icons/next.png" class="next">
</div>
CSS
/* Body background options */
.background1 {
background: url('/media/import/backgrounds/background1.jpg') no-repeat center center fixed;
background-size: cover;
overflow: hidden;
}
.background2 {
background: url('/media/import/backgrounds/background2.jpg') no-repeat center center fixed;
background-size: cover;
overflow: hidden;
}
.background3 {
background: url('/media/import/backgrounds/background3.jpg') no-repeat center center fixed;
background-size: cover;
overflow: hidden;
}
/* Toggle Buttons */
#toggle .next {
float: right;
margin-right: 20px !important;
}
#toggle .back {
margin-left: 20px !important;
}
#toggle img {
margin-top: 400px;
display: inline;
}
#toggle img:hover {
cursor: pointer;
opacity: 0.8;
}
The trick is to use multiple elements, which are all positioned in the exact same place. All elements must have an opacity: 0, except the active one (opacity: 1).
When you navigate to the next/previous item, you need to toggle an active class on them, which removes/sets opacity: 1
Simplified example with divs:
(function () {
var prevButton = $('.previous'),
nextButton = $('.next'),
allImages = $('.background-images li');
nextButton.click(function(e) {
// Find the active element
activeElement = $('li.bg-active');
// remove the 'bg-active'-class from this element
activeElement.removeClass('bg-active');
// if current element is the last one, make sure to add 'bg-active'-class to the very first element.
if (activeElement[0] === allImages.last()[0]){
allImages.first().addClass('bg-active');
} else {
// Add 'bg-active'-class to the next element
activeElement.next().addClass('bg-active');
}
});
prevButton.click(function(e) {
activeElement = $('li.bg-active');
activeElement.removeClass('bg-active');
// if current element is the first one, make sure to add 'bg-active'-class to the very lst element.
if (activeElement[0] === allImages.first()[0]){
allImages.last().addClass('bg-active');
} else {
// add 'bg-active'-class to the previous element
activeElement.prev().addClass('bg-active');
}
});
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Slider</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
ul {
overflow: auto;
}
li {
width: 100px;
height: 100px;
position: absolute;
left: 0;
}
.bg {
opacity: 0;
transition: all 0.5s ease-out;
}
.bg-active {
opacity: 1;
}
.bg1 {
background-color: red;
}
.bg2 {
background-color: green;
}
.bg3 {
background-color: blue;
}
</style>
</head>
<body>
previous
next
<ul class="background-images">
<li class="bg bg1 bg-active"></li>
<li class="bg bg2"></li>
<li class="bg bg3"></li>
</ul>
</body>
</html>
Try using
#Crossfade img {
position:absolute;
left:0;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
This should give you the crossfade that you want.
Instead of toggling classes you could just swap out the image, here's a quick proof of concept you can run in your console:
jQuery("body").css({'background-image':'url(/media/import/backgrounds/background3.jpg)', 'transition':'all 0.5s ease-out'});
Adapting this for your code would look something like:
jQuery
jQuery(".next").click(function() {
current++;
if (current > max_backgrounds) {
current = 1;
}
jQuery("body").css({'background-image':'url(/media/import/backgrounds/background' + current + '.jpg');
});
jQuery(".back").click(function() {
current--;
if (current < 1) {
current = max_backgrounds
}
jQuery("body").css({'background-image':'url(/media/import/backgrounds/background' + current + '.jpg');
});
CSS
body {
transition: all 0.5s ease-out;
}
There many ways you can about this and this gentleman has showcase many of them
Some pointers:
The page you've given as an example loads every image when the page loads.
Performance wise, you don't want that. If you're going to do such an effect, make sure you load the images only when they actually required.
They achieve the effect by pilling all images on top of each other, then animating the opacity in/out when clicking the arrows.
Since they all have position:absolute, you'll get the crossfade effect you wish for.