How to make an image x% bigger in JavaScript (with jQuery) - javascript

I thought this ought to be a straightforward thing to do, but I don't see a clear way to do it.
I would like to make it so that when a user hovers the mouse over an image, the image becomes 10% bigger and then returns to its original size when the user moves the mouse away.
I think that I will want to use the jQuery hover function, but I don't know what functions to pass into hover.
$('.resizableImage').hover(makeBigger, returnToOriginalSize);

jQuery lets you use += and %. So those two together will do what you want.
$('.resizableImage').hover(makeBigger, returnToOriginalSize);
function makeBigger() {
$(this).css({height: '+=10%', width: '+=10%'});
}
function returnToOriginalSize() {
$(this).css({height: "", width: ""});
}
DEMO: http://jsfiddle.net/rZaAE/

You could do it with CSS3 tranform property, for example
$('.resizableImage').hover(function(){
$(this).css("transform", "scale(1.1, 1.1)");
}, function(){
$(this).css("transform", "none");
});

Without CSS3 you could simply get original size using .width() and .height() methods, store it in data attribute(s) and resize. On mouseout just restore the original values.
var hoverRatio = 1.1;
$('.resizableImage').hover(function() {
$(this).data('width', $(this).width());
$(this).data('height', $(this).height());
$(this).css({
width: $(this).width() * hoverRatio,
height: $(this).height() * hoverRatio
});
}, function() {
$(this).css({
width: $(this).data('width'),
height: $(this).data('height')
});
});​
See the DEMO.

You should use stop on the animation also so it doesn't get interrupted when the user moves out before the animation has finsihed
html:
<img src="http://placehold.it/350x150" class="resizableImage" width="350" height="150" />​
js:
$('.resizableImage').mouseenter(function() {
$(this).stop().animate({ width: "+=10%", height: "+=10%" });
});
$('.resizableImage').mouseleave(function() {
var x = $(this).attr('width'),
y = $(this).attr('height');
$(this).stop().animate({ width: x, height: y });
});
​
Here is a fiddle:
http://jsfiddle.net/tWdAK/1/

Couldn't you just do this with css:
CSS
.resizable_img {
position: relative; // needed for z-index to work
width: 100%;
height: auto; // will resize image proportionally
}
.resizable_img:hover {
width: 120%;
z-index: 1; // place image on top
}
.img_container {
width: 25%;
position: relative;
overflow: visible; // stops images being shifted
float:left;
}
HTML
<div class="contents">
<div class="img_container">
<img class="resizable_img" src="img.jpg">
</div>
</div>
Fiddle here

If you're not using inline styling, you can omit saving the old values in data and use style attr instead.
$('.element').hover(function() {
var el = $(this);
el.attr('style','width:'+el.width() * 1.1 + 'px;height:'+el.height() * 1.1 + 'px;');
}, function() {
$(this).removeAttr('style');
});​

Related

Why div have different animation in these two cases

I have two divs with animation, both are doing the same but with different animation. I have
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle' });
});
});
Whole code in in jsfiddle http://jsfiddle.net/xLHb8/192/
Can anyone please explain to me why first div is animating right to left, left to right and second div is animating always to top left corner.
How can I make second div animate same as first div?
First, the relevant details in your code should be included in your question (in addition to providing the fiddle). But so you have the following CSS:
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second img {
max-width:100%;
max-height:100%;
}
.second {
width: 200px;
}
With the following HTML:
<button id="show_hide_button">click me</button>
<div id="some_box"></div>
<div class="second">
<img src="http://piq.codeus.net/static/media/userpics/piq_66223.png" />;
</div>
Note that you're setting the img to have a maximum width and height of its parent container. So because you're toggling the width of the parent, as parent collapses, the image is scaling down. Further, since you don't have a height setting on the img, its height is going to animate along with the animated width. This creates the effect of the image animating to the top left corner.
Without further details, it's hard to say how to fix your code to achieve the desired effect.
Update
If you want the width only to collapse, you can set a pixel height on your image so that it doesn't scale in proportion to its width:
.second img {
max-width: 100%;
height: 200px;
}
You can also put both animations in a single click event handler, like so:
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle'});
$('.second').animate({ width: 'toggle' });
});
});
Forked your fiddle: http://jsfiddle.net/u1sdd8j5/1/
Update 2
From the comments, it seems like you want the image to collapse to the left, without losing the aspect ratio. We need to get a little creative to pull that off, especially if you're looking for a solution involving jQuery.animate(). The image actually needs to move downwards as it is scaled down. We can pull that off by animating the <img> itself, rather than its container, and adjusting its top margin at the same time animate its width.
Revised CSS (making the containers the same size for consistency):
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second {
width: 25%;
height: 200px;
}
.second img {
max-width: 100%;
max-height: 100%;
}
Revised JS:
$(document).ready( function(){
$('#show_hide_button').click( function() {
$('#some_box').animate({ width: 'toggle' });
var $secondImg = $('.second img'),
secondImgMargin = $secondImg.is(':visible') ? '50%' : 0;
$('.second img').animate({
width: 'toggle',
marginTop: secondImgMargin
});
});
});
Note that we need to first determine whether or not the <img> is visible. If it is, then we want to animate the top margin to 50%. If it's not, then switch the top margin back to 0.
Here's a new forked fiddle: http://jsfiddle.net/xwanm9ze/1/
Final Note
All of this might be easier to achieve with CSS3 transitions. You would want to set up a class that toggles the animation. And you can specify the transform-origin which, in this case, would be 'left center'.
The problem is, that you added a relative width and height attribute to the inside the second div and did not give a height and width attribute to the second div. This way, the image controls the height and width of the second div, since it has no height and width attribute.
In your case, a solution would be to give the second div a fixed width and height
Also, for the JQuery, you only need one $(document).ready function
$(document).ready(function () {
$('#show_hide_button').click(function () {
$('#some_box').animate({
width: 'toggle'
});
$('.second').animate({
width: 'toggle'
});
});
});
#some_box {
background: #fc0;
width: 25%;
height: 200px;
}
.second img {
width:100%;
height:100%;
}
.second {
width:200px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="show_hide_button">click me</button>
<div id="some_box"></div>
<div class="second">
<img src="http://piq.codeus.net/static/media/userpics/piq_66223.png" />
</div>

Keep scroll to top button in the same height?

I've a problem with my button. What I want is when the windows size on the height is changed, how can force the button to stay in the same height? I don't want it to follow or be pressed down as the height is changed...
http://jsfiddle.net/ccq9cs9L/3/
HTML
<a href="#" class="scrollToTop hidden-phone">
<span class="icon icon-arrow-up-white"></span>
</a>
<div class="myDiv">
<div class="myContent">
a lot of text
</div>
</div>
CSS
a.scrollToTop {
content: "";
z-index: 1000;
width: 60px;
height: 45px;
background: #78b209;
position: fixed;
top: 35.5%;
right: 0;
display: none;
}
JavaScript
$(document).scroll(function(e) { // This is scrollToTop button
e.preventDefault();
if ($(this).scrollTop() > 100) {
$('.scrollToTop').fadeIn();
} else {
$('.scrollToTop').fadeOut();
}
});
$('.scrollToTop').click(function () { // Scroll to top with ease
$('html, body').animate({ scrollTop: 0 }, 1000, 'easeOutExpo');
return false;
});
If I understand you correctly, your question is actually about CSS. Try changing top: 35.5%; to a static amount, for example top: 100px;
If you want the pixel amount to be based on the viewport height, you can get that with
$(window).height();
So to always show the button at position N % from the top and keep it there despite viewport resizing you could do this:
function positionButton() {
var percFromTop = 35,
newHeight = $(window).height() / 100 * percFromTop;
$(".scrollToTop").css("top", newHeight+"px");
}
$(document).ready(function() {
positionButton();
};
See it in a fiddle here: http://jsfiddle.net/ccq9cs9L/9/

How to user controlled overlap images in JS

I'm desperately searching for solution for my client. I have graphic - something like that:
And I want to be able to take the line with circle in the center and drag it to right or left. And it will be hiding and unhiding my two full images. It's basically two images on the same place, just with another z-index I think.
I think it's possible to do it with JavaScript, but I don't know of any functions or methods for this option.
Here is my solution:
The HTML is pretty simple, just two divs for the images and one for the drag:
<div class="img" id="img1"></div>
<div class="img" id="img2"></div>
<div id="drag"></div>
For the CSS, the important part is to absolute position all the divs and give a background image.
As for the Javascript, with a little help from jQuery, we listen for the mouse events, make some calculations and adjust the CSS of the second image:
$('#drag').on('mousedown', function(e){
var $self = $(this),
dragPos = $self.position().left + $self.width()/2,
imgWidth = $('#img1').width();
$(document).on('mouseup', function(e){
$(document).off('mouseup').off('mousemove');
});
$(document).on('mousemove', function(me){
var mx = me.pageX - e.pageX + dragPos
$self.css({ left: mx });
$('#img2').css({
width: imgWidth - mx,
left: mx,
backgroundPosition: -mx + 'px 0px',
});
});
});
From there, I believe it's pretty easy to customize it and give it a unique look.
Hope this helps!
JsFiddle Demo
Something like this alphamask plugin may do the trick, though I'm not sure how simple it would be for you to implement in the manner of your slider example.
Actually quite simple. The first step is to make it work manually. I'd set it up as follows:
<div class="wrap" id="wrap1">
<div class="img-wrap img1"></div>
<div class="img-wrap img2"></div>
<div>
With CSS as follows:
.wrap {
position: relative;
width: 300px;
height: 300px;
}
.img-wrap {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
.img1 {
z-index: 1;
background: url(bg1.png) no-repeat 0px 0px;
}
.img2 {
z-index: 2;
background: url(bg1.png) no-repeat 0px 0px;
}
Now some JavaScript (with jQuery) to set a position (you can call this when you move a slider over the top later):
function setPosition(percentage){
// get the width of the container
var w = $('#wrap1').width();
// work out the width of left panel
var w1 = Math.floor(w * percentage);
// and the right panel
var w2 = w - w1;
// set the width of the right panel
// move it right by the width of the left panel
// and move the background back by the width of the left panel
$('#wrap1 .img2').css({
width: w2,
left: w1,
backgroundPosition: -w1 + 'px 0px',
});
}
You now just have to decide how to do the dragging. You could even just do it on mouseOver. Easy!

Center an image inside of a responsive viewport without it losing its aspect ratio

What I'm trying to do is to center and resize an image that's inside of a viewport (or a parent element), without stretching it.
To make a very long story short, I want the images to keep their aspect ratio and be resized so that they cover up the viewport completely.
This is my HTML layout:
<div class="media-area" data-size="b" data-type="2">
<ul class="content-slider">
<li class="cs-item">
<img class="cs-background" src="assets/img/backgrounds/top-slider-1.jpg" alt="slider-element">
</li>
<li class="cs-item">
<img class="cs-background" src="assets/img/backgrounds/top-slider-2.jpg" alt="slider-element">
</li>
<li class="cs-item">
<img class="cs-background" src="assets/img/backgrounds/top-slider-3.jpg" alt="slider-element">
</li>
</ul>
</div>
This is my CSS:
.media-area {
width: 100%;
height: 100%; /* Standard height */
position: relative;
overflow: hidden;
}
.media-area .content-slider {
position: relative;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.media-area .content-slider .cs-item {
position: relative;
display: block;
float: left;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.media-area .content-slider .cs-item img {
display: block;
}
.media-area .content-slider .cs-background {
-webkit-transition: all .1s ease-in-out;
-moz-transition: all .1s ease-in-out;
-o-transition: all .1s ease-in-out;
transition: all .1s ease-in-out;
}
And this is my JS:
function mediazone() {
var defaults = {
elem: ".media-area",
elemWrap: ".media-area .content-slider",
elemSlide: ".media-area .content-slider .cs-item",
vh: $(window).height(),
vw: $(window).width()
};
$(defaults.elemSlide).find(".cs-background").each(function () {
var bkndImgW = $(this).width(); // Current image width
var bkndImgH = $(this).height(); // Current image height
var mediaViewPortW = $(this).parents(defaults.elem).width(); // Current media viewport width
var mediaViewPortH = $(this).parents(defaults.elem).height(); // Current media viewport height
// Used for viewport aspect ratio
var viewportratio = Math.round((mediaViewPortW / mediaViewPortH) * 100000 ) / 100000;
// Used for image aspect ratio
var imageratio = Math.round((bkndImgW / bkndImgH) * 100000 ) / 100000;
// Negative margins for when the height is larger than the width
var bkndImgPosW = ((bkndImgW - mediaViewPortW) / 2)*-1;
// Negative margins for when the width is larger than the height
var bkndImgPosH = ((bkndImgH - mediaViewPortH) / 2)*-1;
bkndImgPosW = Math.min(0, Math.max(bkndImgPosW, bkndImgPosW));
bkndImgPosH = Math.min(0, Math.max(bkndImgPosH, bkndImgPosH));
if (viewportratio > imageratio) {
$(this).removeAttr("style");
$(this).css("min-height", "100%");
$(this).css("width", "100%");
$(this).css("margin", bkndImgPosH+"px 0px");
} else if (viewportratio < imageratio){
$(this).removeAttr("style");
$(this).css("height", "100%");
$(this).css("min-width", "100%");
$(this).css("margin", "0px "+bkndImgPosW+"px");
} else if (viewportratio == imageratio) {
$(this).removeAttr("style");
}
});
}
The function is initialized here:
$(document).ready(function () {
mediazone();
});
$(window).resize(function () {
mediazone();
console.log('window resize event');
});
The problem I'm faced with right now is that when the page loads, the image is half-way out of the viewport, but when I resize the browser window, it fits perfectly.
Another problem I can't really find a way around right now is the one with the two aspect ratio's being equal ( i couldn't find a way to make the image cover the screen without having to deal with some white spaces). This makes the image flicker when the aforementioned scenario is under way.
It is important that I use the IMG tag in the DOM, otherwise maybe there would have been a way to make use of the "background-image" property in CSS.
Can anyone point out what I'm missing/ doing wrong/ I should delete?
Kind regards,
Alex
* Later Edit *
This is what I have right now:
http://jsfiddle.net/LexEckhart/Z5cjx/
After resizing, it seems to work fine and maintain the image balanced in the middle but when the page loads, the items are not positioned properly.
Since the OP specifically said he didn't want to use background-image as the image must be present in the DOM as an image, here's a jsfiddle showing a solution. I've dimmed the images using opacity to show the borders of the li's beneath it. I think the OP was overthinking the problem a bit. Anyway, hope this helps.
jsfiddle
if (viewportratio > imageratio) {
$(this).removeAttr("style");
$(this).css("width", "100%");
$(this).css("margin", bkndImgPosH+"px 0px");
} else if (viewportratio < imageratio){
$(this).removeAttr("style");
$(this).css("height", "100%");
$(this).css("margin", "0px "+bkndImgPosW+"px");
} else if (viewportratio == imageratio) {
$(this).removeAttr("style");
}
Keep in mind that images retain their aspect ratio if you only provide one attribute / property (width OR height). That's the key to the solution.
EDIT: Updated fiddle. I played around with the math logic until it worked for the images I had, replacing your images which I used before. The math logic below the first section is possibly wrong, so it'll need further testing, but this works for what I had.
You can give try for
"background-size" and "align-items" properties from css3.
set "background-size:100% 100%;";
it will cover (parent window);
For aligning contents in center you could use "align-items:center".
You can take advantage of the fact that percentage padding is always figured from the element's width. You can therefore use vertical padding with a percentage width to enforce an aspect ratio.
<div id=img></div>
// ... then in CSS:
#img {
background: url("http://placekitten.com/1280/720") no-repeat center center;
background-size: cover;
height: 0;
padding-bottom: 56.25%; /* 9:16, or 720/1280 */
}
Here is a jsfiddle to demonstrate. If you don't know the aspect ratio in advance, you can of course compute it and set the "padding-bottom" dynamically via JavaScript.
Thanks are due to the inimitable Dave Rupert for this technique.
edit ah, the <img> tag in that ending paragraph was hidden. You can employ a variation of this trick if you really need an <img> tag:
<div class=image-centerer>
<img src='http://whatever.com/your/image.png'>
</div>
// ... then in CSS:
.image-centerer {
position: relative;
height: 0;
padding-bottom: 56.25%;
}
.image-centerer img {
position: absolute;
display: block;
height: 100%;
}
Fiddle demo, and here is one demonstrating the handling of arbitrarily-proportioned images.

grow/shrink image gallery with jquery WITHOUT affecting the layout

I got an image gallery organized as an <ul>. all images are in <li> elements and when I move my mouse over one of those pictures, it should grow to give the user a visual feedback. thing is, when I just change the size of the image using animate(), the other pictures will be pushed to the side as the resized image uses more space.
therefore I went with cloning the image element, float it right over the original image and then calling animate. this comes with the problem that onMouseOut() is called as soon as the cloned images pops up. so I need a nested hover() function and this is where things got complicated.
I got two errors and I can't find out whats causing them. the first one is, that animate() won't let the cloned image grow beyond the right border of its original, the second is, that I get weird grow/shrink behavior, when moving my mouse quickly over the gallery.
html:
<ul id="gallery1" class="gallery_container">
<li class="frame">
<img src="pic1.jpg" class="picture" /></li><li class="frame">
<img src="pic2.jpg" class="picture" /></li><li class="frame">
<img src="pic3.jpg" class="picture" /></li>
</ul>
css:
.picture
{
height: 200px;
border: 0px;
margin: 0px;
padding: 0px;
}
.frame
{
display: inline-block;
position: relative;
margin: 0px;
margin-right:8px;
padding: 0px;
}
.frame a
{
padding: 0px;
margin: 0px;
}
.gallery_container
{
height: 200px;
width: 150%;
position: relative;
top: 4px;
padding: 0px;
margin: 0px;
}
and finally the code that is giving me those headaches:
$(document).ready(function()
{
var zooming = false;
var zoom = 4;
var speed_zoom = 100;
$('.gallery_container li a').hover(function(element)
{
// disable zooming to prevent unwanted behavior
if(zooming) return;
zooming = true;
$(this).after( $(this).clone(false) );
$(this).next().attr('id', 'focus_frame');
},
function(element) // when the new element pops up, onmouseout is triggered, since the focus_frame is in front of the image
{
$(this).next().hover(function(element)
{
// we need to re-position the element in the dom-tree, since it needs to grow out of a container with overflow: hidden
$('#focus_frame img').animate({'left' : zoom * -1, 'top' : zoom * -1, 'height' : 200+(zoom*2), 'width' : $('#focus_frame img').outerWidth() + (zoom*2)}, speed_zoom);
},
function(element)
{
$(this).remove();
zooming = false;
});
});
});
var $doc=$(document.body)
$doc.on({
"mouseenter" : function (e) {
$doc.find("> .gallery_clone").remove();
var $i=$(this).parent();
$i.pos = $i.offset();
$i.clone()
.addClass("gallery_clone "+$i.parent().parent().attr("class"))
.css({
top:(Math.round($i.pos.top)-3)+"px"
,left:(Math.round($i.pos.left)-3)+"px"
,width:$i.width()
}).appendTo($doc);
}
},
" ul > li > img"
).on ({
"mouseleave" : function (e) {
$(this).remove();
},"> .gallery_clone");
in css .gallery_clone is position:absolute
then i animate .gallery_clone:hover through css but you can do it in the jquery as well i guess, adding a mouseenter event on .gallery_clone
edit : i've literally copy/pasted from my script so you'll have to adapt this code to your html
nb: give css anim a go, it's worth it even if older ie will not animate; (i also made lightbox effect almost pure css for that same gallery - will publish later, not ready for plugin release just now sorry)
nb2: that part "+$i.parent().parent().attr("class") is because in the cms they can chose gallery background color so adding that class forward the background color & other gallery style to the clone (ie you should not need it)

Categories

Resources