Im making a website, and i love the functionality of this google chrome extension call Facebook Photo Zoom # https://chrome.google.com/extensions/detail/elioihkkcdgakfbahdoddophfngopipi
I think the essential idea behind the extension is when you hover over the thumbnail, it grabs the original image file and displays it in full view. If the image is too big, then it will be position on the corners or the top and bottom bars of the window. If it is not too big, it will float next to the mouse position.
The logic behind it i understand, but the actually coding seems to be a bit daunting. I guess the only parts of it i dont understand is how do you code the positions of the expanded images and make them contract/expand when you move your mouse to the left/right. Thanks
13 zoom jquery plugins in here. Choose the best for your needs:)
on mouseover you create big image with
css({position: 'absolute', left: e.pageX, top: e.pageY})
on mousemove you update the left and top in the same way.
check also:
http://api.jquery.com/event.pageY/
http://api.jquery.com/css/
http://api.jquery.com/event.pageX/
Check out this preview image tooltip which is similar to what that Chrome extension does, but you have to provide it the url to the thumbnail and full sized image. Here is the original blog post.
I modified the script to adjust the image size to fit the distance between the cursor and right browser edge. It's not perfect, but it works. Here is a demo.
/*
* Image preview script
* powered by jQuery (http://www.jquery.com)
*
* written by Alen Grakalic (http://cssglobe.com)
*
* for more info visit http://cssglobe.com/post/1695/easiest-tooltip-and-image-preview-using-jquery
*
*/
this.imagePreview = function(){
/* CONFIG */
xOffset = 10;
yOffset = 20;
// these 2 variable determine popup's distance from the cursor
// you might want to adjust to get the right result
/* END CONFIG */
$('a.preview').hover(function(e){
this.t = this.title;
this.title = '';
var p, c = (this.t != '') ? '<br/>' + this.t : '';
$('body').append('<p id="preview"><img src="' + this.href + '" alt="Image preview" />' + c + '</p>');
// load image and get size
p = $('#preview');
p
.fadeIn('fast')
.find('img').load(function(){
// get image dimensions after it has been loaded
p.data('widths', [ $(window).width(), p.find('img').width() ]);
// set image to 100% to fit in preview window
$(this).width('100%');
position(e);
});
},
function(){
this.title = this.t;
$('#preview').remove();
});
$('a.preview').mousemove(function(e){
position(e);
});
var position = function(e){
var w, prevw = $('#preview'),
w = $.data( prevw[0], 'widths' );
if ( w ) {
prevw
.css('top', e.pageY + yOffset)
.css('left', e.pageX + xOffset)
.css('max-width', (e.pageX + prevw.outerWidth() > w[0]) ? w[0] - e.pageX - xOffset : w[1] || 'auto' );
}
};
};
// starting the script on page load
$(document).ready(function(){
imagePreview();
});
See the Kabbar Image Zoomer at http://www.ideabonus.com/Kabbar/index.html
Related
I am using Magnify.js (http://mark-rolich.github.io/Magnifier.js/) in an older project and want to move away from it as it is pretty convoluted.
I attempted to build my own image zoom capabilities by refactoring + reading some articles on the subject but honestly the code wasn't going to go anywhere and thus I deleted it all due to its ineptitude at the time.
Anyway, to the issue at hand, here is what I am looking to make happen:
I hover an image with a specific css class
A canvas element appears on screen only if an image with that class is what is hovered
A zoomed in version of an area around the cursor (100px x 100px) is shown inside the canvas element
As the cursor is moved around the image the canvas updates in real time to show the zoomed in part of the new hover area as described above
When the hovering stops, the canvas item is hidden once more
Sounds simple enough but it is far from it in how I am thinking about this issue.
So, my question, in short is: Are there any simple frameworks other than Magnify.js (as linked above) that you know of that I could check out or if it is simple enough to do and I am just over complicating it, how would you go about the issue?
Well, using a framework use to be a good idea because it solves cross-browser issues and is a more full-featured solution than a code that you can make from scratch.
Anyway, if your needs are very limited you can do it yourself. BTW, you dind't tag the question with jQuery, but I will suppose that you are using it.
I don't think you need to use a canvas. Instead:
Place the image twice, the second one inside a hidden container.
Scale down the first one so you can use as a thumbnail.
Leave the second one in its original size, but ensure the container has overflow: hidden.
Create a mousemove event. It needs to make visible the container.
Detect the position of the mouse inside the picture with e.pageX / e.pageY and $( element ).offset().
Calculate the ratio between the area of the thumbnail and the original picture size.
Every time you move the cursor, modify the margins of the original size picture (the one inside the container) according the calculated ratio.
Create a mouseout event that hides the container.
Here you have a snippet:
var zoom_container_size = $( '.zoom_container').height();
var zoom_area_size = 100;
var zoom_radius = zoom_area_size / 2;
$( '.thumbnail' ).mousemove(function(e) {
// Show original picture
var $original = $( '#' + this.id + '_original');
var $container = $original.parent();
$container.removeClass( 'hidden' );
// Thumbnail
var offset = $( this ).offset();
var tX = e.pageX - offset.left;
var tY = e.pageY - offset.top;
// We stay inside the limits of the zoomable area
tX = Math.max( zoom_radius, Math.min( $( this ).width() - zoom_radius, tX ) );
tY = Math.max( zoom_radius, Math.min( $( this ).height() - zoom_radius, tY ) );
// Ratios
var ratioX = ( $original.width() - zoom_container_size) / ( $( this ).width() - zoom_area_size );
var ratioY = ( $original.height() - zoom_container_size) / ( $( this ).height() - zoom_area_size );
// Margin to be set in the original
var moX = -Math.floor( ( tX - zoom_radius ) * ratioX );
var moY = -Math.floor( ( tY - zoom_radius ) * ratioY );
// Apply zoom efect
$original.css( 'marginLeft', moX );
$original.css( 'marginTop', moY );
// Log values
$('#ratios').html( 'Ratio X: <b>' + ratioX + '</b><br>Ratio Y: <b>' + ratioY + '</b>' );
$('#coordinates_thumbnail').html( 'tX: <b>' + tX + '</b><br>tY: <b>' + tY + '</b>' );
$('#coordinates_original' ).html( 'Margin left: <b>' + Math.round(moX) + '</b><br>Margin top: <b>' + moY + '</b>' );
});
$( '.thumbnail' ).mouseout(function(e) {
var $original = $( '#' + this.id + '_original');
var $container = $original.parent();
$container.addClass( 'hidden' );
});
.main_container div {
display: inline-block;
}
.thumbnail {
height: 200px;
}
div.zoom_container {
width: 200px;
height: 200px;
overflow: hidden;
}
.zoom_container.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A beautiful pic from Külli Kolina.
<div id="zoom_area"></div>
<div class="main_container">
<img id="forest" class="thumbnail" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Talv_V%C3%A4ike-Taevaskojas.jpg/640px-Talv_V%C3%A4ike-Taevaskojas.jpg">
<div class="zoom_container hidden">
<img id="forest_original" class="original" src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Talv_V%C3%A4ike-Taevaskojas.jpg/640px-Talv_V%C3%A4ike-Taevaskojas.jpg">
</div>
</div>
<hr><span id="ratios">Ratios</span>
<hr><span id="coordinates_thumbnail">Coordinates</span>
<hr><span id="coordinates_original">Negative margin</span>
There is a lot of things that can be optimized in this code (mainly related to get some of the work out of the event handler) to get a smoother effect, but you have now a base to start to work on. If you are really concern about performance you can read this other answer (the topic is different but most of the ideas apply in the same way).
Hope it helps!
edit- I actually had my image originally position:relative. I have fixed that in my code. I would like the image to scroll left until it has disappeared from the window. I would like it to stop moving, or even reset. I can do that part. I used the developer window in chrome to check, and the position:right of the image in question moves on well past 1700px, which I tried to stop with my if block in paraScrollRight
I'm trying to get an image to stop moving, so that I can get another image to move while the user scrolls down the page. For some reason, my if logic doesn't stop scrolling at all.
var yPos, image;
function paraScrollDown(){
yPos = window.pageYOffset;
image = document.getElementById("image");
image.style.top = (yPos * 1.0) + "px";
}
function paraScrollRight(){
yPos = window.pageYOffset;
image = document.getElementById("image");
if(image.style.right <= 1,374 + "px") {
image.style.right = (yPos * 2.7) + "px";
}
}
window.addEventListener("scroll",paraScrollRight);
<img id="image" style="position:relative" src="https://s-media-cache-ak0.pinimg.com/236x/ee/94/32/ee94322ba44eebc686d2e8381a84259c.jpg" />
Try this: https://jsfiddle.net/92rse23e/
I only handled the paraScrollDown method since that's what I understood what you needed to be taken care of. An important thing you needed to add was to make the image position: absolute; in CSS.
I'm using the jQuery library 'transitions' for its extension in simply CSS tweening. The issue, however, comes when I simply try to hide or remove the backdrop (which causes the area around the appearing content to get darker).
When I hide/remove the backdrop, the original site underneath it "flashes" with a bright color before returning to its original dark scheme.
Webpage in question (just click one of the TV shows to make the backdrop appear, then click anywhere off of it to witness the removal + flashing) : Webpage in Question
$(document).ready(function(){
$("#MetaContent").transition({scale:[0,0]});
$(".AMResultSelector").click(function(){
var Title = $(this).children("span").html();
var CoverPhoto = $(this).children("img").attr("src");
var Description = $(this).children("p").html();
$("#MetaTitle").html(Title);
$("#MetaCoverPhoto").attr('src', CoverPhoto);
$("#MetaSummary").html(Description);
$("#AMMetaGoTo").children("a").attr("href", "/?Page=ViewAnime&ID=" + $(this).attr("data-media-id"));
//Center it
setTimeout(function(){
var CWidth = $("#AMMetaPreviewBox").width();
var CHeight = $("#AMMetaPreviewBox").height();
var OffsetX = $("#MetaContent").width()/2;
var OffsetY = $("#MetaContent").height()/2;
console.log(OffsetX);
$("#MetaContent").css("left", (CWidth/2 - OffsetX) + "px");
$("#MetaContent").css("top", (CHeight/2 - OffsetY) + "px");
}, 10);
$("#AMMetaPreviewBox").show();
$("#MetaContent").transition({scale:[1,1]}, 200);
})
$("#AMMetaPreviewBox").click(function(){
$("#MetaContent").transition({scale:[0,0]}, 200, function(){ $("#AMMetaPreviewBox").hide() });
})
})
</script>
I don't understand why this is happening...
Browser: Google Chrome Version 39.0.2171.95 m
I've implemented a JavaScript function that shows a popup when a particular image is clicked; however, the popup and the cover (transparent grey cover behind the popup that when clicked makes the popup go away) won't move to the center of the current window. As the image can be clicked wherever it is visible, the popup needs to open in the center (which will have a dynamic height and static width) of the page in its current position (when the image was clicked). I also need this to work with multi-monitor setups. I found this JavaScript
function PopupCenter(url, title, w, h) {
// Fixes dual-screen position Most browsers Firefox
var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
var dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;
width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
var left = ((width / 2) - (w / 2)) + dualScreenLeft;
var top = ((height / 2) - (h / 2)) + dualScreenTop;
var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
// Puts focus on the newWindow
if (window.focus) {
newWindow.focus();
}
}
but I'm fairly new to JavaScript and I'm not sure how to implement something like this. If there is a fix using HTML and CSS then I'd much prefer that, but a simple JavaScript fix that I can follow is fine. Thanks if you can help.
My code is here: http://jsbin.com/EMAHetA/4/edit
What I think you're trying to create here is typically called a modal, and it's possible to pull one off in pure CSS. You can also implement a modal in jQuery: do some searching for "jquery modal" and see what you get. I recommend Foundation Reveal (if you don't mind including some other useful js) or Kyle Fox's modal code (super lightweight).
Using the PopupCenter code you have provided, you could do the following.
In HTML (I use JSON in a data attribute to make it easy). The class will be used to find the nodes.
<span
class="popup"
data-popup='{"s": "http://google.com", "t": "Google", "h": 400, "w": 400}'
>Click me!</span>
In JavaScript
window.addEventListener('load', function () { // wait for nodes to exist
var popups = document.getElementsByClassName('popup'), // get all the popups
i = popups.length; // for iterating
function clickPopupNode() { // function describing actions to take
var obj = JSON.parse(this.getAttribute('data-popup'));
PopupCenter(obj.s, obj.t, obj.h, obj.w);
}
while (i-->0) { // iterate over each matching node
popups[i].addEventListener('click', clickPopupNode); // and attach func
}
});
Demo
Except your PopupCenter code function does not seem to work as you intend; try this simplified version instead
function PopupCenter(s, t, h, w) {
var y = (window.screen.height - (h | 0)) / 2,
x = (window.screen.width - (w | 0)) / 2;
window.open(
s, t,
'scrollbars=yes, width='+w+', height='+h+', top='+y+', left='+x
).focus();
}
Demo 2
If you do not want to use javascript or any external modal libraries and instead want to use pure css, you can just add the following css code to your div element
.Absolute-Center {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
Fiddle: http://jsfiddle.net/mBBJM/1/
I'd rather not have to answer my own question again, but I've figured out how to do it, and this method isn't in any of the answers. Anyway, the idea is actually rather simple. First determine the dimensions of the popup, which in my case is 1280px x 720px. Then give the popup this css (in context):
position:fixed;
top:50%;
left:50%;
margin:-360px 0 0 -640px;
What this does is set the position of the popup's top-left corner at the center of the screen, and then set the left and top dimensions of the popup back by half of its own dimensions, effectively moving the center of the popup to the center of the screen. To use this method yourself, all you need to do is adjust the various dimensions accordingly.
According to the Slimbox2 documentation this function isn't supported. But I was wondering if anyone had encountered any tricks to make this work.
The main concern I have is that some of my images are fairly lengthy, and at low resolution LightBox2 would create an annoying experience for the user.
I recently started to use slimbox2 on my website (http://www.trips.elusien.co.uk) and found that it could benefit from a few modifications:
"slide resize": this makes the size of the slideshow constant, rather than depending on the size of the image (by specifying a pixel size), or you can use a percentage to make the slides larger or smaller in the slideshow. You specify this using 2 new options:
slideWidth: 0, // Initial width of the slide (in pixels or in percent as a string e.g. "50%")
slideHeight: 0, // Initial height of the slide (in pixels or in percent as a string e.g. "50%")
enable the slides to be flipped automatically, rather than manually. You specify this using a new option:
slideInterval: 0, // Interval between flipping slides (in seconds), 0 means no automation.
download the slides from the slideshow.
The first and last features cannot be done with the origal version of slimbox2 since in that version the image is displayed as a BACKGROUND image, rather than using the "IMG" tag.
I have put the Javascript and CSS files on my website. If you want to try them go to my website and click on the "slimbox examples" link, you can download them from here. To see a neat way of using slimbox2 click in the "photoSLide Show" link on the home-page.
Regards Neil
its easy to fix check my code.
find and replace the three lines in slimbox2.js file:
$(image).css({backgroundImage: "url(" + activeURL + ")", visibility: "hidden", display: ""});
$(sizer).width(preload.width);
$([sizer, prevLink, nextLink]).height(preload.height);
with:
/* make sure the image won't be bigger than the window */
window.innerWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; //ie fix
window.innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; //ie fix
var winWidth = window.innerWidth-200; //browser width
var winHeight = window.innerHeight-100; //browser height
var my_w = preload.width; //original width
var my_h = preload.height; //original height
// scale width
var scaleW1 = winWidth;
var scaleH1 = (my_h * winWidth) / my_w;
// scale height
var scaleW2 = (my_w * winHeight) / my_h;
var scaleH2 = winHeight;
var scale = (scaleW2 > winWidth);
if (scale) {
reswidth = Math.floor(scaleW1);
resheight = Math.floor(scaleH1);
}
else {
reswidth = Math.floor(scaleW2);
resheight = Math.floor(scaleH2);
}
if ($("p").hasClass("slimboxie")){
$(image).css({filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader( src='"+ activeURL + "', sizingMethod='scale')", visibility: "hidden", display: ""});
$(sizer).width(reswidth);
$([sizer, prevLink, nextLink]).height(resheight); }
else {
$(image).css({backgroundImage: "url(" + activeURL + ")", backgroundSize: reswidth + "px " + resheight + "px", visibility: "hidden", display: ""});
$(sizer).width(reswidth);
$([sizer, prevLink, nextLink]).height(resheight);
}
im amateur at javascript but i think its working great. I made it work with IE8 also. You only need to insert:
<!--[if IE 8]>
<p class="slimboxie"></p>
<![endif]-->
after loading the image, do this:
$('#lbImage').css('background-size', 'contain');