Keeping iframe/image ratio when resizing on height - javascript

I managed to keep the iframe's ratio for when the user resizes the window on width, but I have trouble adding the logic for when the user resizes the window on height due to conflicting logic, since the resize on width already alters the height of the iframe.
This is the function that gets called when resizing:
function calculateAspectRatioFit(width, height, ratio) {
if(height) {
let width = ((length)/(Math.sqrt((1)/(Math.pow(ratio, 2)+1))));
return Math.round(width);
} else if(width) {
let height = ((width)/(Math.sqrt((Math.pow(ratio, 2)+1))));
return Math.round(height);
}
}
But I believe that the problem lies in the trigger:
const resizeHandler = (e) => {
console.log("inside ", parseInt(iframeHeight), iframeElement.offsetHeight);
if(parseInt(iframeWidth) > iframeElement.offsetWidth) {
// overwrite inline styling
iframeElement.style.cssText = 'height: ' + calculateAspectRatioFit(iframeElement.offsetWidth, null, iframeRatio) + 'px!important';
} else if (parseInt(iframeHeight) > window.innerHeight) {
iframeElement.style.cssText = 'width: ' + calculateAspectRatioFit(null, iframeElement.offsetHeight, iframeRatio) + 'px!important';
}
}
Got any solutions for this? (pen below)
https://codepen.io/Dragosb/pen/WNoeXRa?editors=0011

Solved, as per the codepen (link is the same as the one in the original post):
Added a container for the iframe (if you are using a modal, that can be the container):
const resizeHandler = (e) => {
// get container measures
let computedContainerStyling = getComputedStyle(iframeContainer);
let containerWidth = parseInt(computedContainerStyling.width);
let containerHeight = parseInt(computedContainerStyling.height);
if ( (containerWidth / iframeRatio) > containerHeight){
iframeHeight = containerHeight;
iframeWidth = containerHeight * iframeRatio;
} else {
iframeWidth = containerWidth;
iframeHeight = containerWidth / iframeRatio;
}
iframeElement.style.width = Math.floor(iframeWidth) + 'px';
iframeElement.style.height = Math.floor(iframeHeight) + 'px';
}
window.addEventListener('resize', resizeHandler, false);
https://codepen.io/Dragosb/pen/WNoeXRa?editors=0011

Related

html2canvas won't take scrollHeight into account after resizing div

I am trying to usehtml2canvas to export some divs in .png format. My div has a greater height than my body which is not a problem because I can use the windowHeight option with myDiv.scrollHeight and it works perfectly.
function exp(e) {
html2canvas(e, {
windowWidth: e.scrollWidth,
windowHeight: e.scrollHeight * 1.12
}).then((canvas) => {
let a = document.createElement("a");
a.download = 'capture_' + date + '.png';
a.href = canvas.toDataURL("image/png");
a.click();
});
}
Now, the thing is, the div I'm "screening" is resizable. It shouldn't be a problem given I use the scrollHeight value but it takes the actual height into account instead of scrollHeight.
Working
Not working
I tried pretty much everything I could find on the internet, every configuration option on html2canvas, myDiv.scrollTo(0,0) as explain in this second answer
I don't know if it can help but here is my resize code :
function resize_height(e) {
topTab.scrollTop = 0
topTab.style.overflow = 'hidden'
const dx = m_pos_height - e.y;
m_pos_height = e.y;
topTab.style.height = (topTab.offsetHeight - dx) + "px"
botTab.style.height = cont - (topTab.offsetHeight - dx) + "px"
topTab.style.maxHeight = cont + 'px'
}
botTab.addEventListener("mousedown", function (e) {
if (e.offsetY < BORDER_SIZE_HEIGHT) {
m_pos_height = e.y;
document.addEventListener("mousemove", resize_height, false);
}
}, false);
document.addEventListener("mouseup", function () {
document.removeEventListener("mousemove", resize_height, false);
topTab.style.overflow = 'auto'
}, false);
topTab being the div I try to screen.

Remove function on browser width

I'm still very new to javascript and I'm learning as I build. This may be a simple fix but how would I disable a function on my parallax images ( or disable a specific js function in general ) on a smaller width?
Here's what I have so far that doesn't quite work but shows "undefined". I've been searching for a solution for a couple of days now with no luck. Any help would be appreciated.
var paraLlaxS = document.querySelector("#firstImgc2");
var paraLlaxS = document.querySelector("#secondImgc2");
var paraLlaxS = document.querySelector("#backbox1");
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + ", " + yPos + "px, 0)";
}
window.addEventListener("DOMContentLoaded", scrollLoop, false);
var xScrollPosition;
var yScrollPosition;
function scrollLoop() {
xScrollPosition = window.scrollX;
yScrollPosition = window.scrollY;
setTranslate(0, yScrollPosition * -0.2, firstImgc2);
setTranslate(0, yScrollPosition * 0.15, secondImgc2);
setTranslate(0, yScrollPosition * -0.6, backbox1);
requestAnimationFrame(scrollLoop);
if(window.innerWidth < 900) {
document.querySelector('#firstImgc2').innerHTML = window.removeEventListener("DOMContentLoaded", scrollLoop, false);
return;
} else {
}
}
You could add a conditional return at the beginning of you function. But if the width increases again you would need to listen for that to start the loop again.
function scrollLoop() {
if(window.innerWidth < 900)return;
...
I borrowed a solution from another post.
Listen for browser width for responsive web design?
This code is compatible with a wider variety of browsers as getting the screen size can vary depending on the browser.
var width = 0;
function getWindowSize() {
if (document.body && document.body.offsetWidth) {
width = document.body.offsetWidth;
}
if (document.compatMode=='CSS1Compat' &&
document.documentElement &&
document.documentElement.offsetWidth ) {
width = document.documentElement.offsetWidth;
}
if (window.innerWidth) {
width = window.innerWidth;
}
return(width);
}

trigger animation at the end of debounced requestanimationframe

I followed Paul Lewis's guide to debounce and requestAnimationFrame. I'm translating an image across the screen on scroll when it comes into view.
var bicycles = $('.tandem-bike', context),
lastScrollY = 0,
ticking = false;
function update() {
var windowHeight = window.innerHeight,
windowWidth = $(window).width(),
bikeTop = [];
bicycles.each( function (i, el) {
bikeTop[i] = $(this).offset();
});
bicycles.each(function(i, el) {
var position = bikeTop[i];
var fromTop = position.top - windowHeight;
var imgHeight = $(this).height();
// When this image scrolls into view.
if (lastScrollY > fromTop && lastScrollY < position.top + imgHeight && i == 1 ) { // 375 ~= height of image
var translate = Math.floor((lastScrollY - fromTop) / ((windowHeight + imgHeight + 300) / windowWidth));
console.log('add tp tranlate ', translate);
$(this).css('transform', 'translateX(' + (translate - 275) + 'px)');
}
});
ticking = false;
}
function onScroll() {
lastScrollY = window.scrollY;
requestTick();
}
function requestTick() {
if(!ticking) {
requestAnimationFrame(update);
ticking = true;
}
}
window.addEventListener('scroll', onScroll, false);
This works great and the bicycle-built-for-two slides effortlessly across the screen. However, I want the image to "bounce" when the user stops scrolling. I figure an easy way would be to add a class when the animation ends, and pull it off when the animation starts. The obvious place to do that is within the if block in requestTick().
if(!ticking) {
$('.tandem-bike').removeClass('bounce');
requestAnimationFrame(update);
$('.tandem-bike').addClass('bounce');
ticking = true;
}
or
if(!ticking) {
requestAnimationFrame(update);
$('.tandem-bike').addClass('bounce');
ticking = true;
} else {
$('.tandem-bike').removeClass('bounce');
}
}
Neither works, and I don't love then because I'm whole-sale adding classes to all the animated images on the page. (I would live with that if it worked)

How to make script resize images and divs on window resize and orientation change

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);
}

Rerun javascript function when screen orientation changes

I'm using a code that scale images to fit the parent div, it's called "aspectcorrect".
The problem happens on the mobile version: my parent div has 100% width, and when the user changes the orientation of the screen to landscape, the image doesn't resize to fit the new div's width.
There is a way to rerun the onload event (which scales the image), when the user changes the orientation of the screen?
Here is my website: www.mcsoftware.com.br/sitemc
I'm still working on it.
(To understand what I'm saying, open it on your cellphone, and when you change the screen orientation just click on "Continuar mesmo assim" to navigate)
Thanks!
aspectcorrect.js
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;
}
onimageload.js
function OnImageLoad(evt) {
var img = evt.currentTarget;
// what's the size of this image and it's parent
var w = $(img).width();
var h = $(img).height();
var tw = $(img).parent().width();
var th = $(img).parent().height();
// compute the new size and offsets
var result = ScaleImage(w, h, tw, th, false);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
Where onload function goes
<img onload="OnImageLoad(event);" />
https://jsfiddle.net/ffxeqq21/
You can try some javascript library like jQuery mobile and use the orientationchange event This way you could just do
$( window ).on( "orientationchange", function( event ) {
//Some code
});

Categories