Algoritmo de cálculo de la window de image de jQuery para evitar barras de desplazamiento

Estoy creando un efecto de image estacionario pero estoy teniendo problemas con él. Cuando sobrevuelo sobre ciertas imágenes, aparecen las barras de desplazamiento que quiero evitar pero no sé cómo hacerlo. Creo que tiene que ver con la window gráfica y los cálculos, pero no estoy seguro de cómo se hace eso.

Ejemplo aquí

Código JSBin

Aquí está el código:

$('.simplehover').each(function(){ var $this = $(this); var isrc = $this[0].src, dv = null; $this.mouseenter(function(e){ dv = $('<div />') .attr('class', '__shidivbox__') .css({ display: 'none', zIndex : 9999, position: 'absolute', top: e.pageY + 20, left: e.pageX + 20 }) .html('<img alt="" src="' + isrc + '" />') .appendTo(document.body); dv.fadeIn('fast'); }) .mouseleave(function(){ dv.fadeOut('fast'); }); }); 

¿Alguien puede por favor ayudarme cómo lo hago para que aparezca la image suspendida en el lugar donde no aparecen las barras de desplazamiento? (Por supuesto no podemos evitar la barra de desplazamiento si el tamaño de la image es muy grande)

Solo quiero mostrar la image original con el zoom mientras evito las barras de desplazamiento tanto como sea posible.

Tenga en count que estoy planeando convertirlo en un plugin jQuery y, por lo tanto, no puedo obligar a los usuarios del complemento a tener el overflow establecido en hidden . La solución tiene que ver con window gráfica , izquierda , arriba , ancho y alto de desplazamiento , properties de ancho / alto de window que puedo incorporar al plugin más adelante.


Actualizar:

He venido con esto:

http://jsbin.com/upuref/14

Sin embargo, es muy muy hacky y no es 100% perfecto. Estoy buscando un mejor algorithm / solución. He visto muchos plugins hover que hacen esto muy bien, pero como no soy tan bueno en esto, no puedo hacerlo perfectamente bien. Por ejemplo, el complemento Hover Zoom Chrome hace un excelente trabajo al mostrar imágenes en el lugar apropiado en function de su tamaño.

Bueno, esto parece divertido. De todos modos, aquí está mi respuesta . He estado viendo esto durante unos días y aunque también me gustaría participar. A continuación, se asegurará de que las imágenes flotantes no salgan de la window gráfica y, en el caso de que el ancho de la image sea mayor que el espacio disponible para visualizar, la visualización de la image cambiará de tamaño (puede comentar el código eso hace esto si no lo quieres. Solo busca la palabra "networkingimensionar" en el código).

 var $document = $(document); $('.simplehover').each(function(){ var $this = $(this); // make sure that element is really an image if (! $this.is('img')) return false; var isrc = $this[0].src, ibox = null; if (! isrc) return false; ibox = $('<img />') .attr('class', 'simpleimagehover__shidivbox__') .css({ display: 'none', zIndex : 99, MozBoxShadow: '0 0 1em #000', WebkitBoxShadow: '0 0 1em #000', boxShadow: '0 0 1em #000', position: 'absolute', MozBorderRadius : '10px', WebkitBorderRadius : '10px', borderRadius : '10px' }) .attr('src', isrc) .appendTo(document.body); $this.bind('mouseenter mousemove', function(e) { $('.simpleimagehover__shidivbox__').hide(); var left = e.pageX + 5, top = e.pageY + 5, ww = window.innerWidth, wh = window.innerHeight, w = ibox.width(), h = ibox.height(), overflowedW = 0, overflowedH = 0; // calucation to show element avoiding scrollbars as much as possible - not a great method though if ((left + w + $document.scrollLeft()) > ww) { overflowedW = ww - (left + w + $document.scrollLeft()); if (overflowedW < 0) { left -= Math.abs(overflowedW); } } // 25 is just a constant I picked arbitrarily to compensate pre-existing scrollbar if the page itself is too long left -= 25; left = left < $document.scrollLeft() ? $document.scrollLeft() : left; // if it's still overflowing because of the size, resize it if (left + w > ww) { overflowedW = left + w - ww; ibox.width(w - overflowedW - 25); } if (top + h > wh + $document.scrollTop()) { overflowedH = top + h - wh - $document.scrollTop(); if (overflowedH > 0) { top -= overflowedH; } } top = top < $document.scrollTop() ? $document.scrollTop() : top; ibox.css({ top: top, left: left }); ibox.show(); }); $('.simpleimagehover__shidivbox__').mouseleave(function(){ $('.simpleimagehover__shidivbox__').hide(); }); $document.click(function(e){ $('.simpleimagehover__shidivbox__').hide(); }); $document.mousemove(function(e){ if (e.target.nodeName.toLowerCase() === 'img') { return false; } $('.simpleimagehover__shidivbox__').hide(); }); }); 

Si bien mi solución en sí misma no es perfecta, es posible que encuentre algo útil allí que pueda ayudarlo a determinar la window gráfica. Además, es posible que desee pensar en el performance del código. Como se trata de un complemento que estás creando, querrás realizar algunas optimizaciones antes de publicarlo en público. Básicamente, solo asegúrate de que no sea lento.

Me gusta esto:

 html{overflow-x:hidden;} html{overflow-y:hidden;} 

Todo lo que necesita hacer es agregar estas definiciones a su CSS y listo.

Actualizar con Cambiar tamaño: este es el código del mouseenter para cambiar el tamaño y el reposicionamiento de las imágenes, tanto horizontal como verticalmente. Ahora, sin importar dónde aparezca la image HOVER, se cambia de tamaño y se posiciona para mostrar siempre en su totalidad Y sin cortar. En cuanto a las barras de desplazamiento, si muestra más miniaturas de las que caben en la página, tendrá barras de desplazamiento incluso antes de que aparezcan las imágenes HOVER.

ACTUALIZACIÓN FINAL Y DE TRABAJO: debido a que se había centrado en las barras de desplazamiento ocultas, creo que omitió el hecho de que si coloca más miniaturas de las que puede contener la window gráfica, las barras de desplazamiento se mostrarían de todos modos y, por lo tanto, el usuario puede desplazarse hacia abajo. documento, cuando calcule la position de la image de desplazamiento, no solo necesita tener en count el cambio de tamaño sino también la position de scrollTop. FINAL JSBIN AQUÍ , todas las imágenes muestran RESIZED y en su totalidad sin importar dónde esté scrollTop y sin importar el tamaño de la window gráfica.

 $this.mouseenter(function () { dv = $('<div />') .attr('class', '__shidivbox__') .css({ 'display': 'none', 'z-index': 9999, 'position': 'absolute', 'box-shadow': '0 0 1em #000', 'border-radius': '5px' }) .html('<img alt="" src="' + isrc + '" />') .appendTo(document.body); var DocuWidth = window.innerWidth; var DocuHeight = window.innerHeight; var DvImg = dv.find('img'); var TheImage = new Image(); TheImage.src = DvImg.attr("src"); var DivWidth = TheImage.width; var DivHeight = TheImage.height; if (DivWidth > DocuWidth) { var WidthFactor = (DivWidth / DocuWidth) + 0.05; DivHeight = parseInt((DivHeight / WidthFactor), 10); DivWidth = parseInt((DivWidth / WidthFactor), 10); } var ThumbHeight = $this.height(); var ThumbWidth = $this.width(); var ThumbTop = $this.position().top; var ThumbLeft = $this.position().left; var SpaceAboveThumb = ThumbTop - $(document).scrollTop(); var SpaceBelowThumb = DocuHeight - ThumbTop - ThumbHeight + $(document).scrollTop(); var MaxHeight = Math.max(SpaceAboveThumb, SpaceBelowThumb); if (DivHeight > MaxHeight) { var HeightFactor = (DivHeight / MaxHeight) + 0.05; DivHeight = parseInt((DivHeight / HeightFactor), 10); DivWidth = parseInt((DivWidth / HeightFactor), 10); } var HoverImgLeft = 0; var HoverImgTop = 0; if (SpaceBelowThumb > SpaceAboveThumb) { HoverImgTop = ThumbTop + ThumbHeight; } else { HoverImgTop = ThumbTop - DivHeight; } HoverImgTop = (HoverImgTop < 0) ? 0 : HoverImgTop; HoverImgLeft = (DocuWidth - DivWidth) / 2; dv.find('img').css({ 'width': DivWidth, 'height': DivHeight, 'border-radius': '5px' }); dv.css({ 'left': HoverImgLeft, 'top': HoverImgTop }); dv.fadeIn('fast'); }); 

Puede colocar la image según el ancho disponible: http://jsbin.com/upuref/19/

Esta demostración toma en count el espacio disponible para posicionar la image (es decir, el ancho de la window less el ancho de la image). También he mejorado el order de los events, con el div emergente solo comenzando su fade-in después de que la image ha sido cargada.

Mi respuesta también ( JSBin DEMO )

 $('.simplehover').each(function(){ var $this = $(this); // make sure that element is really an image if (! $this.is('img')) return false; var isrc = $this[0].src, dv = null; if (! isrc) return false; $this.mouseenter(function(e){ // mouse x position var initXPos = e.pageX; var initYPos = e.pageY+20-$(window).scrollTop(); var windowWidth = $(window).width(); var windowHeight = $(window).height(); // load original image var $img = $('<img/>'); $img.on('load',function(eload) { var widthImage = this.width; var heightImage = this.height; // set inline style for get sizes after (see problems webkit and cache) $(this).css('width',widthImage); $(this).css('height',heightImage); var ratio = widthImage/heightImage; var finalXPos = initXPos+widthImage>windowWidth? windowWidth-widthImage-5 : initXPos; var finalYPos = initYPos; var img = this; // resize image if is bigger than window if(finalXPos<0) { finalXPos = 0; $img.css('width', windowWidth-10); $img.css('height',(windowWidth-10)/ratio); } // If overflow Y if(finalYPos+getSize($img,'height')>windowHeight) { // calculate where is more space (top or bottom?) var showOnTop = (windowHeight-initYPos-10)<windowHeight/2; if(showOnTop) { if(initYPos<getSize($img,'height')) { $img.height(initYPos-30); $img.width(getSize($img,'height')*ratio); } finalYPos = 0; finalXPos = initXPos+getSize($img,'width')>windowWidth? windowWidth-getSize($img,'width')-5 : initXPos; }else { // show on bottom if(windowHeight-initYPos<getSize($img,'height')) { $img.height(windowHeight-initYPos-10); $img.width(getSize($img,'height')*ratio); } finalXPos = initXPos+getSize($img,'width')>windowWidth? windowWidth-getSize($img,'width')-5 : initXPos; } } dv = $('<div />') .attr('class', '__shidivbox__') .css({ display: 'none', zIndex : 9999, position: 'absolute', MozBorderRadius : '5px', WebkitBorderRadius : '5px', borderRadius : '5px', top: finalYPos+$(window).scrollTop(), left: finalXPos }).append($img) .appendTo(document.body); dv.fadeIn('fast'); }); // load the original image (now is the same, but I think is better optimize it) $img.attr("src",$this.attr("src")); function getSize($el,widthOrHeight) { // horrible but working trick :) return +$el.css(widthOrHeight).replace("px",""); } }) .mouseleave(function(){ dv.fadeOut('fast'); }); }); 

este script adapta la image al tamaño de la window y ajusta la position x si es necesario.