js backgroundImage() fade in on load? - javascript

I'm using javascript to display my background image because I'd like to have a random background image on each reload. Anyway, because of this my typical CSS transitions and animations won't do, because instead of fading the background it fades the text inside of my body.
Is there any way around this so that on each reload the background fades in?
This is the code I am using to display the random image:
var randomImage = Math.floor(Math.random() * 18) + 1;
document.body.style.backgroundImage = "url(images/" + randomImage + ".jpg)";
and I'm unsure how to make it fade in... any thoughts?

Using: https://css-tricks.com/snippets/css/transparent-background-images/
http://jsfiddle.net/wby2xf6f/1/
div {
width: 200px;
height: 200px;
display: block;
position: relative;
}
div:after {
transition: opacity 5s;
content: "";
background: url(http://www.wina.ugent.be/style/img/h1.png);
opacity: 0;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
z-index: -1;
}
div.fadein:after {
opacity:1;
}
And then add the class .fadein with Javascript/JQuery.
http://jsfiddle.net/wby2xf6f/1/
On a sidenote: it might be better to select the background-image at random on the server side (using php/ruby/whatever).
Updated, but less semantic version: http://jsfiddle.net/wby2xf6f/5/
.fill {
position:absolute;
height:100%;
width:100%;
z-index:-1;
display:none;
background:url(http://www.wina.ugent.be/style/img/h1.png);
}
$('.fill').fadeIn(5000)

This example with your code above
$(document).ready(function(){
var img1 = "http://www.clarkcraft.co.uk/images/des/48040.jpg";
var img2 = "http://glamorouslymommy.com/wp-content/uploads/2013/05/small-background1.jpg";
setInterval(function(){
var randomImage = Math.floor(Math.random() * 18) + 1;
if(randomImage<=5){
$("div").css("background","url("+img2+")").show().fadeOut("slow"); $("div").css("background","url("+img1+")").show().fadeIn("slow");
}
else{
$("div").css("background","url("+img1+")").show().fadeOut("slow"); $("div").css("background","url("+img2+")").show().fadeIn("slow");
}
}, 1000);
});
div {
width:200px;
height:200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div style="display:none"></div>

Related

Preload background images

I am cycling through background images in javascript/jQuery like this...
var duration = 2500;
var delay = 500;
var i = 0;
setInterval(function() {
if (i == 0) {
$(".myimage").css("background-image", "url('https://placeimg.com/1640/1480/any')");
}
if (i == 1) {
$(".myimage").css("background-image", "url('https://placeimg.com/1640/1481/any')");
}
if (i == 2) {
$(".myimage").css("background-image", "url('https://placeimg.com/1640/1482/any')");
}
if (i == 3) {
$(".myimage").css("background-image", "url('https://placeimg.com/1640/1483/any')");
}
i++;
}, duration + delay)
.myimage {
height: 500px;
width: 500px;
transition: background-image 1s linear;
background-image: url('https://placeimg.com/1648/1488/any');
background-size: cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myimage">
</div>
Problem is, I get flashes of no image occasionally, I think this is down to the images not being loaded in time. Is there a way to preload them?
You could preload them using CSS like:
body::after{
position:absolute; width:0; height:0; overflow:hidden; z-index:-1;
content:url(https://placeimg.com/1640/1480/any) url(https://placeimg.com/1640/1481/any) url(https://placeimg.com/1640/1482/any) url(https://placeimg.com/1640/1483/any);
}
NOTE: You could use an array of images in the JS code and change them based on the index i.
var duration = 2500;
var delay = 500;
var i = 0;
var images = ['https://placeimg.com/1640/1480/any', 'https://placeimg.com/1640/1481/any', 'https://placeimg.com/1640/1482/any', 'https://placeimg.com/1640/1483/any'];
setInterval(function() {
$(".myimage").css("background-image", "url(" + images[i] + ")");
i++;
}, duration + delay)
.myimage {
height: 500px;
width: 500px;
transition: background-image 1s linear;
background-image: url('https://placeimg.com/1648/1488/any');
background-size: cover;
}
body::after {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
z-index: -1;
content: url(https://placeimg.com/1640/1480/any) url(https://placeimg.com/1640/1481/any) url(https://placeimg.com/1640/1482/any) url(https://placeimg.com/1640/1483/any);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myimage">
</div>
You can preload the images as followed
function preloadImages(){
var images = ["https://placeimg.com/1640/1480/any","https://placeimg.com/1640/1481/any","https://placeimg.com/1640/1482/any","https://placeimg.com/1640/1483/any"];
var prelaodedImages = [];
for(i=0;i<images.length;i++){
prelaodedImages[i] = new Image();
prelaodedImages[i].src = images[i];
console.log(prelaodedImages[i].src)
}
}
preloadImages();
After the images are preloaded you can use your code and instead of
"url('https://placeimg.com/1640/1480/any')")
You use
"url("+prelaodedImages1.src+")")
This should normally result in your images already being loaded and displaying correctly.
For the first time, browser needs to download all the images, once downloaded, it'll load from cache.
So, flashes of no image will come every time whenever browser download file. you have two options
the approach you are following (which is ok)
Use CSS trick to load all at once by using following code
.myimage {
height: 500px;
width: 500px;
transition: background-image 1s linear;
background-image: url('https://placeimg.com/1648/1480/any');
background-image: url('https://placeimg.com/1648/1481/any');
background-image: url('https://placeimg.com/1648/1482/any');
background-image: url('https://placeimg.com/1648/1483/any');
background-size: cover;
}
Once browser loads it, it wont be reloaded all the time. the second time the same image is rendered there wont be such issue,
make the image cycle using i= i==3?0:++i.
Rather than just i++
Fiddle

How do I make my flipping image display a different image on either side with javascript?

I'm trying to make the different sides of the object display different images; however, any similar question I've seen has an incredibly overcomplicated answer. I'm not too fluent in js just yet but I'd appreciate the help.
<script>
var k = 0;
function flip() {
var j = document.getElementById("card");
k += 720;
j.style.transform = "rotatey(" + k + "deg)";
j.style.transitionDuration = "7s"
}
</script>
<div id="card" onmouseover="flip()"><img src="day.png"></div>
That is my html and here is my CSS:
#card {
display: block;
width: 300px;
height: 300px;
padding: 25px;
}
Let me know if any clarification is needed, thanks for the help!
Edit: I currently have an object that rotates along the y-axis when moused over. I would like there to be another image displayed after the initial image has rotated 90 degrees (displaying from 90-270 degrees, and then switching back to the previous image from 270-450 degrees, and so on). Not sure why the post was downvoted, but I hope this is the ludicrous specificity they were looking for.
You can actually do this with CSS and HTML alone.
.card-container {
perspective: 1000px;
}
.card-container:hover .card {
transform: rotateY(180deg);
}
.card-container, .front, .back {
width: 200px;
height: 200px;
}
.front, .back {
background: #efe;
}
.card {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
z-index: 2;
transform: rotateY(0deg);
}
.back {
transform: rotateY(180deg);
}
<div class="card-container">
<div class="card">
<div class="front">
Front
</div>
<div class="back">
Back
</div>
</div>
</div>
I'm new to Javascript too and I don't know if this is the best solution to use in a production environment but here's what I came up with.
Basically, you can rotate the image 180 degrees and change the image source attribute halfway. So, if you set your rotation to complete in 1 second, you can use setTimeout with a delay of around half a second to call a function that will change the image source.
var k = 0;
var imgSrc1 = "https://static.pexels.com/photos/9291/nature-bird-flying-red.jpg";
var imgSrc2 = "http://media-channel.nationalgeographic.com/media/uploads/photos/content/video/2014/10/29/349582915975_349582915975_720p_5994_Racing_Speeds_DMS.jpg";
var img = document.getElementById("img");
img.onmouseover = flip;
img.style.transitionDuration = "1s";
function flip() {
k += 180;
img.style.transform = "rotatey(" + k + "deg)";
setTimeout(changeImgSrc(), 300);
}
function changeImgSrc() {
return function() {
if(img.getAttribute("src") === imgSrc1)
img.src = imgSrc2;
else
img.src = imgSrc1;
}
}
img { width:150px; height: 150px;}
<img id="img" src="https://static.pexels.com/photos/9291/nature-bird-flying-red.jpg">

Trying to make continuous JavaScript slider

The problem with my slider is that when it gets to the last slide and i click next it jumps over the two slides to get to the first one. Similarly when i am on the first slide and click previous, it jumps over slides to get to the last one. I would like to make it that when i get to the last slide and click NEXT the first slide would come from the right to left. (similar concept for the PREVIOUS button on first slide). I tried using insertBefore() and appendChild() for the slides but couldn't figure it out...
Here is my code:
// Slider
const slider_wrapp = document.querySelector('.tract-slider');
const slider = document.querySelector('.tract-slider-wrapp');
var slide = document.getElementsByClassName('tract-slide');
const leftBtn = document.querySelector('.slide-left');
const rightBtn = document.querySelector('.slide-right');
let swWidth = slider_wrapp.clientWidth;
let sliderWidth = swWidth * slide.length;
let slideWidth = 0;
slider.style.width = sliderWidth + "px";
for (var i = 0; i < slide.length; i++) {
slide.item(i).style.width = swWidth + "px";
}
function moveRight() {
slideWidth === sliderWidth - swWidth ? slideWidth = 0 : slideWidth += swWidth;
slider.style.transform = "translateX(" + (-slideWidth) + "px)";
}
function moveLeft() {
slideWidth === 0 ? slideWidth = sliderWidth - swWidth : slideWidth -= swWidth;
slider.style.transform = "translateX(" + (-slideWidth) + "px)";
}
rightBtn.addEventListener("click", function() {
moveRight();
});
leftBtn.addEventListener("click", function() {
moveLeft();
});
.tract-slider {
width: 100%;
height: 75vh;
position: relative;
overflow: hidden;
}
.tract-slider-wrapp {
height: 100%;
position: relative;
-webkit-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
-o-transition: all 350ms cubic-bezier(.08, .13, 0, .81);
transition: all 350ms cubic-bezier(.08, .13, 0, .81);
}
.tract-slide {
height: 100%;
float: left;
position: relative;
display: block;
background-position: center;
-webkit-background-size: cover;
background-size: cover;
}
.tract-slide:nth-child(1) {
background-image: url("https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg");
}
.tract-slide:nth-child(2) {
background-image: url("https://static.pexels.com/photos/29017/pexels-photo-29017.jpg");
}
.tract-slide:nth-child(3) {
background-image: url("https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg");
}
.tract-slider-control {
position: absolute;
left: 0;
bottom: 0;
background: #ffffff;
padding: 1em;
}
.tract-slider-btn {
display: inline-block;
cursor: pointer;
margin-left: 1em;
}
.tract-slider-btn:nth-child(1) {
margin-left: 0;
}
<div class="tract-slider">
<div class="tract-slider-wrapp">
<div class="tract-slide"></div>
<div class="tract-slide"></div>
<div class="tract-slide"></div>
</div>
<div class="tract-slider-control">
<div class="tract-slider-btn slide-left">Prev</div>
<div class="tract-slider-btn slide-right">Next</div>
</div>
</div>
PS. Please use JavaScript for solution
Creating an infinite slider means you need to move your slides around in DOM so they give the impression of a continuous track.
The first thing you need to change is having their backgrounds tied up to their position in DOM. If we want to slide back from first slide to the last one, we need to take the last slide, prepend it before the first one but, considering your current CSS, that will change the backgrounds of all slides, as they are currently bound to their position in DOM (...:nth-child {background-image:...}...).
The second thing that needs changing is positioning the slides into the slider track. If they're floated, whenever we change their order, all the rest of the slides will be affected. By positioning them with position:absolute each slide moves independently, without affecting the others, so it's easier to rearrange them while keeping control.
Long story short, I started from scratch and placed all methods inside a single object: theSlider.
The reset() function does the heavy lifting: it puts before class on first element, current on second and after on all the rest. So you have to put the "last" slide first, because the slider will start with it appended before the "current" one.
The sliding is done by applying go-left and go-right classes to the track. After the transition is done, I just move the first/last slide into the new position, depending on case, and run reset() again (which strips all classes and reapplies them based on new positions).
Animations are handled by CSS. All JavaScript does is apply/remove classes and move the slides in DOM.
var theSlider = {
track : document.querySelector('.tract-slider-wrapp'),
// has to match `transition-duration` in CSS:
duration : 600,
reset : function() {
var slides = document.querySelectorAll('.tract-slider-wrapp > div');
for (var i = 0; i < slides.length; i++) {
slides[i].className = '';
slides[i].classList.add(i > 1? 'after' : (i ? 'current':'before'))
}
},
init : function() {
theSlider.reset();
theSlider.track.classList.remove('not-loaded')
},
next : function() {
theSlider.track.classList.add('go-right');
setTimeout(function(){
var firstSlide = document.querySelector('.tract-slider-wrapp > div:first-child');
theSlider.track.appendChild(firstSlide);
theSlider.reset();
theSlider.track.classList.remove('go-right')
},theSlider.duration)
},
prev : function() {
theSlider.track.classList.add('go-left');
setTimeout(function() {
var lastSlide = document.querySelector('.tract-slider-wrapp > div:last-child');
theSlider.track.insertBefore(lastSlide, theSlider.track.firstChild);
theSlider.reset();
theSlider.track.classList.remove('go-left')
},theSlider.duration)
},
prevButton : document.querySelector('.slide-left'),
nextButton : document.querySelector('.slide-right')
};
window.addEventListener("load", theSlider.init);
theSlider.prevButton.addEventListener('click', theSlider.prev);
theSlider.nextButton.addEventListener('click', theSlider.next);
.tract-slider {
width: 100%;
height: 75vh;
position: relative;
overflow: hidden;
background-color: #f5f5f5;
}
.tract-slider-wrapp {
height: 100%;
transition: all 350ms cubic-bezier(.08, .13, 0, .81);
opacity: 1;
}
.tract-slider-wrapp.not-loaded {
opacity: 0;
}
.tract-slider-wrapp>div {
height: 100%;
position: absolute;
background: transparent no-repeat 50% 50% /cover;
width: 100%;
}
.tract-slider-wrapp > div.before {
margin-left: -100%;
}
.tract-slider-wrapp > div.current + div {
margin-left: 100%;
}
.tract-slider-wrapp > div.after ~ div {
opacity: 0;
}
.tract-slider-control {
position: absolute;
width: 100%;
z-index: 1;
top: 50%;
display: flex;
justify-content: space-between;
transform: translateY(-50%);
}
.tract-slider-control div {
background-color: rgba(0,0,0,.35);
padding: .5rem 1rem;
color: white;
cursor: pointer;
}
.tract-slider-control :first-child {
border-radius: 0 17px 17px 0;
}
.tract-slider-control :last-child {
border-radius: 17px 0 0 17px;
}
body {
margin: 0;
}
.go-right div {
transform: translateX(-100%);
}
.go-left div {
transform: translateX(100%);
}
.go-right div, .go-left div {
transition-property: transform;
transition-timing-function: cubic-bezier(.4,0,.2,1);
/* has to match `duration` in js: */
transition-duration: 600ms;
}
<div class="tract-slider">
<div class="tract-slider-wrapp not-loaded">
<div style="background-image:url('https://static.pexels.com/photos/126282/pexels-photo-126282.jpeg')"></div>
<div style="background-image:url('https://static.pexels.com/photos/29017/pexels-photo-29017.jpg')"></div>
<div style="background-image:url('https://static.pexels.com/photos/70760/dandelion-dandelion-seeds-taraxacum-fluffy-70760.jpeg')"></div>
</div>
<div class="tract-slider-control">
<div class="tract-slider-btn slide-left">Prev</div>
<div class="tract-slider-btn slide-right">Next</div>
</div>
</div>
If you want to change the animation duration you need to change it in both js and css.
The only current limitation is it needs at least 3 slides to work. I guess it could be adjusted to work with only two slides by: cloning the "inactive" slide into third position, removing the clone after transition and cloning the other one.
ToDo's:
prefix CSS so it works in more browsers
replace .classList.add('whatever') with .className += ' whatever' and
.classList.remove('whatever') with .className.replace('whatever', '') if you want to show IE some love.
I told the above just to tell you this: if you want to get going, don't reinvent the wheel.
It's great you use vanilla javascript. But sooner or later you'll end up writing your own wrappers for common things. Depending on how good you are/have become, you'll write your own, limited, custom version of jQuery. Allow me to put things into perspective: Google included a lite version of jQuery into AngularJS. It's that good.
You, as an single developer, do not stand a chance at writing a better, more streamlined and tested version of it. And besides, you don't have to. Use your skill and abilities to go forward, not sideways.

Pop out image html

I am developing a chrome extension which on any hover over an image it should popout a box over the image and the image should be zoomed to 1.5 times the original image.
So I started working on examples and found a similar example like this.
.zoomin img {
height: 200px;
width: 200px;
-webkit-transition: all 2s ease;
-moz-transition: all 2s ease;
-ms-transition: all 2s ease;
transition: all 2s ease;
}
.zoomin img:hover {
width: 300px;
height: 300px;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" title="All you need to know about CSS Transitions " />
</div>
But instead i need to create a box without zooming the image on hover. So in my exercise using this Using only CSS, show div on hover over <a> i have developed this.
main.js
div {
display: none;
}
img:hover + div {
display: block;
height : 200px;
width : 300px;
}
But the problem is that the size of the image should be dynamically adjusted based on the image we are hovering.
Is there a way to make this work when we hover over an image it should automatically make a div which should hold 1.5 times the dimensions of the image.Any suggestions.?Please help
I have included the screenshot below for reference.
img:hover div {
display: block;
var img = document.getElementById('imageid');
// get the image dimensions using this id
var width1 = img.clientWidth;
var height1 = img.clientHeight;
height : width * 1.5;
width : height * 1.5;
}
You need to just remove
+
because it selects immediate next div element to img.
I guess you should try:
img:hover ~ div
{
//your height and width goes here
}
I think this is the sort of thing you wanted.
I don't think you can do this with CSS only (though would love to be wrong)
I've done a for loop to add an event listener on for when you mouse over and off an image in .zoomin. Then it sets the image source accordingly.
var zoominSel = document.querySelectorAll(".zoomin img");
var zoomContSel = document.querySelector(".zoomcont img")
for (let i = 0; i < zoominSel.length; i++) {
zoominSel[i].addEventListener("mouseover", function(event) {
zoomContSel.setAttribute('src', event.target.getAttribute('src'));
zoomContSel.style.width = event.target.offsetWidth + "px";
zoomContSel.style.height = event.target.offsetHeight + "px";
zoomContSel.parentElement.style.top = event.target.offsetTop + "px";
zoomContSel.parentElement.style.left = (event.target.offsetLeft + event.target.offsetWidth + 2) + "px";
});
zoominSel[i].addEventListener("mouseout", function(event) {
zoomContSel.setAttribute('src', '');
});
}
body {
margin: 0;
}
.zoomin img {
max-width: 200px;
}
.zoomcont img[src=""] {
display: none;
}
.zoomcont {
z-index: 1000;
position: absolute;
transform: scale(1.5);
transform-origin: 0 0;
}
<div class="zoomin">
<img src="http://www.corelangs.com/css/box/img/zimage.png" />
</div>
<div class="zoomin">
<img src="http://usabilitygeek.com/wp-content/uploads/2013/07/free-fonts-for-commercial-personal-use.jpg" />
</div>
<div class="zoomcont">
<img src="" />
</div>
Hope you find this helpful.

How do I make a div go left and then right in javascript? (no jQuery)

This should be simple but I guess no jQuery makes it a bit difficult.
I want to repeat a process where a div goes 100px to the right (with animation) and then 100px to the left (so i want a continuous movement).
There seems to be plenty of jQuery answers to this question yet no pure javascript solution. I'm probably missing something obvious here yet I can't find it.
Here is the code:
var left = 0;
var id = setInterval(function(){goRight()}, 10);
var ed = setInterval(function(){goLeft()}, 10);
function goRight(){
var redpixel = document.getElementById("redpixel");
left++;
redpixel.style.left = left + "px";
if (left>100) {
clearInterval(id)
goLeft();
}
}
function goLeft(){
var redpixel = document.getElementById("redpixel");
left-=1;
redpixel.style.left = left + "px";
if (left<100) {
clearInterval(ed);
goRight()
}
}
HTML:
<button onclick="goRight()">Go Right</button>
<div id="redpixel"></div>
CSS:
.container {
width: 480px;
height: 800px;
border: 1px solid black;
}
#redpixel {
position: absolute;
top: 200px;
left: 0;
background: red;
width: 25px;
height: 25px;
}
Last comments:
The animation starts without me calling any function (without using the button), how is that possible?
The animation works but stops when it hits the first 100px.
(Additional question) - if i put the var redpixel out of the function it doesn't work at all, why?
All help appreciated, thanks!
The problem with your code is that you set left and right animations at the same time, and the left one is cleared immediately because left<100. Fixed code:
var left = 0,
id = setInterval(goRight, 10);
ed;
function goRight() {
var redpixel = document.getElementById("redpixel");
left++;
redpixel.style.left = left + "px";
if (left > 100) {
clearInterval(id);
ed = setInterval(goLeft, 10);
}
}
function goLeft() {
var redpixel = document.getElementById("redpixel");
left -= 1;
redpixel.style.left = left + "px";
if (left < 1) {
clearInterval(ed);
id = setInterval(goRight, 10);
}
}
#redpixel {
position: absolute;
top: 50px;
left: 0;
background: red;
width: 25px;
height: 25px;
}
<div id="redpixel"></div>
One more point, is as demonstrated by Adjit it really makes sense to look at CSS approach as simpler and more effective.
You don't need any JavaScript at all actually, and it is quite simple to do with CSS3.
Just need to set up keyframes and animation like so: (obviously including the necessary browser compatibility)
#box {
height: 100px;
width: 100px;
background: red;
position: relative;
animation: waver 2s infinite;
-webkit-animation: waver 2s infinite;
}
#keyframes waver {
0% {left: 0px;}
50% {left: 100px;}
100% {left: 0px;}
}
#-webkit-keyframes waver {
0% {left: 0px;}
50% {left: 100px;}
100% {left: 0px;}
}
See this fiddle for an example: http://jsfiddle.net/bwsd3eoy/

Categories

Resources