I'm currently building a simple "jQuery Image Slider" but it does not work as i hoped. It's incredible slow and unresponsive, and the last image does not do anything.
URL: http://fusionmedia.dk/jquery/
What is the problem?
Thanks in advance
Specify a faster speed. Its defaulting to a slower speed.
$('#gallery').delegate('img', 'mouseover', function() {
$this = $(this);
for(var i = 0; i <= $this.siblings().size(); i++) {
if($this.index() > i) {
$this.siblings().eq(i).stop().animate({ left: (i * 50) + 'px' }, 300);
} else {
$this.siblings().eq(i).stop().animate({ left: ((i * 50) + 500) + 'px' }, 300);
}
}
});
EDIT:
You have 2 really bad problems for speed.
1: You are running a time costly loop every time they hover.
2: You are calling $this.siblings() too many times. Cache that.
Here is an example of how to better implement some of this, I still have you loop inside the hover event, you should try and get that moved out.
$(function(){
$('#gallery').find('img').each(function(){
$this = $(this);
$this.css('left', $this.index() * 50 + 'px');
});
$('#gallery').delegate('img', 'mouseover', function(){
$this = $(this);
var $sibs = $this.siblings();
for (var i = 0; i <= $sibs.size(); i++) {
if ($this.index() > i) {
$sibs.eq(i).stop().animate({
left: (i * 50) + 'px'
});
} else {
$sibs.eq(i).stop().animate({
left: ((i * 50) + 500) + 'px'
});
}
}
});
});
It depeneds on various things , are you loading all the images upfront and even size of the images matters alot.
All your subsequent requests should be cached in the browser.
you should use some caching mechanisims if possible.
Related
As you can see on this page: http://www.gigil.it/newroot/index.php//come-doniamo
I have some svg animations done with snap SVG.
The animations are triggered when the element is in the viewport.
And it's basically doing the same animation on all the paths inside the SVG.
Here is the script:
jQuery(window).scroll(function() {
jQuery(".icon-come-doniamo").each(function(){
//console.log($(this));
if (jQuery(this).isOnScreen() == true) {
if (!jQuery(this).hasClass("already-visible")){
var $that = jQuery(this);
setTimeout(function(){
//jQuery(this).addClass("already-visible");
var Elemento = $that.find("svg");
var iconSnap = Snap("#"+Elemento.attr("id"));
var iconPaths = iconSnap.selectAll("path");
var delays = 0;
var count = 0;
iconPaths.forEach(function(elem,i) {
setTimeout(function(){
//console.log("gegge");
var elemDim = elem.getBBox();
elem.animate({transform: 'r0,' + elemDim.cx + ',' + elemDim.cy + 's1,1' }, 700, mina.linear );
}, delays);
delays = delays + 400;
count = count + 1;
});
if (count == iconPaths.length) {
//console.log("fattgegge");
$that.addClass("already-visible");
}
},1000);
}
}
});
});
Pretty simple I think, but very often the FPS gets really really low and the animations become super bulky.
I've tried anything, but no big changes.
Any tips?
Solved it by removing the Bounding Box calculations.
Removed the rotation property.
Now it's a lot smoother.
From this:
elem.animate({transform: 'r0,' + elemDim.cx + ',' + elemDim.cy + 's1,1' }, 700, mina.linear );
to this:
elem.animate({transform: 's1,1' }, 700, mina.linear );
So for one of my new projects, I decided to write a super simple parallax script for some background images on scroll. This is what I came up with:
$(document).ready(function(){
parallaxScroll();
$(window).bind('scroll', function() {
parallaxScroll();
});
});
function parallaxScroll() {
$(".parallax").each(function() {
if($(this).hasClass('reverse')) {
$(this).css("background-position","center " + (($(this).offset().top - $(window).scrollTop())/2) + "px");
} else {
$(this).css("background-position","center " + (($(this).offset().top - $(window).scrollTop())/-2) + "px");
}
});
}
My question is, is this efficient enough? If not, is there a better solution? I wasn't sure if using an .each() would be best for performance, but it seems to work fine. The reason I have the function run at document load is so when you scroll the page for the first time, the background image doesn't jump.
Instead of css which sets the value immediately, consider using animate instead. It defers setting values using timers/requestAnimationFrame, ensuring that your animation does not block the UI, is async (runs pseudo-parallel to other code), and ensures that the animation is smooth.
This is a plain JS solution, but you'll be able to port it to jQuery really easily:
var lastScrollY = 0;
var backgroundImageY = 0;
var requestAnimationFrame = window.requestAnimationFrame ||
window.msRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame;
window.addEventListener('load', processScrollEvent);
function processScrollEvent() {
var innerHeight = window.innerHeight;
var scrollHeight = document.body.scrollHeight;
var backgroundImage = document.querySelector('#background img');
lastScrollY = document.body.scrollTop;
var currBackgroundImageY = Math.round(((backgroundImage.scrollHeight - innerHeight) / 100) * ((lastScrollY / (innerHeight - scrollHeight)) * 100));
if(currBackgroundImageY != backgroundImageY) {
backgroundImageY = currBackgroundImageY;
requestAnimationFrame(processScrollAnimationFrame);
}
}
function processScrollAnimationFrame() {
var backgroundImage = document.querySelector('#background img');
var transforms = ['transform', 'oTransform', 'msTransform', 'mozTransform', 'webkitTransform'];
for(var i = 0; i < transforms.length; i++) {
backgroundImage.style[transforms[i]] = 'translate3d(0, ' + backgroundImageY + 'px, 0)';
}
}
I'm trying to create a background with many circles moving around and it really pushes the browser a bit too hard.
Is there any way I can do this without being too resource-intensive?
Here's the current code I have:
http://jsfiddle.net/2MGAE/2/
$( document ).ready(function() {
// Create all our glorious bubbles
for (var i = 1; i <= 150; i++) {
$('#bubbles').append('<span class="bubble' + i + '"></span>');
}
// Get random number
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Function to move bubbles randomly
function moveRandom(obj) {
var positionTop = getRandomInt(-350,1000);
var positionLeft = getRandomInt(-700,1600);
var positionTopNew = positionTop + getRandomInt(-50,50);
var positionLeftNew = positionLeft + getRandomInt(-50,50);
var size = getRandomInt(30,60);
function animation() {
obj.animate({
top: positionTop + 'px',
left: positionLeft + 'px',
width: size,
height: size
}, 6000
);
obj.animate({
top: positionTopNew + 'px',
left: positionLeftNew + 'px'
}, 6000, function() {
animation();
});
}
animation();
}
// Activate bubble movement
$('#bubbles span').each(function() {
moveRandom($(this));
})
});
Or is it just too many elements animated that it will always be a resource hog?
Pretty neat! You may want to use the HTML 5 canvas element to do this. It will utilize the GPU and doesn't require 3rd party js libraries.
REF:
http://updates.html5rocks.com/2012/07/Taking-advantage-of-GPU-acceleration-in-the-2D-canvas
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial
There are 2 things that come to mind.
You could look up how to use the <canvas> tag with really cool examples at Createjs.com
or
you could gopro and learn webgl and three.js which uses the gpu for cool fast 3d effects!
I have a function which is almost working.
It finds an element with the class of .hex and then runs a random number between 5 and 13 and then appends those .hex items to the body of the document.
Then I have a delay and the hexagons are faded in and out slowly.
What I want to do is to create this on a loop so they constantly fade in and out.
I have commented out the code where this should work to my understanding, but currently doesn't.
All I did was to wrap all my code in a new function called initHex() and then after the code I use setInterval to run the function every 12 seconds (at the moment).
I can see in the console the function runs, and then starts looping very fast, the numbers incrementing dramatically, and quite quickly it stops the browser responding.
I am wondering if the function is wrapped around too much of the code.
The idea is that hopefully the current function is still running (fading out hexagons) as new ones are fading in.
I am assuming at the end of the function I will also require something to remove the existing hex elements so they don't keep getting added to the document. I did try this.
Here is the function:
//function initHex() {
$rndNum = Math.floor(Math.random() * 8) + 5;
var e = $('.hex');
for (var i = 0; i < $rndNum ; i++) {
$docHeight = $(window).height();
$docHeight = Math.random() * $docHeight * 2;
$docWidth = $(window).width();
$docWidth = Math.random() * $docWidth;
$rndOpacity = Math.random();
$rndSpeed = Math.floor(Math.random() * 2000) + 2000;
e.each(function(){
$(this).css({
position: 'absolute',
top: $docHeight,
left: $docWidth - 195,
opacity: $rndOpacity
});
e.clone().prependTo('body').delay(e.length*800).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2);
console.log($rndNum, $rndOpacity, $rndSpeed);
});
}
//}
//setInterval(initHex, 12000);
In terms of removing the hexagons once they have run I tried:
e.clone().prependTo('body').delay(e.length*800).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2.5, function(){
e.remove();
});
Here is the fiddle: http://jsfiddle.net/lharby/j5bSz/
Fork it to your hearts content.
TIA
I have reworked your code. You made a few mistakes and yes you have tried to clone the whole bunch of elements with class hex each time, but the array have no method clone.
Try this:
function initHex() {
var $rndNum = Math.floor(Math.random() * 8) + 5;
for (var i = 0; i < $rndNum ; i++) {
var $docHeight = $(window).height()
, $top = Math.random() * $docHeight * 2
, $docWidth = $(window).width()
, $left = Math.random() * $docWidth - 195
, $rndOpacity = Math.random()
, $rndSpeed = Math.floor(Math.random() * 2000) + 2000;
$('<div></div>').addClass('hex').css({
position: 'absolute',
top: $top,
left: $left,
opacity: $rndOpacity
}).prependTo('body').delay(1000).fadeIn($rndSpeed).delay(1000).fadeOut($rndSpeed*2, function(){
this.remove();
});
}
}
setInterval(initHex, 12000);
One more thing, this code is still not optimized, but I have tried to save your code as much as possible to be more clear for you.
http://jsfiddle.net/andbas/DZSJT/1/
ok so i have an interspire shopping cart so its hard to customize..
anyway,
here is a link to my code
http://jsfiddle.net/WTvQX/
im having trouble getting the scroll to work properly...
it works differently on my actual site here...
so i need help... re-doing it or just fixing..
let me kno
You need to add the "relatedLeft" ID to the left button, however try something like this...
Demo: http://jsfiddle.net/wdm954/WTvQX/3/
$('#relatedRight').click(function() {
$('#scool').animate({left: "+=100px"}, 'slow');
});
$('#relatedLeft').click(function() {
$('#scool').animate({left: "-=100px"}, 'slow');
});
You can adjust pixel distance and speed to your liking.
EDIT: Try something like this. The first part finds the width of all the images. Then the animates only fire when the offset is within range.
Demo: http://jsfiddle.net/wdm954/WTvQX/5/
var w = 0;
$('#scroll img').each(function (i, val) {
w += $(this).width();
});
$('#relatedRight').click(function() {
var offset = $('#scroll').offset();
if (offset.left < w) {
$('#scroll').animate({left: "+=100px"}, 'slow');
}
});
$('#relatedLeft').click(function() {
var offset = $('#scroll').offset();
if (offset.left > -w) {
$('#scroll').animate({left: "-=100px"}, 'slow');
}
});
EDIT: One more code option here. This one will stop scrolling sooner (note there are CSS changes here also).
Demo: http://jsfiddle.net/wdm954/WTvQX/7/
var w = 0;
$('#scroll img').each(function (i, val) {
w += $(this).width();
w += parseFloat($(this).css('paddingRight'));
w += parseFloat($(this).css('paddingLeft'));
w += parseFloat($(this).css('marginRight'));
w += parseFloat($(this).css('marginLeft'));
});
$('#scroll').css('width', w + 'px');
$('#relatedRight').click(function() {
var offset = $('#scroll').offset();
if (offset.left < 0) {
$('#scroll').stop().animate({left: "+=100px"}, 'slow');
}
});
$('#relatedLeft').click(function() {
var offset = $('#scroll').offset();
var b = $('#bar').width();
if (offset.left > b-w) {
$('#scroll').stop().animate({left: "-=100px"}, 'slow');
}
});