Smooth background images transition - Javascript - javascript

http://www.chooseyourtelescope.com/ (>> Please watch it on a minimum 15'' screen, the site is not entirely responsive yet and you wont see what I'm talking about)
When you hover the buttons (moon, planet, etc...) it changes the background. But the transition is buggy on Chrome (image0>blank>image1). And worknig on IE11 but sometimes with a lag. I didn t try with the other browsers.
How to make a smooth transition?
A quick fade Image0>image1, not image0>transition color>image1
Here is the code for the MOON button. Thats the same with the others.
(I don't know anything about Javascript. I found the script below on Stackoverflow.)
HTML
<div class="top-logos-home" id="top-logos-moon-front"><img src="moon-logo.png" alt="MOON"></div>
CSS
.image-home {
position: absolute;
width: 100%;
height: 100%;
background-image: url(Frontpage.jpg);
background-size: cover;
display:inline;
top:0;
}
JAVASCRIPT
jQuery(function(){
var $body = $('.image-home');
$('#top-logos-moon-front').hover(function(){
$body.css('background-image', 'url("Frontpage-moon.jpg")')
}, function() {
$body.css('background-image', '')
})
})

You need to change just your script code if you want smooth transtion.
jQuery(function(){
var $body = $('.image-home');
$('#top-logos-moon-front').hover(function(){
$body.fadeOut('slow',function(){
$body.css('background-image', 'url("Frontpage-moon.jpg")').fadeIn('slow');
});
}, function() {
$body.css('background-image', '')
})
})
If you want to do best solution for this you need follow the steps below.
Firstly you need to defined your path of images in the js with the below code.
var imgs = [
'http://i.imgur.com/DwLjYhh.jpg',
'http://i.imgur.com/gAlqfUU.jpg'
];
After this step, you need to add new attiribute your buttons like data-id.
<div class="top-logos-home" id="top-logos-moon-front" data-id='0'>
<img src="button_image_jpg" alt="MOON">
</div>
When you defined all variables, you need to detect the hover with your current code and choose the right image that is in imgs array for your background.
jQuery(function(){
var $body = $('.image-home');
$('#top-logos-moon-front').hover(function(){
$body.fadeOut('slow',function(){
//fade out slowly element and after change the style of inner elements then fade in slowly.
$body.css('background-image','url('+imgs[$(this).attr('data-id')]+')').fadeIn('slow');
});
});
});
In my personal opinion; Image transitions shouldn't manage in this way. Create different element for each planets. When user click the button, planets slip and overlapping. You can see a demo in the below code.
http://codepen.io/thegeek/pen/GDwCa

I found a solution by using the opacity property. Now its working perfectly.
HTML
<img id="background-moon-front" class="hover-backgrounds" src="Frontpage-moon.jpg" />
CSS
.hover-backgrounds {
opacity:0;
transition: opacity 0.6s linear;
top:0;
position:absolute;
background-size: 100%;
}
JAVASCRIPT
$(document).ready(function (e) {
$("#top-logos-lune-front").hover(function (e) {
$("#background-moon-front").css("opacity", "1");
}, function() {
$("#background-moon-front").css("opacity", "0")
})
});

Related

Animate text using intervals (and timeouts?) Javascript, JQuery

I would like to make a Text run from left to right in a loop. Here is the fiddle with my attempt:
https://jsfiddle.net/9Lruxym8/33/
I started with css #keyframes but I think I need the width of the text itself if I want the text to run seamlessly. My idea was to write down the text two times and once the div with the texts has run exactly halfway, the animation starts again.
After #keyframes didn't work, I tried jQuery animation. It did work somewhat but didn't run smoothly. Now I'd like to do it via transition. I thought a combination of intervals and timeouts could do the trick but I still don't get it to work - and now, I don't know why. Does anyone have a hit for me?
function runText() {
var text_width = $('#runningP').width()/2;
console.log(text_width)
setInterval(function(){
console.log("interval");
$('.text').css({'transition':'margin-left 5s'});
$('.text').css({'margin-left':'-' + text_width + 'px'});
moveBack();
}, 3000);
function moveBack() {
console.log("timeout")
setTimeout(function(){
$('.text').css({'transition':'none'});
$('.text').css({'margin-left': 0});
}, 3000);
}
}
runText();
I've recently made a bit of custom code for this functionality.
Looking at my code, it seems a bit much having essentially 3 "levels" (.scrollTextWrap > .scrollingText > .scrollContent) but this was the structure I ended up using to get a clean and consistent effect.
I've added in an initialiser too so that you could simply add the scrollMe class and have them setup the html for you
In the snippet I've added a .parentContainer purely to show how it works when constrained
$(document)
.ready(function(){
// check that scrollingText has 2 scrollContent element
$('.scrollMe')
.each(function(){
initScrollingText($(this));
});
});
function initScrollingText($this){
// store text
var text = $this.text();
// empty element
$this.html(null);
var $wrap = $('<div class="scrollTextWrap" />'),
$text = $('<div class="scrollingText" />'),
$content = $('<div class="scrollContent" />');
// set content value
$content.text(text);
// duplicate content
$text
.append($content)
.append($content.clone());
// append text to wrap
$wrap.append($text)
// add $wrap to DOM
$wrap.insertAfter($this);
// remove old element
$this.remove();
}
/* to simulate width constraints */
.parentContainer {
width: 140px;
position:relative;
overflow:hidden;
}
.scrollTextWrap {
position:relative;
width:auto;
display:inline-block;
}
.scrollingText {
display: flex;
position:relative;
transition:left 0.1s;
animation: scrollText 5s infinite linear;
}
.scrollContent {
white-space: nowrap;
padding-right:5px;
}
#keyframes scrollText {
0% { left:0 }
100% { left:-50% }
}
<div class="parentContainer">
<div class="scrollMe">Content you want to scroll goes here</div>
<!-- alternatively you can just structure the html -->
<div class="scrollTextWrap">
<div class="scrollingText">
<div class="scrollContent">Content you want to scroll goes here</div>
<div class="scrollContent">Content you want to scroll goes here</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to make my animated skills bar responsive

I have an animated skills bar on my website, which fires when the section scrolls into view. Everything is working well so far.
Except when the viewport changes/window resizes the animated bars won't adjust to it and will be too long or to short.
I tried to solve this problem with
$(window).resize(function(){location.reload();
but on mobile viewport it keeps refreshing the page even though I'm just scrolling.
I already searched the net to see if there is a way to just reload the specific jquery function, but couldn't find anything. Or to be honest I didn't quite understood I guess, and couldn't get it working.
Here is what I found: https://css-tricks.com/forums/topic/reload-jquery-functions-on-ipad-orientation-change/
I read there is a way to make the website reload the whole js file. But since I still have other animations on my page, I don't know if this is the best way to do it.
I'm glad if anyone could help me with this. I'm very new to coding and my js/jquery knowledge is still very limited/non-existent.
here is my script for the bar animation
var $meters = $(".meter > span");
var $section = $('#skills .meter');
var $queue = $({});
function loadDaBars() {
$meters.each(function() {
var $el = $(this);
var origWidth = $el.width();
$el.width(0);
$queue.queue(function(next) {
$el.animate({width: origWidth}, 800, next);
});
});
}
$(document).bind('scroll', function(ev) {
var scrollOffset = $(document).scrollTop();
var containerOffset = $section.offset().top - window.innerHeight;
if (scrollOffset > containerOffset) {
loadDaBars();
$(document).unbind('scroll');
}
});
the width for the skillbar is defined via div class and span in %.
Maybe there is a css solution to this?
edit: this is how my html and css code looks like
.meter {
background-color: hsla(54, 73%, 95%, 1);
vertical-align: bottom;
width: 100%;
position: relative;
}
.meter>span {
display: block;
background-color: rgb(241, 233, 166);
position: relative;
overflow: hidden;
}
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="meter">
<span style="width: 50%"></span>
</div>
You remove the style property of the bar once the animation has finished. This way the css rule will apply again:
$el.animate({width: origWidth}, {duration: 800, complete: function (){$el.removeAttr('style')}}, next);
(Assuming the width defined by the css is responsive)

How to slide a div by hovering over another div with jquery?

I have some code here and cannot find out how to make this work because I am still really new to javascript and jquery. I will have a demo below so you can see what I have going on. In the demo there is div positioned left:-60px so it is hidden, this div also has class of 'show' which positions the div to left:0 There is also the long black box which is another div. I want to make it so when you hover over the long black box, it will activate the 'show' property of the other div. Here is my code:
var $showSidemenu = $('#sidemenu');
var $sidemenuShowButton = $('#sidemenuShowButton');
function(showSidemenu){
$showSidemenu.onmouseover($sidemenuShowButton).addclass('show');
}
#sidemenuShowButton {
width:60px;
height:100%;
background:#000000;
top:0;
left:0;
position:fixed;
}
#sidemenu {
width: 60px;
height:100%;
background-color: #383D3F;
position: fixed;
top: 0;
left:-60px;
float: left;
z-index:0;
}
#sidemenu.show {
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="sidemenuShowButton"></div>
<div id="sidemenu"></div>
try this jQuery:
var $showSidemenu = $('#sidemenu');
var $sidemenuShowButton = $('#sidemenuShowButton');
$(document).ready(function(){
$sidemenuShowButton.on('mouseover',function(){
$('#sidemenu').addClass("show");
});
$sidemenuShowButton.on('mouseout',function(){
$('#sidemenu').removeClass("show");
});
// to make the showed div stay while the mouse is still over it
$('#sidemenu').on('mouseover',function(){
$(this).addClass("show");
});
$('#sidemenu').on('mouseout',function(){
$(this).removeClass("show");
});
});
if you want a little animation, you can use CSS3 Transition for that, like this one:
#sidemenu {
transition: 1s;
}
HERE'S A WORKING DEMO
Use JQuery's show and hide functions. If you set your #sidemenu to display: none;. And then use this this function it will work:
$('#sidemenu').mouseenter(function(){
$("#sidemenuShowButton").show();
}).mouseleave(function(){
$("#sidemenuShowButton").hide();
});
No classes are needed in this way.
Your JS should looks like this:
var $showSidemenu = $('#sidemenu');
var $sidemenuShowButton = $('#sidemenuShowButton');
$sidemenuShowButton.on('mouseover', function(){
$showSidemenu.addClass('show')
});
First of all you are using function which never used and cannot be used since it have no name. Second, there is no onmouseover method in jQuery (read the manual ;-). Third you have to pass there a callback function which will be involved when 'mouseover' event occurs.
And if you wanna hide your div when mouse leaves add
$showSidemenu.on('mouseleave', function(){
$showSidemenu.removeClass('show')
});
You should use $showSidemenu in this case instead of $sidemenuShowButton because when $showSidemenu apears mouse leaves $sidemenuShowButton and enters $showSidemenu. But if you wanna use css3 animation - it's better to make appearing div nested to control div and use event bobbling.
And jsfiddle
Solution:Use mouseover and mouseout events to add and remove class "show"
I have intentionally added mouseout event on showSidemenu as when it slides in it goes over sidemenuShowButton div and comes on top of it, so attaching mouseout to sidemenuShowButton will cause flickering effect.
http://api.jquery.com/category/events/mouse-events/
$sidemenuShowButton.mouseover(function(){
$showSidemenu.addClass("show");
}
);
$showSidemenu.mouseout(function(){
$showSidemenu.removeClass("show");
}
);
Working JS Fiddle Example: http://jsfiddle.net/2cjjdm7j/1/

Bring an element to top of the page even if the page does not scroll

Background:
Let's say you have a simple page which has a logo and a heading only and one paragraph
<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1>Foo Bar</h1>
<p>ABC12345</p>
This is how that looks like
That page, obviously would not have vertical overflow / scroll bar for almost even tiny scale mobile devices, let alone computers.
Question
How can you bring that heading to the top left of the screen and move the logo out of focus unless someone scrolls up? Open to using any JavaScript library and any CSS framework
Attempts:
Tried using anchors but they only work if the page already had a scroll bar and anchor was out of focus.
Tried window.scrollTo but that also requires the page to have scroll already
Tried $("html, body").animate({ scrollTop: 90}, 100); but that also doesn't work when the page doesn't have overflow
Notes:
Please note that adding some extra <br/> to induce an overflow is not the way to go, it can be done that way but that's a very ordinary workaround
Why is it needed?
Its for a form for mobile devices, simple requirement is to take the first field of the form to top of the page and hide the logo (one can scroll up if they wish to see it) so it doesn't take attention away. Not using jQueryMobile for this particular task.
If you want the user to be able to scroll up and see the logo, then the logo must be within the top boundary of the body tag, because anything outside of that tag will not be viewable. This means you cannot use negative margins or offsetting like that. The only way to achieve this is to have the page scroll to the desired location that is within the top boundary of the body tag. You can set the time for this event to one millisecond, but there will still be a 'jump' in the page when it is loaded. So, the logic is: first make sure the page is long enough to scroll to the right place, then scroll there.
//Change the jQuery selectors accordingly
//The minimum height of the page must be 100% plus the height of the image
$('body').css('min-height',$(document).height() + $('img').height());
//Then scroll to that location with a one millisecond interval
$('html, body').animate({scrollTop: $('img').height() + 'px'}, 1);
View it here.
Alternatively, you can load the page without the image in the first place. Then your form field will be flush with the top of the document. Then you could create the element at the top and similarly scroll the page again. This is a round-a-bout way of doing the same thing though. And the page will still 'jump,' there is no way around that.
Only CSS and anchor link solution
With a pseudo element :
--- DEMO ---
First :
set : html,body{height:100%;}
Second :
Choose one of your existing tags. This tag mustn't have a relatively positioned parent (except if it is the body tag). Preferably the first element in the markup displayed after the logo. For your example it would be the h1 tag. And give it this CSS :
h1:before {
content:"";
position:absolute;
height:100%;
width:1px;
}
This creates an element as heigh as the viewport area. As it is displayed under the logo, the vertical scroll lenght is the same as the logo height.
Third :
Give the first element after logo an id (for this example I gave id="anchor").
Then you can use a link like this your_page_link#anchor and you will automaticaly scroll to the anchor (logo outside/above the viewport).
This works whatever height the logo is.
link to editable fiddle
Full code :
HTML
<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1 id="anchor">Foo Bar</h1>
<p>ABC12345</p> Anchor link
CSS
html, body {
height:100%;
margin:0;
padding:0;
}
h1:before {
content:"";
position:absolute;
width:1px;
left:0;
height:100%;
}
You might need to add js functionality to hide the logo if user scrolls down but I guess following code will fullfill the first requirement.
Please see
<script src="js/jquery.js"></script>
<img id='logo' src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" style="display:none">
<h1>Foo Bar</h1>
<p>ABC12345</p>
<script type="text/javascript">
var p = $( "p:first" );
var isScrolled=false;
/* For Firfox*/
$('html').on ('DOMMouseScroll', function (e) {
isScrolled = true;
if(p.scrollTop()==0 && isScrolled==true){
$('#logo').css('display','block');
}
});
/* For Chrome, IE, Opera and Safari: */
$('html').on ('mousewheel', function (e) {
isScrolled = true;
if(p.scrollTop()==0 && isScrolled==true){
$('#logo').css('display','block');
}
});
</script>
I have referred this question to find solution.
You could use touchmove event to detect swipe up or down. This is my example. You can try it on mobile device.
<style>
#logo {
position: absolute;
top: -100%;
-webkit-transition: top 0.5s;
-moz-transition: top 0.5s;
-ms-transition: top 0.5s;
-o-transition: top 0.5s;
transition: top 0.5s;
}
#logo.show {
top: 0;
}
</style>
<script>
var perY;
var y;
$(window).on('touchmove', function(e) {
e.preventDefault();
y = window.event.touches[0].pageY;
if(!perY)
perY = y;
else
{
if(y > perY)
$('#logo').addClass('show');
else
$('#logo').removeClass('show');
perY = null;
}
});
</script>
<img id="logo" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1>Foo Bar</h1>
<p>ABC12345</p>
This is the same problem i've encountered hiding the addressbar without the page overflowing. The only solution that fitted my needs was the following:
Set the min-height of the body to the viewportheight + your logo.
$('body').css('min-height', $(window).height() + 200);
This is a simple solution of getting the height of the contents to see if we can scroll to the part of the header, if not, we add height to the paragraph.
<img id="img" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" />
<h1 id="h" >Foo Bar</h1>
<p id="par" style="background:yellow;">
hello world
</p>
script:
function hola(){
var imgH = $("#img").outerHeight(true);
var titleH = $("#h").outerHeight(true);
var winH = $(window).height();
var parH = $('#par').outerHeight(true);
var contH = (imgH + titleH + parH);
var wishH = (imgH + winH);
console.log("wished height: " + wishH);
console.log("window height: " + winH);
console.log("content height: " + contH);
if(contH < wishH){
console.log("window is smaller than desired :(");
var newH = wishH - contH;
$("#par").height(parH + newH);
$(window).scrollTop(imgH);
}
}
Here is the working example:
http://jsfiddle.net/Uup62/1/
You may like this solution: http://jsfiddle.net/jy8pT/1/
HTML:
<div class="addScroll"></div>
<h1 class="logo"><img src="https://drupal.org/files/images/OQAAAI1PPrJY0nBALB7mkvju3mkQXqLmzMhxEjeb4gp8aujEUQcLfLyy-Sn4gZdkAas6-k8eYbQlGDE-GCjKfF5gIrUA15jOjFfLRv77VBd5t-WfZURdP9V3PdmT.png" height="100" alt="company logo"/></h1>
<h2>This is a sample page heading.</h2>
<p>This is a sample page text.</p>
JS:
function addScroll()
{
$(".addScroll").css({
"height": ($(window).height()+1) + "px",
"width": "100%"
});
}
$(document).ready(function(){
addScroll();
$(window).resize(function(){
addScroll();
});
$(window).scroll(function(){
if($(window).scrollTop() > 0)
{
$(".logo").animate({
marginTop: "-110px"
}, 500);
}
if($(window).scrollTop() == 0)
{
$(".logo").animate({
marginTop: "0"
}, 500);
}
});
});
CSS:
body
{
padding:0;
margin:0;
}
h1.logo
{
display:block;
margin:0 0 10px 0;
padding:0;
outline:0;
}
.addScroll
{
position:absolute;
display:block;
top:0;
left:0;
z-index:-1;
}

jQuery fade to new image

How can I fade one image into another with jquery? As far as I can tell you would use fadeOut, change the source with attr() and then fadeIn again. But this doesn't seem to work in order. I don't want to use a plugin because I expect to add quite a few alterations.
Thanks.
In the simplest case, you'll need to use a callback on the call to fadeOut().
Assuming an image tag already on the page:
<img id="image" src="http://sstatic.net/so/img/logo.png" />
You pass a function as the callback argument to fadeOut() that resets the src attribute and then fades back using fadeIn():
$("#image").fadeOut(function() {
$(this).load(function() { $(this).fadeIn(); });
$(this).attr("src", "http://sstatic.net/su/img/logo.png");
});
For animations in jQuery, callbacks are executed after the animation completes. This gives you the ability to chain animations sequentially. Note the call to load(). This makes sure the image is loaded before fading back in (Thanks to Y. Shoham).
Here's a working example
$("#main_image").fadeOut("slow",function(){
$("#main_image").load(function () { //avoiding blinking, wait until loaded
$("#main_image").fadeIn();
});
$("#main_image").attr("src","...");
});
Well, you can place the next image behind the current one, and fadeOut the current one so that it looks like as though it is fading into the next image.
When fading is done, you swap back the images. So roughly:
<style type="text/css">
.swappers{
position:absolute;
width:500px;
height:500px;
}
#currentimg{
z-index:999;
}
</style>
<div>
<img src="" alt="" id="currentimg" class="swappers">
<img src="" alt="" id="nextimg" class="swappers">
</div>
<script type="text/javascript">
function swap(newimg){
$('#nextimg').attr('src',newimg);
$('#currentimg').fadeOut(
'normal',
function(){
$(this).attr('src', $('#nextimg').attr('src')).fadeIn();
}
);
}
</script>
Are you sure you're using the callback you pass into fadeOut to change the source attr and then calling fadeIn? You can't call fadeOut, attr() and fadeIn sequentially. You must wait for fadeOut to complete...
Old question but I thought I'd throw in an answer. I use this for the large header image on a homepage. Works well by manipulating the z-index for the current and next images, shows the next image right under the current one, then fades the current one out.
CSS:
#jumbo-image-wrapper
{
width: 100%;
height: 650px;
position: relative;
}
.jumbo-image
{
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
HTML:
<div id="jumbo-image-wrapper">
<div class="jumbo-image" style="background-image: url('img/your-image.jpg');">
</div>
<div class="jumbo-image" style="background-image: url('img/your-image-2'); display: none;">
</div>
</div>
Javascript (jQuery):
function jumboScroll()
{
var num_images = $("#jumbo-image-wrapper").children(".jumbo-image").length;
var next_index = jumbo_index+1;
if (next_index == num_images)
{
next_index = 0;
}
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).css("z-index", "10");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).css("z-index", "9");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).show();
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).fadeOut("slow");
jumbo_index = next_index;
setTimeout(function(){
jumboScroll();
}, 7000);
}
It will work no matter how many "slides" with class .jumbo-image are in the #jumbo-image-wrapper div.
For those who want the image to scale according to width percentage (which scale according to your browser width), obviously you don't want to set height and width in PIXEL in CSS.
This is not the best way, but I don't want to use any of the JS plugin.
So what can you do is:
Create one same size transparent PNG and put an ID to it as
second-banner
Name your original image as first-banner
Put both of them under a DIV
Here is the CSS structure for your reference:
.design-banner {
position: relative;
width: 100%;
#first-banner {
position: absolute;
width: 100%;
}
#second-banner {
position: relative;
width: 100%;
}
}
Then, you can safely fade out your original banner without the content which placed after your image moving and blinking up and down

Categories

Resources