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.
Related
I have been using $().hide and $().show to make a smooth transition between images in a slideshow-like fashion. For example, when the right arrow key is pressed, the current image being displayed will slide to the left and disappear, the image will change, and it will slide into view from the right. This is the code I use for such a transition:
$('#mainImage').hide("slide", { direction: "left" }, 200);
$('#mainImage').show("slide", { direction: "right" }, 700);
setTimeout(function() { changeImg(pageNumberNew); }, 200);
The setTimeout() function is purely to control when in the transition the image source will change. The pageNumberNew variable is the URL of the image to be changed to. Here is the changeImg() function:
function changeImg(number) {
document.getElementById('mainImage').setAttribute('src', "/largefiles/2021roadatlas/Images/" + number + ".jpeg");
curPageNumber = number;
setWidth();
}
However, on the first transition of images, it will become very choppy, because the images haven't been loaded yet. I have tried various methods of preloading images, such as
Preloading images with JavaScript
Preloading images with jQuery
Waiting for image to load in JavaScript
JavaScript waiting until an image is fully loaded before continuing script
But none of these have worked.
Once an image has been loaded for the first time, navigating back to that image will be smooth. I would like a solution where these images can be preloaded before the user starts interacting, possibly loading each image before the transitions take place - causing for a slight delay in starting the animation, but allowing it to be smooth.
You can see what I have so far in action here, if you type in 13 and use the right and left arrow keys. The animations might not be choppy if you use desktop, try that website on mobile to see the issue.
TO BE CLEAR: I want a way to preload images in JavaScript, but I haven't been able to use the normal methods of preloading images, as described above.
The reason it is loading so slow is the large image. You should make the image size of the original photo smaller. I can see that the original size is around 5000 x 6500 and you are scaling it down to around 1000 x 600. The original image is unnecessarily big which causes the slow load.
This is certainly going to be an easy one but I can't get my head around what I am doing wrong...
I am trying to do a hover effect on a UL that affects a link within one of the UL LI's.
My current code looks like this:
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
});
$("ul.punchlines").mouseleave(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});
This technically works as it gives the effect that the base of the element to be scaled remains in place and scales up from the bottom however it does it in two stages, I am trying to get this effect to happen all in one motion so it is a seamless scale and move.
I can do this easily with basic CSS3 transitions but as it is not supported in IE9 I am trying to use jQuery to allow for maximum browser support.
Can anyone offer a little support firstly about how I get the animation to happen in one motion (not staggered) and secondly if this is the right approach? I am new to jquery and only just getting my hands dirty with it :-)
Please see JQuery hover api:
http://api.jquery.com/hover/
also make sure that your "li" have absolute position.
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
}, function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});
See the following fiddle:
[edit: updated fiddle => http://jsfiddle.net/NYZf8/5/ ]
http://jsfiddle.net/NYZf8/1/ (view in different screen sizes, so that ideally the image fits inside the %-width layouted div)
The image should start the animation from the position where it correctly appears after the animation is done.
I don't understand why the first call to setMargin() sets a negative margin even though the logged height for container div and img are the very same ones, that after the jqueryui show() call set the image where I would want it (from the start on). My guess is that somehow the image height is 0/undefined after all, even though it logs fine :?
js:
console.log('img: ' + $('img').height());
console.log('div: ' + $('div').height());
$('img').show('blind', 1500, setMargin);
function setMargin() {
var marginTop =
( $('img').closest('div').height() - $('img').height() ) / 2;
console.log('marginTop: ' + marginTop);
$('img').css('marginTop', marginTop + 'px');
}
setMargin();
Interesting problem...after playing around with your code for a while (latest update), I saw that the blind animation was not actually firing in my browser (I'm testing on Chrome, and maybe it was firing but I wasn't seeing it as the image was never hidden in the first place), so I tried moving it inside the binded load function:
$('img').bind('load', function() {
...
$(this).show('blind', 500);
});
Now that it was animating, it seemed to 'snap' or 'jump' after the animation was complete, and also seemed to appear with an incorrect margin. This smacks of jQuery not being able to correctly calculate the dimensions of something that hadn't been displayed on the screen yet. On top of that, blind seems to need more explicit dimensions to operate correctly. So therein lies the problem: how to calculate elements' rendered dimensions before they've actually appeared on the screen?
One way to do this is to fade in the element whose dimensions you're trying to calculate very slightly - not enough to see yet - do some calculations, then hide it again and prep it for the appearance animation. You can achieve this with jQuery using the fadeTo function:
$('img').bind('load', function() {
$(this).fadeTo(0, 0.01, function() {
// do calculations...
}
}
You would need to work out dimensions, apply them with the css() function, blind the image in and then reset the image styles back to their original states, all thanks to a blind animation that needs these dimensions explicitly. I would also recommend using classes in the css to help you manage things a little better. Here's a detailed working example: jsfiddle working example
Not the most elegant way of doing things, but it's a start. There are a lot more easier ways to achieve seemingly better results, and I guess I just want to know why you're looking to do image blinds and explicit alignment this way? It's just a lot more challenging achieving it with the code you used...anyways, hope this helps! :)
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);
I use the following snippet to make an element's background lightblue, then slowly fade to whiite over 30 seconds:
$("#" + post.Id).css("background-color", "lightblue")
.animate({ backgroundColor: "white" }, 30000);
Two questions.
First, instead of fading to white, is there a way to fade opacity to 100%? That way I don't have to change "white" if I choose to change the page's background color?
Second, about once out of every 10 or 15 times, the background stays lightblue and fails to fade to white. I'm using the latest versions of jQuery and the UI core. What could be going wrong?
EDIT: Bounty is for a solution to problem regarding second question.
EDIT2:
Apparently I got downvoted into oblivion because I said I rolled my own solution but didn't show it. My bad. I didn't want to be self-promoting. My code works 100% of the time and doesn't require jQuery. A demonstration and the code can be found at:
http://prettycode.org/2009/07/30/fade-background-color-in-javascript/
For your second question: in my experience this is usually because a Javascript error has occurred somewhere else on the page. Once there is one Javascript exception, the rest of the page stops running Javascript. Try installing Firebug (if you haven't already), then open up the "Console" tab and enable it. Then any javascript errors or exceptions will be printed to the console.
Another thing to try (which kinda contradicts my last statement...) is to disable all your browser plug-ins to see if you can recreate. Sometimes they interfere with scripts on the page (particularly GreaseMonkey.)
If you could provide a sample HTML snippet which reproduces this animation problem it would be a lot easier for us to help you. In the script I have pasted below, I can click it all day, as fast or slow as I like, and it never fails to animate for me.
For the first question: I know you said you'd found a workaround, but the following works for me (even on IE6) so I thought I'd post it, since it may be different from what you were thinking. (Note that setting CSS "opacity" property through jQuery.css() works on IE, whereas IE does not support the "opacity" property directly in CSS.)
<html>
<head>
<style>
body { background-color: #08f; }
#test { background-color: white; width: 100px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
var myOpacity = 0.125;
$(function(){
$('#test').css('opacity', myOpacity);
$('a').click(function(){
myOpacity = 1.0 - myOpacity;
$('#test').animate({ opacity: myOpacity });
return false;
});
});
</script>
</head>
<body>
<p>Click me</p>
<div id="test">Test</div>
</body></html>
Dont forget the color plugin.
See here
When the color fails to animate to blue you could try to use the callback function to log a message to the console. You can then check that the event actually fired and completed. If it does then you could potentially use two animates. The first one to animate to a halfway house color then the use the callback to animate to white (so you get two bites of the cherry, if the outer fails but completes the callback has a second go)
It would be good if you could try to recreate the issue or give a url of the issue itself.
e.g
$("#" + post.Id).css("background-color", "lightblue")
.animate({ backgroundColor: "#C0D9D9" }, 15000, function(){
$(this).animate({ backgroundColor: "#ffffff" }, 15000)
});
You could always use something like this, avoiding the JQuery animate method entirely.
setTimeout(function() { UpdateBackgroundColor(); }, 10);
UpdateBackgroundColor() {
// Get the element.
// Check it's current background color.
// Move it one step closer to desired goal.
if (!done) {
setTimeout(UpdateBackgroundColor, 10);
}
}
Also, you may be able to remove the "white" coding by reading the background color from the appropriate item (which may involve walking up the tree).
It is possible to have jQuery change the Opacity CSS property of an item (as mentioned in another answer), but there's two reasons why that wouldn't work for your scenario. Firstly, making something "100% opaque" is fully visible. If the item didn't have any other modifications to its opacity, the default opacity is 100%, and there would be no change, so I'm guessing you meant fading to 0% opacity, which would be disappearing. This would get rid of the light blue background, but also the text on top of it, which I don't think was your intent.
A potentially easy fix for your situation is to change the color word "white" to "transparent" in your original code listing. The color plugin may not recognize that color word (haven't checked documentation on that yet), but setting the background color to "transparent" will let whatever color behind it (page background, if nothing else) shine through, and will self-update if you change your page background.
I'll answer your first question.
You can animate opacity like this:
.animate({opacity: 1.0}, 3000)
I think you can try using fadeOut/fadeIn too..
What about:
$("#" + post.Id).fadeIn( "slow" );
You could possibly have two divs that occupy the same space (using position: absolute; and position: relative; setting the z-index on one higher to make sure one is above and the other is below. the top one would have a transparent background and the one below would have a background color. then just fadeout the one below.
As for the second question:
If you think the default animation classes from JQuery are not properly working you could try Bernie's Better Animation Class. I have some good experiences with that library.
Animate only works for numbers. See the jquery docs. You can do opacity but you can't do background color. You can use the color plug in. Background-color uses strings like 'red', 'blue', '#493054' etc... which are not numbers.