I have a page with a lot of GIFs.
<img src="gif/1303552574110.1.gif" alt="" >
<img src="gif/1302919192204.gif" alt="" >
<img src="gif/1303642234740.gif" alt="" >
<img src="gif/1303822879528.gif" alt="" >
<img src="gif/1303825584512.gif" alt="" >
What I'm looking for
1 On page load => Animations for all gifs are stopped
2 On mouseover => Animations starts for that one gif
3 On mouseout => Animation stops again for that gif
I suppose this can be done in Jquery but I don't know how.
No, you can't control the animation of the images.
You would need two versions of each image, one that is animated, and one that's not. 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('.gif', '_anim.gif'));
}, function(){
$(this).attr('src', src);
});
});
});
Update:
Time goes by, and possibilities change. As kritzikatzi pointed out, having two versions of the image is not the only option, you can apparently use a canvas element to create a copy of the first frame of the animation. Note that this doesn't work in all browsers, IE 8 for example doesn't support the canvas element.
I realise this answer is late, but I found a rather simple, elegant, and effective solution to this problem and felt it necessary to post it here.
However one thing I feel I need to make clear is that this doesn't start gif animation on mouseover, pause it on mouseout, and continue it when you mouseover it again. That, unfortunately, is impossible to do with gifs. (It is possible to do with a string of images displayed one after another to look like a gif, but taking apart every frame of your gifs and copying all those urls into a script would be time consuming)
What my solution does is make an image looks like it starts moving on mouseover. You make the first frame of your gif an image and put that image on the webpage then replace the image with the gif on mouseover and it looks like it starts moving. It resets on mouseout.
Just insert this script in the head section of your HTML:
$(document).ready(function()
{
$("#imgAnimate").hover(
function()
{
$(this).attr("src", "GIF URL HERE");
},
function()
{
$(this).attr("src", "STATIC IMAGE URL HERE");
});
});
And put this code in the img tag of the image you want to animate.
id="imgAnimate"
This will load the gif on mouseover, so it will seem like your image starts moving. (This is better than loading the gif onload because then the transition from static image to gif is choppy because the gif will start on a random frame)
for more than one image just recreate the script create a function:
<script type="text/javascript">
var staticGifSuffix = "-static.gif";
var gifSuffix = ".gif";
$(document).ready(function() {
$(".img-animate").each(function () {
$(this).hover(
function()
{
var originalSrc = $(this).attr("src");
$(this).attr("src", originalSrc.replace(staticGifSuffix, gifSuffix));
},
function()
{
var originalSrc = $(this).attr("src");
$(this).attr("src", originalSrc.replace(gifSuffix, staticGifSuffix));
}
);
});
});
</script>
</head>
<body>
<img class="img-animate" src="example-static.gif" >
<img class="img-animate" src="example-static.gif" >
<img class="img-animate" src="example-static.gif" >
<img class="img-animate" src="example-static.gif" >
<img class="img-animate" src="example-static.gif" >
</body>
That code block is a functioning web page (based on the information you have given me) that will display the static images and on hover, load and display the gif's. All you have to do is insert the url's for the static images.
I think the jQuery plugin freezeframe.js might come in handy for you. freezeframe.js is a jQuery Plugin To Automatically Pause GIFs And Restart Animating On Mouse Hover.
I guess you can easily adapt it to make it work on page load instead.
The best option is probably to have a still image which you replace the gif with when you want to stop it.
<img src="gif/1303552574110.1.gif" alt="" class="anim" >
<img src="gif/1302919192204.gif" alt="" class="anim" >
<img src="gif/1303642234740.gif" alt="" class="anim" >
<img src="gif/1303822879528.gif" alt="" class="anim" >
<img src="gif/1303825584512.gif" alt="" class="anim" >
$(window).load(function() {
$(".anim").src("stillimage.gif");
});
$(".anim").mouseover(function {
$(this).src("animatedimage.gif");
});
$(".anim").mouseout(function {
$(this).src("stillimage.gif");
});
You probably want to have two arrays containing paths to the still and animated gifs which you can assign to each image.
found a working solution here:
https://codepen.io/hoanghals/pen/dZrWLZ
JS here:
var gifElements = document.querySelectorAll('img.gif');
for(var e in gifElements) {
var element = gifElements[e];
if(element.nodeName == 'IMG') {
var supergif = new SuperGif({
gif: element,
progressbar_height: 0,
auto_play: false,
});
var controlElement = document.createElement("div");
controlElement.className = "gifcontrol loading g"+e;
supergif.load((function(controlElement) {
controlElement.className = "gifcontrol paused";
var playing = false;
controlElement.addEventListener("click", function(){
if(playing) {
this.pause();
playing = false;
controlElement.className = "gifcontrol paused";
} else {
this.play();
playing = true;
controlElement.className = "gifcontrol playing";
}
}.bind(this, controlElement));
}.bind(supergif))(controlElement));
var canvas = supergif.get_canvas();
controlElement.style.width = canvas.width+"px";
controlElement.style.height = canvas.height+"px";
controlElement.style.left = canvas.offsetLeft+"px";
var containerElement = canvas.parentNode;
containerElement.appendChild(controlElement);
}
}
Pure JS implementation https://jsfiddle.net/clayrabbit/k2ow48cy/
(based on canvas solution from https://codepen.io/hoanghals/pen/dZrWLZ)
[].forEach.call(document.querySelectorAll('.myimg'), function(elem) {
var img = new Image();
img.onload = function(event) {
elem.previousElementSibling.getContext('2d').drawImage(img, 0, 0);
};
img.src = elem.getAttribute('data-src');
elem.onmouseover = function(event) {
event.target.src = event.target.getAttribute('data-src');
};
elem.onmouseout = function(event) {
event.target.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
};
});
.mydiv{
width: 320px;
height: 240px;
position: relative;
}
.mycanvas, .myimg {
width: 100%;
height: 100%;
position: absolute;
}
<div class="mydiv">
<canvas class="mycanvas" width=320 height=240></canvas>
<img class="myimg" data-src="https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif">
</div>
You can solve this by having a long stripe that you show in steps, like a filmstrip. Then you can stop the film on any frame.
Example below (fiddle available at http://jsfiddle.net/HPXq4/9/):
the markup:
<div class="thumbnail-wrapper">
<img src="blah.jpg">
</div>
the css:
.thumbnail-wrapper{
width:190px;
height:100px;
overflow:hidden;
position:absolute;
}
.thumbnail-wrapper img{
position:relative;
top:0;
}
the js:
var gifTimer;
var currentGifId=null;
var step = 100; //height of a thumbnail
$('.thumbnail-wrapper img').hover(
function(){
currentGifId = $(this)
gifTimer = setInterval(playGif,500);
},
function(){
clearInterval(gifTimer);
currentGifId=null;
}
);
var playGif = function(){
var top = parseInt(currentGifId.css('top'))-step;
var max = currentGifId.height();
console.log(top,max)
if(max+top<=0){
console.log('reset')
top=0;
}
currentGifId.css('top',top);
}
obviously, this can be optimized much further, but I simplified this example for readability
A more elegant version of Mark Kramer's would be to do the following:
function animateImg(id, gifSrc){
var $el = $(id),
staticSrc = $el.attr('src');
$el.hover(
function(){
$(this).attr("src", gifSrc);
},
function(){
$(this).attr("src", staticSrc);
});
}
$(document).ready(function(){
animateImg('#id1', 'gif/gif1.gif');
animateImg('#id2', 'gif/gif2.gif');
});
Or even better would be to use data attributes:
$(document).ready(function(){
$('.animated-img').each(function(){
var $el = $(this),
staticSrc = $el.attr('src'),
gifSrc = $el.data('gifSrc');
$el.hover(
function(){
$(this).attr("src", gifSrc);
},
function(){
$(this).attr("src", staticSrc);
});
});
});
And the img el would look something like:
<img class="animated-img" src=".../img.jpg" data-gif-src=".../gif.gif" />
Note: This code is untested but should work fine.
For restarting the animation of a gif image, you can use the code:
$('#img_gif').attr('src','file.gif?' + Math.random());
Related answer, you can specify the number of playbacks on a gif. The below gif has 3 playbacks associated with it (10 second timer, 30 second playback total). After 30 seconds have passed since page load, it stops at "0:01".
Refresh the page to restart all 3 playbacks
You have to modify the gif itself. An easy tool is found here for modifying GIF playbacks https://ezgif.com/loop-count.
To see an example of a single-loop playback gif in action on a landing page, checkout this site using a single playback gif https://git-lfs.github.com/
This answer builds on that of Sourabh, who pointed out an HTML/CSS/JavaScript combo at https://codepen.io/hoanghals/pen/dZrWLZ that did the job. I tried this, and made a complete web page including the CSS and JavaScript, which I tried on my site. As CodePens have a habit of disappearing, I decided to show it here. I'm also showing a simplified stripped-to-essentials version, to demonstrate the minimum that one needs to do.
I must also note one thing. The code at the above link, whose JavaScript Sourabh copies, refers to a JavaScript constructor SuperGif() . I don't think Sourabh explained that, and neither does the CodePen. An easy search showed that it's defined in buzzfeed /
libgif-js , which can be downloaded from https://github.com/buzzfeed/libgif-js#readme . Look for the control that the red arrow below is pointing at, then click on the green "Code" button. (N.B. You won't see the red arrow: that's me showing you where to look.)
A menu will pop up offering various options including to download a zip file. Download it, and extract it into your HTML directory or a subdirectory thereof.
Next, I'm going to show the two pages that I made. The first is derived from the CodePen. The second is stripped to its essentials, and shows the minimum you need in order to use SuperGif.
So here's the complete HTML, CSS, and JavaScript for the first page. In the head of the HTML is a link to libgif.js , which is the file you need from the zip file. Then, the body of the HTML starts with some text about cat pictures, and follows it with a link to an animated cat GIF at https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif .
It then continues with some CSS. The CodePen uses SCSS, which for anyone who doesn't know, has to be preprocessed into CSS. I've done that, so what's in the code below is genuine CSS.
Finally, there's the JavaScript.
<html>
<head>
<script src="libgif-js-master/libgif.js"></script>
</head>
<body>
<div style="width: 600px; margin: auto; text-align: center; font-family: arial">
<p>
And so, the unwritten law of the internet, that any
experiment involving video/images must involve cats in
one way or another, reared its head again. When would
the internet's fascination with cats come to an end?
Never. The answer is "Never".
</p>
<img src='https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif' class='gif' />
</div>
<style>
img.gif {
visibility: hidden;
}
.jsgif {
position: relative;
}
.gifcontrol {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
cursor: pointer;
transition: background 0.25s ease-in-out;
z-index: 100;
}
.gifcontrol:after {
transition: background 0.25s ease-in-out;
position: absolute;
content: "";
display: block;
left: calc(50% - 25px);
top: calc(50% - 25px);
}
.gifcontrol.loading {
background: rgba(255, 255, 255, 0.75);
}
.gifcontrol.loading:after {
background: #FF9900;
width: 50px;
height: 50px;
border-radius: 50px;
}
.gifcontrol.playing {
/* Only show the 'stop' button on hover */
}
.gifcontrol.playing:after {
opacity: 0;
transition: opacity 0.25s ease-in-out;
border-left: 20px solid #FF9900;
border-right: 20px solid #FF9900;
width: 50px;
height: 50px;
box-sizing: border-box;
}
.gifcontrol.playing:hover:after {
opacity: 1;
}
.gifcontrol.paused {
background: rgba(255, 255, 255, 0.5);
}
.gifcontrol.paused:after {
width: 0;
height: 0;
border-style: solid;
border-width: 25px 0 25px 50px;
border-color: transparent transparent transparent #ff9900;
}
</style>
<script>
var gifElements = document.querySelectorAll('img.gif');
for(var e in gifElements) {
var element = gifElements[e];
if(element.nodeName == 'IMG') {
var supergif = new SuperGif({
gif: element,
progressbar_height: 0,
auto_play: false,
});
var controlElement = document.createElement("div");
controlElement.className = "gifcontrol loading g"+e;
supergif.load((function(controlElement) {
controlElement.className = "gifcontrol paused";
var playing = false;
controlElement.addEventListener("click", function(){
if(playing) {
this.pause();
playing = false;
controlElement.className = "gifcontrol paused";
} else {
this.play();
playing = true;
controlElement.className = "gifcontrol playing";
}
}.bind(this, controlElement));
}.bind(supergif))(controlElement));
var canvas = supergif.get_canvas();
controlElement.style.width = canvas.width+"px";
controlElement.style.height = canvas.height+"px";
controlElement.style.left = canvas.offsetLeft+"px";
var containerElement = canvas.parentNode;
containerElement.appendChild(controlElement);
}
}
</script>
</body>
</html>
When I put the page on my website and displayed it, the top looked like this:
And when I pressed the pink button, the page changed to this, and the GIF started animating. (The cat laps water falling from a tap.)
To end, here's the second, simple, page. Unlike the first, this doesn't have a fancy Play/Pause control that changes shape: it just has two buttons. The only thing the code does that isn't essential is to disable whichever button is not relevant, and to insert some space between the buttons.
<html>
<head>
<script src="libgif-js-master/libgif.js"></script>
</head>
<body>
<button type="button" onclick="play()"
id="play_button"
style="margin-right:9px;"
>
Play
</button>
<button type="button" onclick="pause()"
id="pause_button"
>
Pause
</button>
<img src="https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif"
id="gif"
/>
<script>
var gif_element = document.getElementById( "gif" );
var supergif = new SuperGif( {
gif: gif_element,
progressbar_height: 0,
auto_play: false
} );
supergif.load();
function play()
{
var play_button = document.getElementById( "play_button" );
play_button.disabled = true;
var pause_button = document.getElementById( "pause_button" );
pause_button.disabled = false;
supergif.play();
}
function pause()
{
var play_button = document.getElementById( "play_button" );
play_button.disabled = false;
var pause_button = document.getElementById( "pause_button" );
pause_button.disabled = true;
supergif.pause();
}
pause_button.disabled = true;
</script>
</body>
</html>
This, plus the example.html file in libgif-js, should be enough to get anyone started.
There is only one way from what I am aware.
Have 2 images, first a jpeg with first frame(or whatever you want) of the gif and the actual gif.
Load the page with the jpeg in place and on mouse over replace the jpeg with the gif. You can preload the gifs if you want or if they are of big size show a loading while the gif is loading and then replace the jpeg with it.
If you whant it to bi linear as in have the gif play on mouse over, stop it on mouse out and then resume play from the frame you stopped, then this cannot be done with javascript+gif combo.
Adding a suffix like this:
$('#img_gif').attr('src','file.gif?' + Math.random());
the browser is compelled to download a new image every time the user accesses the page. Moreover the client cache may be quickly filled.
Here follows the alternative solution I tested on Chrome 49 and Firefox 45.
In the css stylesheet set the display property as 'none', like this:
#img_gif{
display:'none';
}
Outside the '$(document).ready' statement insert:
$(window).load(function(){ $('#img_gif').show(); });
Every time the user accesses the page, the animation will be started after the complete load of all the elements. This is the only way I found to sincronize gif and html5 animations.
Please note that:
The gif animation will not restart after refreshing the page (like pressing "F5").
The "$(document).ready" statement doesn't produce the same effect of "$(window).load".
The property "visibility" doesn't produce the same effect of "display".
css filter can stop gif from playing in chrome
just add
filter: blur(0.001px);
to your img tag then gif freezed to load via chrome performance concern :)
so far (with the help of this comm :)) I created a full viewport background, thats able to switch on click.
Since I'm a beginner I have two questions:
1) Is the code "good", or did I wrote it to complicated?
and the Mainquestion:
How can I put a fade effect into my code? Now it's kinda ugly, because the images are loading slow (stuttering). I imagine something like this:
Image--Click--Fading black--Fading in new Image--Click--Fading black---Fading in new Image--..
Here is the code I wrote:
HTML:
<div class="t1">
</div>
CSS:
.t1 {
background: url(pics/homescreen.JPG) no-repeat center center fixed ;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width: 100%;
height: 100%;
}
jQuery:
$(function () {
var y = 1;
$('.t1').click(function () {
var x = ['url(pics/screen1.jpg) no-repeat center center fixed',
'url(pics/screen2.jpg) no-repeat center center fixed',
'url(pics/schild.jpg) no-repeat center center fixed'
]
$('.t1').css('background', x[y]);
$('.t1').css('background-size', 'cover');
if (y == 2) {
y = 0;
} else {
y = y + 1;
}
});
})
Demo: http://jsfiddle.net/bSAm2/
This doesn't include preloading, but the effect is quite nice.
If you are interested in a preloader, you probably want to preload images one at a time, when they are needed: loading all images upfront or worse in the head of your document, will likely slow down page loading beyond what's an acceptable UX.
Also, transition won't work on older browsers (see here)
To animate CSS properties, you can use http://api.jquery.com/animate/
In particular, you can fade out the current image by animating its opacity (to 0), then, when this animation is completed change the image source (while it is not visible) and start the fade-in animation.
For best appearance, you can preload images "Just in Time", for example you can preload the next image to show, so there won't be any latency
EDIT
This example works, and uses closure so that you can have multiple images rotating independently:
$(function () {
var images = ['url(http://lorempixel.com/output/people-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/nature-q-c-640-480-8.jpg) no-repeat center center fixed',
'url(http://lorempixel.com/output/fashion-q-c-640-480-9.jpg) no-repeat center center fixed'
];
function bindSwitcher (elem) {
var imageIndex = 0;
return function switchImage () {
elem.fadeOut(function (){
elem.css('background', images[imageIndex]);
if (imageIndex == images.length - 1) {
imageIndex = 0;
} else {
imageIndex += 1;
}
elem.css('background-size', 'cover');
elem.fadeIn();
});
};
}
var imageSwitcher = bindSwitcher($('#t1'));
$('#t1').click(imageSwitcher);
$('#t2').click(bindSwitcher($('#t2')));
});
And the HTML, with a little change to show the difference:
<div id="t1" class="t1" style="position: absolute; left:0%">
</div>
<div id="t2" class="t1" style="position: absolute; left:50%">
</div>
Demo: http://jsfiddle.net/abhitalks/FNUx8/8/
Is the code "good", or did I wrote it to complicated?
A couple of things which you could do is:
Take your image array outside of click handler. You woudn't want to create that array every time a click happens.
Reduce the code to cycle the array by using a modulus.
Refer to the element using this.
Use an id instead of class to target the element directly if that is unique.
So, effectively your code reduces to:
var x = ['url(...1.jpg) no-repeat center center fixed',
'url(...2.jpg) no-repeat center center fixed',
'url(..3.jpg) no-repeat center center fixed'
];
var index = 0;
$('#t1').click(function () {
index = (index + 1) % x.length;
$(this).css('background', x[index]);
});
How can I put a fade effect into my code? Now it's kinda ugly, because
the images are loading slow (stuttering)
(1.) You can put a fade effect using CSS3 transition:
#t1 {
...
transition: 1s;
}
(2.) There is stuttering because the images are loaded at runtime. You could avoid that by pre-loading images:
One way could be like this:
var d = []; // create an array for holding dummy elements
for (var i = 0; i < x.length; i++) {
d[i] = $("<img>"); // create an img and add to the array
d[i].attr('src', x[i]).hide(); // add src to img and hide it
$("body").append(d[i]); // add the img to body to start load
}
Ideally wrap this code in the head so that this is done by the time DOM is ready. Put rest of your code either wrapped in body at the end or in .ready.
Edit:
Changed the preloading code to use img. Updated the fiddle.
The code is not complicated, in time you'll learn to write cleaner (good) code. Here is my suggestions:
1. move the x definition outside the click event, put it right after y and y should be 0 initially;
2. if(y == 2) is too static, beter take the length of the array if(y == x.length);
3. remove background-size from script, it's set in css;
4. For fade effect you can do something like this:
$('.t1').fadeOut(300, function() {
$(this).css('background', x[y]).fadeIn(300);
});
I haven't tested it, but should do the job.
What I'm looking for is a way to make my HTML header tag change background images every few seconds. Any solutions are welcome, as long as it is not to complex.
I have this code right now as well as linking to JQuery:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
$(function() {
var header = $(‘.mainHeader’);
var backgrounds = new Array(
‘url(img/rainbow.jpg)’,
‘url(img/chickens_on_grass.jpg)’
‘url(img/cattle_on_pasture.jpg)’
‘url(img/csa_bundle.jpg)’
);
var current = 0;
function nextBackground() {
header.css(‘background’,backgrounds[current = ++current % backgrounds.length]);
setTimeout(nextBackground, 10000);
}
setTimeout(nextBackground, 10000);
header.css(‘background’, backgrounds[0]);
});
My HTML header:
<header class="mainHeader"></header>
And CSS:
.mainHeader {
background: no-repeat center bottom scroll;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
min-height: 150px;
padding-top: 2%;
font-size: 100%;
}
Right now I have now background image at all.
Made a few amendments to your code
DEMO: http://jsfiddle.net/p77KW/
var header = $('body');
var backgrounds = new Array(
'url(http://placekitten.com/100)'
, 'url(http://placekitten.com/200)'
, 'url(http://placekitten.com/300)'
, 'url(http://placekitten.com/400)'
);
var current = 0;
function nextBackground() {
current++;
current = current % backgrounds.length;
header.css('background-image', backgrounds[current]);
}
setInterval(nextBackground, 1000);
header.css('background-image', backgrounds[0]);
Biggest changes (as noted in others comments) is that you have to use apostrophe**'**s, not those funky open and close single-quotes and that your array wasn't correct.
With these corrections out of the way I simplified a few things:
Increment current then take modulus (I know this is basically what you did but how much easier is that to debug ;))
Target background-image directly
Used setInterval() instead of a double call to setTimeout
You could acheive this same technique with HTML/CSS Only by 1. placing images within an "img" tag in your HTML surrounded by a "div wrapper" and setting it to position:relative and div wrapper img's to position:absolute. For full-width/full-height you can use percentages or potentially "background-size:cover" (haven't checked) and then call a CSS animation to change the images dynamically.
Or 2. you can add multiple images to a background in your CSS separated by commas, apply background-size:cover and again use CSS animations to change the background.
Here's an example and also Mozilla CSS3 Animation Documentation
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function(){
var header = $('body');
var backgrounds = new Array(
'url(http://placekitten.com/100)'
, 'url(http://placekitten.com/200)'
, 'url(http://placekitten.com/300)'
, 'url(http://placekitten.com/400)'
);
var current = 0;
function nextBackground() {
current++;
current = current % backgrounds.length;
header.css('background-image', backgrounds[current]);
}
setInterval(nextBackground, 1000);
header.css('background-image', backgrounds[0]);
});
</script>
</head>
<body>
<header></header>
</body>
</html>
You can't delimit JavaScript strings with ‘ characters. You must use " or '.
It must be late but may help to another one.
For this goal in some situations I prefer to use a jquery plugin named tcycle which have only a few lines of code and supports just fade transition, but it works smoothly even with large images.
Setting up a slideshow with tcycle is easy and even could be done with declarative markup such as
<div class="tcycle">
<img src="p1.jpg">
<img src="p2.jpg">
</div>
The trick could be donde using css z-index:-1 for container div and setting width and height to 100%
Homepage for downloading and check for other examples is Malsup jQuery plugins
I'm pretty much a newbie on the HTML/CSS realm and have been facing a jquery challenge ever since I started building my first website. I want to create an jquery-powered image gallery, using thumbnails. The tutorial I followed for that matter was Ivan Lazarevic's (http://workshop.rs/2010/07/create-image-gallery-in-4-lines-of-jquery/). I also made use of Stackoverflow's forum through this thread: http://goo.gl/ILzsx.
The code he provides replaces the large image on display with the larger version of the thumbnail that's been clicked. This seems to work pretty smoothly but just for pictures that have the same orientation. The following code appears on two different files, thus establishing a difference between the horizontal and vertical images:
<div id="mainImage">
<img id="largeImage" src="Images/Projects/UOW/UOWII_large.jpg"/>
</div>
AND:
<div id="mainImageVERTICAL">
<img id="largeImageVERTICAL" src="Images/Projects/UOW/UOWI_large.jpg" />
</div>
I have created different CSS rules for both the largeImage and largeImageVERTICAL parameters, depending on whether the image has a portrait or landscape orientation.
#largeImage {
position: fixed;
height: 83%;
width:auto;
top: 15%;
left: 5%;
}
AND:
#largeImageVERTICAL {
position: fixed;
height: 83%;
width:auto;
top: 15%;
left: 36.36%;
}
These two rules just place the images at different points of the screen. However, what I would like to know is how to modify my code so that I can create a page with both portrait and landscape-oriented images applying the CSS rule that belongs to each. Up to now, what I have is what I got from Lazarevic's approach, which is:
$('#thumbs img').click(function(){
$('#largeImage').attr('src',$(this).attr('src').replace('thumb','large'));
});
This code just replaces the thumbnails with the bigger pictures. As stated, I want to be able to apply the right rule to the right image and I'm assuming this has to be be made through some JS coding, which I know pretty much nothing about.
I would appreciate some help so that I can keep on with this project. Any ideas how to make this work? Maybe a JS function that tells the machine to use one or another CSS rule depending on which image is clicked upon? I'm really stuck here...
Thanks in advance!
There are a couple of ways you could do this.
Use a HTML5 data-* attribute to specify which of the <img> elements should be updated. So:
<div id="thumbs">
<img src="img.jpg" data-large="largeImage"/>
<img src="anotherimg.jpg" data-large="largeImageVERTICAL"/>
</div>
Then:
$('#thumbs img').click(function(e) {
var imageId = $(this).attr('data-large'),
newSrc = this.src.replace('thumb', 'large');
$('#' + imageId).attr('src', newSrc);
});
Or, use the dimensions of the thumbnail to determine whether it's portrait or landscape:
$('#thumbs img').click(function(e) {
var $this = $(this),
height = $this.height(),
width = $this.width(),
newSrc = this.src.replace('thumb', 'large');
var imageId = (height > width) ? 'largeImageVERTICAL' : 'largeImage';
$('#' + imageId).attr('src', newSrc);
});
In either case, you'll probably need to hide the other, unused <img> element so that you don't have the previously selected image for the other orientation displayed.
One way to achieve this would be:
var alternateImageId = (imageId === 'largeImage') ? 'largeImageVERTICAL' : 'largeImage';
$('#' + alternateImageId).hide();
Add the above two lines to the click event handler above, and call .show() after calling .attr('src', ...).
Use class not id.
#largeImage{
top: 15%;
width:auto;
height: 83%;
position: fixed;
}
.portrait{
left: 36.36%;
}
.landscape{
left: 5%;
}
js
$('#largeImage').on('load', function () {
var that = $(this);
if (that.width() < that.height()) {
that.addClass('portrait');
} else {
that.addClass('landscape');
}
});
$('#thumbs').on('click', 'img', function () {
$('#largeImage').attr('src',$(this).attr('src').replace('thumb','large'));
});