How can I animate an image on page scroll in a single page website so that when I scroll to next section it animates? Suppose I am using a closed eye which opens when I scroll to next section.
You can use the libgif library here: https://github.com/buzzfeed/libgif-js
It allows you to start, stop, or advance the gif frame programmatically. Here is an example straight from the source:
<script type="text/javascript" src="./libgif.js"></script>
<img src="./example1_preview.gif" rel:animated_src="./example1.gif" width="360" height="360" rel:auto_play="1" rel:rubbable="1" />
<script type="text/javascript">
$$('img').each(function (img_tag) {
if (/.*\.gif/.test(img_tag.src)) {
var rub = new SuperGif({ gif: img_tag } );
rub.load(function(){
console.log('oh hey, now the gif is loaded');
});
}
});
</script>
You can then use a combination of get_length (the number of frames in the gif), move_to (to go to a specific frame), and onscroll in jQuery/JavaScript to set the frame as the user scrolls your page.
There is also ScrollMagic which specializes in exactly what you are asking. Not sure about gif animations specifically, but they have tons of examples for different element animations.
Related
I have implemented a parallax effect with a video. I wanted to do it for my own so I did it without any framework or plugin but it is slow and it stumbles around.
My idea was that there are 2 pictures, 1 video and 2 boxes in front of them. So my code was that if i am on the position of the 1 picture, the pictures scroll slower (with margin-top) like this:
$( window ).scroll(function() {
var scroll = $(window).scrollTop();
if(scroll>470){
scroll = scroll-470;
var scrollSlow = scroll*0.4;
$('#Picture1').css('margin-top', scrollSlow);
$('#InfoBox1').css('margin-top', -scroll);
if(scroll<400){
$('#Picture2').css('margin-top', -scroll);
}
$('#InfoBox2').css('margin-top', -scroll+heightPX);
if(scroll<900){
$('#Picture3').css('margin-top', -scroll+heightPX);
}
}
}
But if I scroll down it doesn't work.
Here is the online version: http://p-goetz.de/Parallax.html
Problem: You are probably testing your website in chrome/safari, try using Firefox you will notice that the things are smoother.
Reason: In some browsers when you scroll they jump 100px at once hence your parallax animation start looking odd.
Solution: Try to use a custom scroll with smooth fx.I will recommend Nicescroll.
The issue is the images/videos are so large, the browser lags when scrolling before they are completely loaded. One solution would be to wait for the images/videos to finish loading before presenting the page.
$('body').hide();
var video = document.getElementById('PARALLAX_bild2');
video.addEventListener('loadeddata', function() { // video is loaded
$('img').load(function() { // images are loaded
// Do some fancy fade in of the page here. This is just an example.
$('body').show();
});
}, false);
Hope you are all well.
I am trying to create my own video gallery using html, CSS, and Javascript.
My idea is that there are thumbnails that are hyperlinks that when clicked, scroll to the top and plays a youtube video in an iframe.
So far i have managed to get both the scroll to top and changing the iframe source to work individually. But, annoyingly, they do not seem to work when they are together.
Could anybody give me tips on the best way of achieving my goal?
Here is the jsfiddle of the 'changing iframe source' code working: jsfiddle.net/2SH97/ (This has the design of the page and what it'll look like at the end)
Here is the jsfiddle of the 'scroll to top' code: jsfiddle.net/RpPEe/229/ (a short version of the scroll to top with my attempt to change iframe source)
Thanks in advance.
Best,
function scrollt(){
$("body").animate({
scrollTop: 0
}, 600);
}
$("[target='projectsiframe']").on('click',function () {
$("#ifr").attr('src',$(this).attr('href'));
scrollt();
});
DEMO
http://jsfiddle.net/2SH97/3/
I have a large gif animation on a web page and want to start it not until it's completely finished loading. How would that be possible using JavaScript / jQuery?
Use a placeholder image, and replace it with the animated GIF once that GIF is fully loaded:
<img id="anim" src="placeholder.gif">
JS:
var myanim = new Image();
myanim.src = '/img/actions.png';
myanim.onload = function() {
document.getElementById('anim').src = myanim.src;
}
http://jsfiddle.net/mblase75/6XTg7/
You can hide GIFs with CSS (or JS replacing them with a placeholder) and when GIFs are loaded you can fire show()
$('img[src$=".gif"]').load(function(){$(this).show())
You could hide it until it is fully loaded.
<!--- this uses jquery !-->
<script type="text/javascript">
var image_url = "http://media.tumblr.com/tumblr_m4doax3R071r9c1z7.gif";
var image = $('<img />').load(function(){
$(this).show();
}).attr('src', image_url).hide();
$('body').append(image);
</script>
The issue here is that once the image has been downloaded (i.e it is in the browsers cache), there really doesn't seem to be any way of starting it from a particular frame.
You have no control over gif animation through javascript, so you have to implement some sort of a hack. You have to make it hidden in the beginning. Instead of the actual picture you can put a div with the dimensions of the actual picture and with text like "wait".
When the image is downloaded in the browser you can substitute div with an image. And at that point of time animation will start
Thanks for looking, I have this plan, I want to create a gallery where I have the main image which is changed by mouse-ing over a bunch of 8 thumbnails, easy.
What I would like to add is separate small bunch of 3 thumbnails and when these are moused over they change the 8 thumbnail images and make them call up 8 new main images. Sorry I hope that’s understandable?
So it’s a little like a tiered or a nested arrangement almost like a small folder tree where the new 3 thumbs hold different libraries of 8 thumbs… no that’s probably just made it even more confusing!!!..
I was keen that it was all done with mouse over the thumbs so it’s smooth and there’s no clicking or reloading the page.
I’ve had a good look around but probably just need telling what terms/phrases/commands to pop in my search engine.
Getting the 3 thumbs to change the 8 thumbs and the main image should be straightforward enough I’m currently using this:
<img src = "images/nicepic5thumb.png" onmouseover =”document.main.src = 'images/nicepic5.jpg';">
Where the main big image is:
<img src = "images/nicepic1.jpg" name= "main">
And I guess it could be expanded to multiple images. Doesn’t have to be done like this however, just whatever would work best, it’s making one mousover change multiple mouseover commands thats currently beyond me.
Ultimately I aim to get all the transitions to fade.
Very grateful for a pointer in the right direction.
I would sent the 3 panels (or more) of 8 thumbs with the respective commands to change main images and make the 3 index thumbs switch the visibility of the 8 images panel
This is actually something that would be very easy to do in jQuery
All you need to do is add a common class to the images in the gallery or more efficiently add an ID to the element that contains the image and use that to select the images such as.
<img src = "images/nicepic1.jpg" name= "main" id="main_img">
<div id="gallery"><img src="nicepic1thumb.png"><img src="nicepic2thumb.png"><img src="nicepic3thumb.png"></div>
<script>
$(document).ready(function(){
$("#gallery img").onmouseover(function(){
$("#main_img").attr('src',$(this).attr('src').replace("thumb.png",".jpg"));
}
}
</script>
Here is a full working gallery without animations that does exactly what you wanted.
<html>
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript" ></script>
<script>
$(document).ready(function(){
gallery.init();
});
var gallery = {
main_img: null,
init:function(){
gallery.main_img = $("#main_img img");
$("#images img").click(function(){
gallery.change($(this).attr('src'));
});
},
change: function(image){
gallery.main_img.attr('src', image.replace("thumb.png",".jpg"));
}
}
</script>
</head>
<body>
<div id="gallery">
<div id="main_img"><img src="images/image1.jpg"/></div>
<div id="images">
<img src="images/image1thumb.png"/><img src="images/image2thumb.png"/><img src="images/image3thumb.png"/><img src="images/image4thumb.png"/><img src="images/image5thumb.png"/>
</div>
</div>
<body>
</html>
If you need animations such as fading and stuff just ask.
I've noticed this in numerous "modern" websites (e.g. facebook and google image search) where the images below the fold load only when user scrolls down the page enough to bring them inside the visible viewport region (upon view source, the page shows X number of <img> tags but they are not fetched from the server straight away). What is this technique called, how does it work and in how many browsers does it work. And is there a jQuery plugin that can achieve this behavior with minimum coding.
Edit
Bonus: can someone explain if there is a "onScrolledIntoView" or similar event for HTML elements. If not, how do these plugins work?
Some of the answers here are for infinite page. What Salman is asking is lazy loading of images.
Plugin
Demo
EDIT: How do these plugins work?
This is a simplified explanation:
Find window size and find the position of all images and their sizes
If the image is not within the window size, replace it with a placeholder of same size
When user scrolls down, and position of image < scroll + window height, the image is loaded
I came up with my own basic method which seems to work fine (so far). There's probably a dozen things some of the popular scripts address that I haven't thought of.
Note - This solution is fast and easy to implement but of course not great for performance. Definitely look into the new Intersection Observer as mentioned by Apoorv and explained by developers.google if performance is an issue.
The JQuery
$(window).scroll(function() {
$.each($('img'), function() {
if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
var source = $(this).data('src');
$(this).attr('src', source);
$(this).removeAttr('data-src');
}
})
})
Sample html code
<div>
<img src="" data-src="pathtoyour/image1.jpg">
<img src="" data-src="pathtoyour/image2.jpg">
<img src="" data-src="pathtoyour/image3.jpg">
</div>
Explained
When the page is scrolled each image on the page is checked..
$(this).attr('data-src') - if the image has the attribute data-src
and how far those images are from the bottom of the window..
$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)
adjust the + 100 to whatever you like (- 100 for example)
var source = $(this).data('src'); - gets the value of data-src= aka the image url
$(this).attr('src', source); - puts that value into the src=
$(this).removeAttr('data-src'); - removes the data-src attribute (so your browser doesn't waste resources messing with the images that have already loaded)
Adding To Existing Code
To convert your html, in an editor just search and replace src=" with src="" data-src="
(Edit: replaced broken links with archived copies)
Dave Artz of AOL gave a great talk on optimization at jQuery Conference Boston last year. AOL uses a tool called Sonar for on-demand loading based on scroll position. Check the code for the particulars of how it compares scrollTop (and others) to the element offset to detect if part or all of the element is visible.
jQuery Sonar
Dave talks about Sonar in these slides. Sonar starts on slide 46, while the overall "load on demand" discussion starts on slide 33.
There is a pretty nice infinite scroll plugin here
I've never programmed one myself, but I would imagine this is how it works.
An event is bound to the the window scrolling
$(window).scroll(myInfinteScrollFunction);
The called function checks if scroll top is greater than the window size
function myInfiniteScrollFunction() {
if($(window).scrollTop() == $(window).height())
makeAjaxRequest();
}
An AJAX request is made, specifying which result # to start at, how many to grab, and any other parameters necessary for the data pull.
$.ajax({
type: "POST",
url: "myAjaxFile.php",
data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
success: myInfiniteLoadFunction(msg)
});
The ajax returns some (most-likely JSON formatted) content, and passes them into the loadnig function.
Hope that makes sense.
You can now use loading="lazy" on the images as well as iframes so that it defers the loading until the user scrolls to that element.
<img src="http://placeimg.com/640/360/any" loading="lazy" />
As quoted in MDN:
Loading attribute The loading attribute on an element (or the
loading attribute on an ) can be used to instruct the browser
to defer loading of images/iframes that are off-screen until the user
scrolls near them.
Can I use?
You can use on all modern browsers for the images, but iframes are experimental as of now.
#import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
.scroll-down {
height: 100vh;
background: #037ef3;
display: grid;
place-items: center;
color: #fff;
font-family: "Oswald";
font-size: 2em;
}
.image {
padding: 2em;
display: grid;
place-items: center;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
<div class="scroll-down">
Let me take this space so that you can scroll down
</div>
<div class="image">
<img src="http://placeimg.com/640/360/any" loading="lazy" /> <!-- The only important part -->
</div>
Tip:
As you can see in the demo, it creates layout shift which will create a bad UX while scrolling. So try to use placeholders. Something similar like this: NextJS Placeholder
Lazy loading images by attaching listener to scroll events or by making use of setInterval is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.
Use Lozad.js (just 569 bytes with no dependencies), which uses IntersectionObserver to lazy load images performantly.
The Swiss Army knife of image lazy loading is YUI's ImageLoader.
Because there is more to this problem than simply watching the scroll position.
This Link work for me demo
1.Load the jQuery loadScroll plugin after jQuery library, but before the closing body tag.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>
2.Add the images into your webpage using Html5 data-src attribute. You can also insert placeholders using the regular img's src attribute.
<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">
3.Call the plugin on the img tags and specify the duration of the
fadeIn effect as your images are come into view
$('img').loadScroll(500); // in ms
Im using jQuery Lazy. It took me about 10 minutes to test out and an hour or two to add to most of the image links on one of my websites (CollegeCarePackages.com). I have NO (none/zero) relationship of any kind to the dev, but it saved me a lot of time and basically helped improve our bounce rate for mobile users and I appreciate it.