Hey, I'm just wondering how to cycle through a bunch of images, and set them as the background for a div.
What I'm looking to do is: set the first image as the background to a div. Wait X seconds. Set the next image as the background. Wait X seconds … etc. and continue
I've got the following code which works for 1 image.
$(document).ready(function() {
var source = $(".field-field-background img:first").attr("src");
$('.field-field-background img:first').remove();
$('#main-inner').css('background', 'url('+ source +') no-repeat');
});
I'm guessing I need to get an array of the image sources, loop through the array and set it as the background, with a delay somewhere in the loop. Any ideas how I'd do this?
One of the biggest advantages of jQuery is that it has a very robust plug-in community. Many tasks that you might want to accomplished have been tackled by others before you. Particularly with a common task like this, I would recommend looking for a plug-in first, before trying to reinvent the wheel. Many plug-ins have the advantage of having gone through rigorous testing and multiple versions, to result in a polished product.
The jQuery Cycle plug-in would be a good candidate, if you are looking to do a slideshow type effect. If what you want is to cycle the background, while keeping foreground elements, you might look at something more like this: Advanced jQuery background image slideshow
$(document).ready(function() {
Cycler={};
Cycler.src=['path/to/img1', 'path/to/img2', 'path/to/img3'];
Cycler.cur=0;
Cycler.cycle=function() {
if(++Cycler.cur>=Cycler.src.length) {
Cycler.cur=0;
}
$('#main-inner').css('background', 'url('+ Cycler.src[Cycler.cur] +') no-repeat');
setTimeout(Cycler.cycle, 5000);//5 seconds
}
Cycler.cycle();
});
try this:
setInterval(function(){
var source = $(".field-field-background img:first").attr("src");
$('.field-field-background img:first').remove();
$('#main-inner').css('background', 'url('+ source +') no-repeat');
},4000);
Related
I want to slide an image (of a boomerang) off screen and then 5 seconds later slide it back into place. I want the image to right next to some text to begin with and end.
Ideally I'd like the animation to be smooth. I can find many examples doing things like this, but none that seem to do this very simple thing. Any pointers in the right direction would be greatly appreciated.
$(document).ready(function()
{
var my_div = $("#target");
var div_top = my_div.offset().top;
$(document).scroll(function()
{
if (div_top <= $(document).scrollTop()+($(window).height() /2))
{
// EVENT TO SEND IMAGE OFF SCREEN TO THE RIGHT
// EVENT TO WAIT 5 SECONDS
// EVENT TO SEND THE IMAGE BACK
}
});
});
<div id="target;">
<p style="font-size:32px; display: inline;">TEXT</p>
<img id="foo" style="height:35px;" src="https://upload.wikimedia.org/wikipedia/commons/4/46/Ic_account_box_48px.svgg">
You've tagged the question with javascript and provide code that's an incomplete javascript solution, but you also mention you want it to be smooth.
Perhaps declaring a CSS animation using transforms would be better?
Check out https://daneden.github.io/animate.css/ for some examples of what a CSS animation can do. And they can be quite complex, as you can define as many steps as needed.
Now if in some of your animation steps you need to perform calculations, you're stuck with JS, but you can still use a library that uses CSS transitions under the hood get get a smooth frame-rate.
I've used move.js for such a task in the past, and worked pretty well.
https://visionmedia.github.io/move.js/
I am trying to achieve a "crt-like" scrolling glitch effect using Javascript and CSS. I have come up with the following code which clones the content and applies clip to make it look like it scrolls while adding random horizontal offset.
function scanglitch() {
var e = $('#wrapper').clone().appendTo('#glitchcontainer');
var i = 0;
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css("z-index",200);
var interval = setInterval(function () {
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css({"left": Math.round(Math.random() * 10) + "px"});
i+=4;
if (i > window.innerHeight) {
e.remove();
window.clearInterval(interval);
}
}, 40);
}
Fiddle (Click on the text to see the effect)
I am actually quite pleased with the effect, but the implementation is obviously a hack. As a result the performance is unacceptably low (chrome cpu usage spikes from 5% to 50% when the effect is triggered).
Could someone help me figure out a way to achieve this effect in a more elegant and less performance-heavy way?
UPDATE:
I have implemented your suggestions: Using translate instead of left, scrolling with translate instead of a js loop, calculations outside of the css tag and using requestAnimationFrame(). The code is nicer and more predictable now, but the animations are still very taxing.
New fiddle
You can try using requestAnimationFrame (it is available in almost all browsers). Seems to make a big difference in Chrome.
JSFiddle
EDIT
Here's a transition-only version, and while it doesn't even implement the jitter, it's useful for comparison. Surprisingly(?) it shows about the same, if not more, CPU usage. (You can check the Profile and Timeline tabs in Chrome)
CSS3 Transition-Only JSFiddle
Here's some information about why that should be expected. Essentially, CSS transitions and requestAnimationFrame work very similarly under the hood.
I would delegate as much as possible to css transitions. So instead of moving the clip with js in the interval callback, transition it from top to bottom (example of transitioning).
You could try something similar with the left property, there's no random easing function but maybe you could achieve something similar with one of the bounce functions. Maybe change the easing function with an interval that's less frequent than your current one.
Also, just by slowing the interval of your current solution you'd get visually ok results with less CPU usage.
Side-note: for a completely different route you can replicate your html in a canvas and apply some effects to that. Google has plenty of results for "canvas glitch".
Update: here's my version of your latest fiddle
I get about 10 % less cpu usage with it when comparing to yours. Key differences are:
uses a timeout instead of requestAnimationFrame. requestAnimationFrame is meant to keep framerate high and the animation smooth but we don't need that for the random offsetting. Timeout is also better than an interval since the loop function is quaranteed to finish before next iteration starts.
removed the transparent background, since transparency has a rendering cost
I am building a Star Wars fansite.
My navigation menu will be star wars lightsabers.
I am planning to make (when the cursor is over the lightsaber) for the actual light sword to come out. When the cursor leaves the lightsaber, it goes back down.
I have a gif that does that, but how to make it unactive then active when cursor is hovered over??
If the idea above doesn't sound correct, how would you suggest I do it?
No, you can't control the animation of the images.
You would need two versions of each images, one that is animated (.gif), and one that's not(.gif/.png/.jpg/etc).
On hover you can easily change from one image to another.
Example:
$(function(){
$('img').each(function(e){
var src = $(e).attr('src');
$(e).hover(function(){
$(this).attr('src', src.replace('nonanimated.gif', 'animated.gif'));
}, function(){
$(this).attr('src', src);
});
});
});
Reference link
like Parag Meshram said, but no need to do it with jQuery or JavaScript:
.foo {
background: url(still.png) no-repeat 0 0;
}
.foo:hover {
background-image: url(animation.gif);
}
It might be a overkill, but I think you can control the GIF with WebGL.
Here is some GIF manipulation, it's not what you ask for, but maybe some inspiration for doing something own http://www.clicktorelease.com/code/gif/
Your best bet is to actually split the handle and the sword into two different graphics to then animate the sword in with Javascript (as background property). This way you wouldn't have the restrictions of the GIF file format but still a lot smaller files. You'll need to create a div the same size as the sword and set it as background, then set the background-position-x to -100% and animate it back in on hover, you can use jQuery for that:
$('.sword').on('hover', function(event){
$(this).animate({
'background-position-x': '0%',
}, 100, 'linear');
});
$('.sword').off('hover', function(event){
$(this).animate({
'background-position-x': '-100%',
}, 100, 'linear');
});
(I wrote this off the top of my head, check the jQuery docs if this doesn't work)
I had a similar situation and found a pretty simple solution. I'm pretty new to JQuery, so I'm not sure if this is in line with best practices, but it works.
I've used a static image (.png for transparency, in my case) and switched out the src attribute to point to the animated .gif on mouseenter and back to the .png on mouseleave. For your lightsaber to go from hilt alone to powering up I would do it a bit differently than usual. Try taking a frame from the .gif in Photoshop and making it into a static image using "save for web and devices". I recommend .png. In your HTML markup use this static image of the hilt for your src of the image, also be sure to give it an ID, such as saber for this example.
Now onto the jquery script. I link it in a separate file. For one saber it should look something like this:
$(document).ready(function()
{
$("#saber").mouseenter(
function()
{
$(this).attr("src", "img/stillframehilt.png");
},
function()
{
$(this).attr("src", "img/saberpowerup.gif");
});
$("#saber").mouseleave(
function()
{
$(this).attr("src", "img/saberpowerup.gif");
},
function()
{
$(this).attr("src", "img/stillframehilt.png");
});
});
Notice the on mouseleave I had it switch src to "img/saberpowerdown.gif". I think that rather than have the saber revert back instantaneously to the hilt in its dormant state (which any Star Wars geek[myself included] would wince at) it would look better to have a .gif that is essentially the reverse of the saber turning on. This can be achieved by reversing the order of the animation frames(ensure that visible layers are correct). For good measure I would make sure when to have it not loop either .gif's as well as add a few extra frames of the hilt alone when the power down is finished to ensure it remains off.
Also, it might be beneficial to add a .click to the saber to change the src to the power down, or even a different animation, but that is just extra flair. For each additional lightsaber use the same code, just changing the id to reference each in a logical way such as by color.
Again, I can't claim this to be in line with best practices as far as jquery goes (I'm but a padawan) but this method worked when I needed to activate a .gif on mouseenter and back on .mouseleave . May The Force be with you.
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'});
The issue I am having is fairly complicated to explain. I have written up a javascript that displays an image slideshow, and it works fairly well, despite using up more resources than I would like
// imgArr[] is populated before
var i = 0;
var pageLoaded = 0;
window.onload = function() {pageLoaded = 1;}
function loaded(i,f) {
if (document.getElementById(i) != null) f();
else if (!pageLoaded) setTimeout('loaded(\''+i+'\','+f+')',100);
}
}
function displaySlideshow() {
document.getElementById(destinationId).innerHTML = '<div id="slideWindow"><img src="'+imgArr[i]+'" />' + '<img src="'+imgArr[i + 1]+'" /></div>';
setTimeout('displaySlideshow()',1000*3);
i++;
if (i >= imgArr.length - 1)
i = 0;
}
loaded(destinationId,displaySlideshow);
So, this script dynamically adds two images to a HTML element, and it is wrapped in a div.
The div is styled with the height and width of the image, with the overflow (the second image) hidden.
The second image is below the first, and the slideshow is meant to go from RIGHT to LEFT.
My inquiry is twofold:
1) Is there a more efficient way of doing this?
2) How would I animate the images? Would I need to put the second image on the right of the first with CSS somehow, and then set a timer to pull the images (via a style) leftward?
I really don't recommend rolling your own animation library. The Facebook Animation Library written by the wonderful Marcel Laverdet is simple to use and comes with a lot of tutorials to get what you want out of your slideshow. (Note: ignore the FBJS stuff, it's exactly the same even if you're using it on your own site.)
If you're not using a framework, I think you'll find a lot of pain ahead of you. If you still don't want to use a framework, at least find one that is liberally licensed, and take a look at the source code. Here's one, for example.
The basic theory is, yes, you set a timer that moves the image on some sort of interval, either fixed or based on some sort of mathematical equation (eg, sin, cos, etc). By setting these intervals close together, and making lots of them, you get an "animation" in javascript. Typically, you'd use some sort of absolute positioning, moving one element off the screen as the other moves on.