if i zoom the image it will going to the right. here is my js function below. the moment i zoom the image the background actual width and height is constant only the background size should be dynamic. that's the reason why it looks like if it zoom it will going to the right not in the center. what i want is when i zoom the image it zoom it forward to the center of the image.
function zooms(zoomType) {
switch(zoomType) {
case '+':
newW += 10;
break;
case '-':
newW -= 10;
break
}
if(newW <= 0) {
newW = 0;
} else {
if(newW >= 100) {
newW = 100;
}
}
return newW;
}
function backgroundAdjust(num, el) {
wid = (parseInt(num)+parseInt(el.width()));
el.css({
'background-size': wid + 'px auto'
});
return;
}
$('input.zoomButton').click(function() {
zoomType = $(this).val();
zoomNum = zooms(zoomType);
backgroundAdjust(zoomNum, $('#uploadImage'));
});
This should work if your image is square : it offsets the background image so its center remains at the center of the containing element.
var posx = (el.width()-wid)/2;
var posy = (el.height()-wid)/2;
el.css({
'background-size': wid + 'px auto',
'background-position': posx +'px ' +posy +'px'
});
What worked for me was scrolling the container element by half the value of same amount you are increasing the width and height of the image. For this you can use scrollBy. Eg. if your container element is el and the image inside is img. Now to zoom-in if you are increasing the width and height by 10% of the current 'x' px and height by 'y' px, Your zoom-in function would look like below:
function zoomIn() {
let imgWidth = img.width.replace(/px/g,""); // removing 'px'
let imgHeight = img.height.replace(/px/g,""); // removing 'px'
let x = imgWidth + (imgWidth*0.1);
let y = imgHeight + (imgHeight*0.1);
el.scrollBy(x/2, y/2);
}
Related
I am trying to get a div to expand div to always fill the viewport;
at the moment i calculate the if the div is left ,rigth above or below the center of the viewport and expand accordingly.
I would prefer if the div would expand to center in the viewport if possible. atm the moment i am just adjusting the margin to allow the div to expand sideways. but if the expanded div is big it can expand passed the viewport on a side while having enough space on the otherside.
this has to be in vannilla javascript. My current code follows:
function calculateExpandDir(el) {
var ele = el.getBoundingClientRect();
var windowH = window.innerHeight;
var windowW = window.innerWidth;
var expandDir = {}
if (ele.left + (ele.width / 2) >= window.innerWidth / 2) { expandDir.horizontal = "left" } else { expandDir.horizontal = "right" }
if (ele.top + (ele.height / 2) >= window.innerHeight / 2) { expandDir.vertical = "up" } else { expandDir.vertical = "down" }
return expandDir
}
function expandEl(el) {
var expandedHeight = parseFloat(el.getAttribute('data-height'));
var expandedWidth = parseFloat(el.getAttribute('data-width'));
var originalWidth = parseFloat(el.getAttribute('data-orig-width'));
var originalHeight = parseFloat(el.getAttribute('data-orig-height'));
var marginTop = 0;
var marginRight = 0;
var marginBottom = 0;
var marginLeft = 0;
var dir = calculateExpandDir(el)
console.log("expand to " + dir.vertical + dir.horizontal)
if (dir.horizontal == "right") {
}
if (dir.horizontal == "left") {
marginLeft = -(expandedWidth - originalWidth);
}
if (dir.vertical == "up") {
marginTop = -(expandedHeight - originalHeight)
}
if (dir.vertical == "down") {
};
el.style.position = "absolute";
el.style.height = expandedHeight+"px";
el.style.width = expandedWidth + "px";
el.style.transition = "all 0.5s ease-in-out";
el.style.marginTop = marginTop+"px";
el.style.marginBottom = marginBottom+"px";
el.style.marginLeft = marginLeft+"px";
el.style.marginRight = marginRight+"px";
}
I figured i have to calculate the ammount of space on each side of the div and expand the div proportionally to the ammount of space available so it will become centered but i am stuck on how to do this at the moment
EDIT:
https://codepen.io/sereal_killer/pen/eGZaNo
in this example the divs expand depending on their position. the center div is a cheat as it has the data attribute to tell it to expand in both directions.
i want the divs to expand to fill the screen depending on the available room (they have a max height and width).
if i have a centered div like in the example i want it to know it has equal room on both sides and expand equally left and right.
if it is a bit more to the right i want it to expand to still be centered.
the caveat is that it cannot leave where it originated. it cant pop out and just appear in the center. If i have time i will draw a picture aswell
I am attempting to code a custom mouse trail. To do this I am using temporary divs that appear at the mouse location and fade out after a small interval. Currently the divs only appear at mouse location. I am trying to make them appear at where the mouse is at the moment and stay there while the mouse moves on and draws more divs. Also, how would I add a fade out effect to each individual div so after being placed it would slowly go transparent.
Here's my code so far.
var posX,
posY,
paused = null,
circles = [],
maxCircles = 30,
//width & height of div
circleSize,
//border radius to make it look like a circle
rad,
randCircle;
$(document).ready(function() {
for (var i = 0; i < maxCircles; i++) {
circleSize = Math.floor((Math.random() * 10) + 5);
rad = Math.floor(circleSize / 2);
circles[i] = document.createElement("Div");
circles[i].style.opacity = "0.6";
circles[i].className = "circle";
circles[i].style.width = circleSize + "px";
circles[i].style.height = circleSize + "px";
circles[i].style.borderRadius = rad + "px";
circles[i].style.background = "green";
circles[i].style.zIndex = "-1";
}
$("body").mousemove(function(e) {
posX = e.clientX - 5;
posY = e.clientY - 5;
randCircle = Math.floor((Math.random() * (maxCircles - 1)) + 0);
if (!paused) {
document.getElementsByTagName("body")[0].appendChild(circles[randCircle]);
$('.circle').css({
position: "absolute",
top: posY,
left: posX
});
paused = setTimeout(function() {
paused = null
}, 100);
}
});
});
body, html {
height: 100%;
background: #eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Your divs change position because you're setting the position of every div with the class name "circle".
You need to change
$('.circle').css({position:"absolute", top:posY,left:posX});
To
circles[randCircle].css({position:"absolute", top:posY,left:posX});
To make them fade out you could add an animation to the circles using CSS.
I am currently using the following javascript to resize an image to the size of it's parent, while maintaining aspect ratio and keeping the parent div square. So i have a square box with a rectangle stretched to either the max width or max height depending on orientation. This works great on first load however I cannot get the images and divs to resize on page orientation change or resize to work. Any ideas. I have tried using the window.resize and window.orientation listeners.
Original code was from:
Scale, crop, and center an image...
var aspHt = $('.aspectcorrect').outerWidth();
$('.aspectcorrect').css('height', aspHt + 'px').css('width', aspHt + 'px');
function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox) {
var result = {
width : 0,
height : 0,
fScaleToTargetWidth : true
};
if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) {
return result;
}
// scale to the target width
var scaleX1 = targetwidth;
var scaleY1 = (srcheight * targetwidth) / srcwidth;
// scale to the target height
var scaleX2 = (srcwidth * targetheight) / srcheight;
var scaleY2 = targetheight;
// now figure out which one we should use
var fScaleOnWidth = (scaleX2 > targetwidth);
if (fScaleOnWidth) {
fScaleOnWidth = fLetterBox;
} else {
fScaleOnWidth = !fLetterBox;
}
if (fScaleOnWidth) {
result.width = Math.floor(scaleX1);
result.height = Math.floor(scaleY1);
result.fScaleToTargetWidth = true;
} else {
result.width = Math.floor(scaleX2);
result.height = Math.floor(scaleY2);
result.fScaleToTargetWidth = false;
}
result.targetleft = Math.floor((targetwidth - result.width) / 2);
result.targettop = Math.floor((targetheight - result.height) / 2);
return result;
}
function RememberOriginalSize(img) {
if (!img.originalsize) {
img.originalsize = {
width : img.width,
height : img.height
};
}
}
function FixImage(fLetterBox, div, img) {
RememberOriginalSize(img);
var targetwidth = $(div).width();
var targetheight = $(div).height();
var srcwidth = img.originalsize.width;
var srcheight = img.originalsize.height;
var result = ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox);
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
function FixImages(fLetterBox) {
$("div.aspectcorrect").each(function(index, div) {
var img = $(this).find("img").get(0);
FixImage(fLetterBox, this, img);
});
}
window.onload = function() {
FixImages(true);
};
Call .resize() after $(window).resize():
$(window).resize( function(){
var height = $(window).height();
var width = $(window).width();
if(width>height) {
// Landscape
$("#landscape").css('display','none');
} else {
// Portrait
$("#landscape").css('display','block');
$("#landscape").click(function(){
$(this).hide();
});
}
}).resize();
I figured out what I was missing. The first bit of javascript is setting the style of height and width. When recalling the .outerHeight it was still using the inline style to calculate the width, and hence not resizing the div. I simply used .removeAttr('style') to remove that property first and then did the resize. Working now. I simply used $(window).on("resize", resizeDiv) and wrapped my resizing into a function named resizeDiv
function resizeDiv() {
var asp = $('.aspectcorrect');
asp.removeAttr("style");
var aspHt = asp.outerWidth();
asp.css('height', aspHt + 'px').css('width', aspHt + 'px');
FixImages(true);
}
I'm looking for an effect very similar to this:
http://jsfiddle.net/G5Xrz/
function rnd(max) { return Math.floor(Math.random()*(max+1)) }
function showImage(container, maxwidth, maxheight, imgsrc, imgwidth, imgheight) {
var id = "newimage" + rnd(1000000);
$(container).append(
"<img id='" + id + "' src='" + imgsrc +
"' style='display:block; float:left; position:absolute;" +
"left:" + rnd(maxwidth - imgwidth) + "px;" +
"top:" + rnd(maxheight - imgheight) + "px'>");
$('#' + id).fadeIn();
return id;
}
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
But i'd prefer a flexible layout, ie images not bound by a div with predefined height and width, instead responding to the dimensions of the browser.
The following piece of code seems to have a more appropriate way of generating the random positions:
http://jsfiddle.net/Xw29r/15/
function makeNewPosition(){
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh,nw];
}
function animateDiv(){
var newq = makeNewPosition();
var oldq = $('.a').offset();
var speed = calcSpeed([oldq.top, oldq.left], newq);
$('.a').animate({ top: newq[0], left: newq[1] }, speed, function(){
animateDiv();
});
};
However I'm very much a beginner with javascript and I don't know how to combine the two.
Can anyone help?
Thanks
Take this part from the second code:
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
and use those variables h and w with the browser height and width (minus 50) as the appropriate parameters in this part of the first code:
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
Also, the first code has this HTML:
<div id="container" style="width:400px; height:600px; background: green; position:relative"></div>
That hard-codes the height and width at pixel values. You can use a CSS percentage value to make the width respond to the parent container's size. However, you will need JS to set the height properly; a percentage for the height does nothing
Putting that all together (and removing the "minus 50" part), you get this:
jsFiddle demo
<div id="container" style="width:100%; height:100px; background: green; position:relative"></div>
function adjustContainerHeight(height) {
$('#container').height(height);
}
adjustContainerHeight($(window).height());
setInterval(
function() {
var h = $(window).height();
var w = $(window).width();
adjustContainerHeight(h);
showImage("#container", w, h,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
This updates the height of the container when the page is first loaded, and once again whenever the random image is placed. More robust code would have a separate height-adjusting event handler that updates the height whenever the page size changes.
I am creating an image hover effect but I am having problem with it. When I hover over certain images, the scrollbars appear which I want to avoid but don't know how to do so. I believe it has to do with viewport and calculations but am not sure how that is done.
Example Here
JSBin Code
Here is the code:
$('.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');
});
});
Can anyone please help me how do I make it so that hovered image appears at such place that scrollbars dont appear? (Of course we can't avoid scrollbar if image size is very very big)
I just want to show original image on zoom while avoiding scrollbars as much as possible.
Please note that I am planning to convert it into jQuery plugin and therefore I can't force users of plugin to have overflow set to hidden. The solution has do with viewport, left, top, scroll width and height, window width/height properties that I can incorporate into plugin later on.
Update:
I have come up with this:
http://jsbin.com/upuref/14
However, it is very very hacky and not 100% perfect. I am looking for a better algorithim/solution. I have seen many hover plugins that do this very nicely but since I am not that good at this, I can't do it perfectly well. For example Hover Zoom Chrome Plugin does great job of showing hovered images at appropriate place based on their size.
Like this:
html{overflow-x:hidden;}
html{overflow-y:hidden;}
All you need to do is add these definitions to your CSS and you're done.
Update with Resize: this is the mouseenter code for resizing and repositioning the pictures BOTH horizontally and vertically. Now, no matter where the HOVER image shows up, it's resized and positioned to always show in full AND uncut. As far as the scrollbars are concerned, if you show more thumbnails than can fit on the page, you will have scrollbars even before the HOVER images show up.
FINAL AND WORKING UPDATE: Because you had focused on the scrollbars being hidden, I think you overlooked the fact that if you put more thumbnails than the viewport can contain, the scrollbars would show up anyway and that therefore, since the user can scroll down the document, when you calculate the position of the hover image, not only do you need to account for the resize but you also to account for the scrollTop position too! FINAL JSBIN HERE, all pictures are showing RESIZED and in FULL no matter where the scrollTop is and no matter what the viewport size is.
$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');
});
Well, this looks fun. Anyway, here's my answer. I've been watching this for a few days and though I'd chip in too. The following will make sure that the hovering images do not go out of the viewport and in the event that the width of the image is bigger than the available space for display, the display of the image will be resized (You can comment out the code that does this if you don't want it. Just look for the word "resize" in the code).
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();
});
});
While my solution itself is not perfect, you might find something useful in there that can help you determine the viewport. Also, you might want to think about the performance of the code. Since this is a plugin that you're building, you'll want to make some optimizations before releasing it to public. Basically, just make sure it's not slow.
You can position the image based on the available width: http://jsbin.com/upuref/19/
This demo takes in account the available space for positioning the image (i.e. the window width minus the image width). Also I've improved the event order, with the popup div only starting its fade-in after the image has been loaded.
My answer too (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');
});
});
this script adapt the image to window size and adjust x position if needed.