I would like to do something like this: http://javascript.about.com/library/blcmarquee1.htm
The script I referenced however seems to be a bit laggy (outdated?), so I was wondering if anyone knew of a better solution. (jQuery solutions welcome.)
Just found this — jQuery-driven, and has images. I’m intending to use it for a current project.
http://logicbox.net/jquery/simplyscroll/
UPDATE: I have now used this in production code. The plugin is capable of looping 70+ 150×65px images pretty smoothly - which a number of another plugin I tried similar to this were failing on.
NOTE it reeked havoc with z-index issues in IE 6 / 7 and was not showing up etc. - But this might also have been partly due to my CSS. To anyone having trouble with it not showing up at all in IE check out the standard IE z-index fixes: http://www.google.com/search?q=ie+z+index+issues
LATEST UPDATE:
Addition things to consider when implementing plug-ins like these:
The number of items and type of content to scroll. I found a number that would start to glitch as soon as you had more than say 15 images to scroll.
I found a number of these plugins that were tied to old versions of jquery
If scrolling images ARE THEY ALL THE SAME SIZE again a number of the plug-ins I experimented with only worked if all the images were the same size but did not make this clear in the tutorials. I believe then the plugins run then set a string of li tags that are all x wide then calculate the total distance of them all chained together to manage the scrolling.
Effects - some would continuously scroll others would move one image pause for a second then move another image
I have now also found these two scroller plugins to be very good as well.
http://caroufredsel.frebsite.nl/
http://sorgalla.com/jcarousel/
The Silky-Smooth jQuery Marquee and Giva Labs' Marquee
Just a thought. Could you do something like this.
<style type="text/css">
.imgwindow{
width:500px; //or whatever
height:65px; //or whatever
position:relative;
overflow:hidden;
}
.imgholder{
min-width:2000px;
height:65px;
position:absolute;
left:-200px;
}
.inline-image{
display:inline-block;
}
</style>
<script type="text/javascript">
var img;
function imgScroll(){
img = $(".inline-image").first();
img.animate({width:0},2500,'linear',function(){
img.remove();
$(".imgholder").append(img);
imgScroll();
});
}
$(document).ready(function(){
imgScroll();
});
</script>
and the html
<div class="imgwindow">
<div class="imgholder">
<img class="inline-image" src="image1" /><img class="inline-image" src="image2" />...
</div>
</div>
Related
I'm moving a very long image using -webkit-transform: translate(-958px, 0); animation
The image gets cut off very soon after it starts to move horizontally, but if I slightly move the tablet screen, it redraws the screen and it displays the whole image while panning across and very smoothly too.
But how do I simulate this in code?
Some suggestion:
Provide the tablet model and android version may help
Information like image dimension and size, animation duration, or a demo page on jsfiddle/jsbin will help a lot
Back to the question:
in the performance term, using translate3d will get better performance, since it doesn't work, the main bottleneck is elsewhere.
from my experience with mobile webkit, when there is large image (in term of size or dimension), you may have trouble:
Ram problem
High Network Delay
Long enough loading and rendering time
If your UI-triggered redraw will smooth everything, the lag may be caused by image loading & rendering
Solution:
Set a reasonable delay on your animation by animation-delay or setTimeout
More precise: preload the image, and then trigger the animation when it is done by listening its onload event: jQuery .load explanation on image load event behaviour
If the above not work for you, try it: Force-redraw DOM technique for WebKit-based browsers
For 2 & 3, the code will be like this:
$("<img>")
.attr({ src: " /* image url */ " })
.load(function(){
/* i. use class or animationName to set animation */
/* ii. force redraw go there if needed */
/* wrap i & ii into a setTimeout function inside this callback
if more delay is needed */
})
good luck.
This little snippet of code and blog post from Paul Irish might be helpful to you:
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
And it's nearly cross browser if that floats your boat.
Forgive me if I'm not reading your question right.
Are you planning on using the tablet's gyro to pan about a large image? That should be possible in code.
However, forcing a transition to update faster is out of the developer's control, to my knowledge. The best you can do is make sure that that is all the tablet has to worry about.
<!DOCTYPE html>
<html>
<head>
<style>
body {
padding:0px;
overflow:hidden;
}
#img {
position:absolute;
left:0px;
top:20px;
-webkit-transition:left 0.5s;
}
</style>
</head>
<body>
<img id="img" src="img.png" />
</body>
<script>
function onOrientationChange(e) {
var img = document.getElementById("img");
var maxWidth = img.clientWidth - document.body.clientWidth;
img.style.left = ((e.gamma-90) * maxWidth / 180 ) + "px";
}
window.addEventListener('deviceorientation', function(e){onOrientationChange(e)}, true);
</script>
</html>
Have you tried using translate 3d? GPU kicks in when it's used.
HTML5 App/Animation Performance
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.
I like to think I'm not a dummy, but I can't get my jQuery horizontal slideshow to animate smoothly especially in FireFox (on a Mac). Anyone have advice?
Animation is being done like so:
$('#lookbook').stop().animate({left: -((lookbook-1)*825)+'px'}, { duration: 800, complete: cap_fade(1)});
Example link:
http://mayfourteenth.com/w/lookbook?preview=1
I've tested in Firefox, Chrome(dev) and Safari on windows and the animation stutters in all browsers(but more in FF though).
To increase JavaScript performance you could get rid of all the getElementById or $("div#mydividentyfier") calls.
If you store them in variables instead they will be cached.
Example:
It could increase performance quite a bit to do this:
var lookbook = $('#lookbook');
var look_caption = $('#look_caption');
if (lookbook.length) {
lookbook.width(lookbook).width()*$('#lookbook img').length)
if (look_caption) {
look_caption.html(lookcaps[0]);
look_caption.fadeIn();
}
Instead of:
if ($('#lookbook').length) {
$('#lookbook').width($('#lookbook').width()*$('#lookbook img').length)
if ($('#look_caption')) {
$('#look_caption').html(lookcaps[0]);
$('#look_caption').fadeIn();
}
I would also recommend using data URIs for the images as it reduces the amount of httpRequests you have to make to get the page loaded.
The animation looks smooth for me in Chrome. However, I believe there are several things you can do to improve smoothness:
First, it's fine to preload all of the images in advance as you do here (at the top). However, displaying them all at once, as in the "Example link", hurts performance, as they are all animating at once:
<div id="lookbook">
<div><img src="/q_images/lib/lookbook/1.jpg"></div>
<div><img src="/q_images/lib/lookbook/2.jpg"></div>
...
<div><img src="/q_images/lib/lookbook/15.jpg"></div>
</div>
Instead of doing this, you can simply cue up the next and previous image on either side of the current image, but then don't have the rest of the images in the page until they're needed. (Preloading them is still fine though.)
Other things which can improve performance slightly are things like the following:
Use smaller (by pixels and/or file size) images.
Make minor code optimizations by computing things in advance.
Use a stand-alone animation library instead of jQuery.
You may also want to use this
.animate({left:'-=825'}); //next
//and
.animate({left:'+=825'}); //previous
Instead of
.animate({left: -((lookbook-1)*825)+'px'});
Please check this page: http://islandhideaway.weebly.com/
For whatever reason, the flash slideshow moves over 1 pixel when opened in Firefox on my Mac. All other browsers render it fine, but only on Firefox it leaves a 1 pixel white gap on the left!
I am using the most recent version of SWFObject. This unfortunately is a garbage Weebly site and I cannot use jQuery in the system so I can't do a real gallery... so let's save the whole "don't use Flash for that" pep talk. It's a favour for a friend and I am already aware of better ways to do it. :)
you should use this in your object code
<param name="SCALE" value="exactfit" />
and for menu you should use transparent flash
<PARAM NAME=wmode VALUE=transparent>
and find the embed and add this
wmode="transparent"
try this
I had the same problem, and kc rajput's answer didn't help for me. (So this may be two distinct bugs.)
For me, the 1px offset bug occurred depending on whether the browser viewport width was an odd or even number of pixels. So, resizing the browser window just a bit made the problem go away or come back. The Flash object was in a horizontally centered element.
Anyway, this tweak helped for me. Basically I just added a border-left: 1px solid transparent; for the element that had margin-left: auto; margin-right: auto;.
Of course, if your centered element already contains a border, it won't be that simple.
I realize this question has already been answered, but I was googling for this problem today and came across this link. I used a javascript fix that seems to work very well. I found the original javascript in this Mozilla bug discussion, and then I modified it a bit.
https://bugzilla.mozilla.org/show_bug.cgi?id=550246
Here is the javascript that I ended up using (I hope it shows up properly in this post):
<script type="text/javascript">
var isFireFoxMac=false;
if (navigator.userAgent.indexOf("Firefox")!=-1) {
if (navigator.platform == "MacIntel" || navigator.platform == "MacPPC") {
isFireFoxMac = true;
}
}
function isEven(value){
return (value%2 == 0);
}
function ensureOddWidth() {
var width = window.innerWidth;
if (isEven(width)) {
self.resizeTo(width-1, window.outerHeight);
}
}
if (isFireFoxMac) {
window.onresize = ensureOddWidth;
window.onload = ensureOddWidth;
}
</script>
You can also do something like:
div.flashContainer {position:relative; width:200px; left:50%; margin-left:-100px }
Replace the width value with your value and make the margin-left negative half that. Another standard way of centering something which avoids the margin:0 auto bug.
Here is a link: http://www.avineon.com/
Open this link see on the top. Four images are rotating.
I need something similiar using Javascript.
Is it possible by using Javascript.
I don't think you'll have much luck if you try to do that in pure javascript. It might be possible using the emerging canvas and SVG libraries such as Raphael, but you'll still have cross-browser issues. That site used Flash, and I'd recommend using that if you wanted such an effect.
...why you'd want that on your website is another story though...
You could so something similar, but not exact.
Transparency = Supported in FF, Safari, IE7+
Changing image width = Place image in div with this Css
.class img {
display: block;
width: 100%;
height: 100%
}
This will make the image stretch to fill the .class div. You can then use JS to make this div narrower like the carousel does, and the image contained will animate within the div.
You would then need to track the mouse locations to determine how fast it spins.
You can use an equation using cosine for smooth acceleration from the far ends (IIRC)
You will not however be able to get the images in reverse, unless you create a copy in a server side language or use canvas.
Your best bet would not be to attempt to render something in actual 3D, but rather to use visual tricks to approximate a 3D effect. That is, use perspective / image deformation to make it look like a cube is rotating, similar to what is implemented at this page, which has a better explanation of the math involved.
Really, though, you're probably better off just using Flash.
That effect is possible in JavaScript simply by modifying each of the images width, height, and left styles over time. It's an involved script, but only needs to interpolate those three styles on the each of the image elements.
To get the rotation effect, decrement the width style of the image in a setInterval function while moving the left style property. There is a slight decrement on the height also.
You'll need two images for each side, a front and reverse. When the width decrements to zero, swap the image with it's flipped version and start incrementing the width.
Alternatively use Webkit's, and Firefox's transform css properties.
Or try one of these coverflow components that look similar:
Protoflow,
ImageFlow
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
if (document.all || document.getElementById){ //if IE4 or NS6+
document.write('<style type="text/css">\n');
document.write('.dyncontent{display: none; width: 728px; height: 90px;}\n');
document.write('</style>');
}
var curcontentindex=0;
var messages=new Array();
function getElementByClass(classname){
var inc=0;
var alltags=document.all? document.all : document.getElementsByTagName("*");
for (i=0; i<alltags.length; i++){
if (alltags[i].className==classname)
messages[inc++]=alltags[i];
}
}
function rotatecontent(){
//get current message index (to show it):
curcontentindex=(curcontentindex<messages.length-1)? curcontentindex+1 : 0;
//get previous message index (to hide it):
prevcontentindex=(curcontentindex==0)? messages.length-1 : curcontentindex-1;
messages[prevcontentindex].style.display="none"; //hide previous message
messages[curcontentindex].style.display="block"; //show current message
}
window.onload=function(){
if (document.all || document.getElementById){
getElementByClass("dyncontent");
setInterval("rotatecontent()", 5000);
}
}
</script>
<table width="100%">
<tr align="center">
<td>
<div class="dyncontent" style="display: block">
first
</div>
<div class="dyncontent">
second
</div>
<div class="dyncontent">
Third
</div>
</td>
</tr>
</table>
</body>
</html>