I am trying to set up a basic functionality to smoothly toggle an img on click from being longer than screen to being on a display (fit to window size) (back and forth). It kinda works already using percentages etc.
My issue is I'd like to have a smooth animated transition between the 2 states but the img is being brutally scaled. Also whenever I try to work with "transition" or "animation", when the img come back to its original size, it will block the scrolling. Same issue happened after I tried to use keyframes.
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<style>
img {
margin: auto;
display: block;
padding: 2%;
width: 90vw;
box-sizing: border-box;
}
.scaled {
width: auto;
height: 100vh;
}
</style>
</head>
<body>
<img class="item" src="images/kitten1.png">
<img class="item" src="images/kitten2.png">
<img class="item" src="images/kitten3.png">
</body>
<script>
$(".item").click(function() {
$(this).toggleClass('scaled');
$(this).scrollIntoView();
});
</script>
</html>
Also I'd like to have the window view (by that I mean the location of the scrolling on the page) centered on the img whenever it is scaled. I am currently trying to use scrollIntoView for that purpose but nothing seems to happen.
Thank you in advance. First time posting here. I don't feel like this should be too difficult but will probably be on a different level than what I can figure out for now ଘ(੭ˊᵕˋ)੭ ̀ˋ
Also tried the following, but the img stay stuck at 90vw and 100vh ...
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<style>
img {
margin: auto;
display: block;
padding: 2%;
width: 90vw;
box-sizing: border-box;
object-fit: contain;
}
</style>
</head>
<body>
<img class="item" src="images/kitten1.png">
<img class="item" src="images/kitten2.png">
<img class="item" src="images/kitten3.png">
</body>
<script>
$(".item").click(function() {
if ($(this).hasClass('scaled')) {
$(this).animate({
height: "none",
width: "90vw"
}, 1000);
$(this).removeClass('scaled');
}
else {
$(this).animate({
width: "none",
height: "100vh"
}, 1000);
$(this).addClass('scaled');
}
});
</script></html>
To scroll to clicked item, use $(this)[0].scrollIntoView();
because .scrollIntoView()
is JavaScript function, not jQuery.
CSS does not support from auto width to specific width or the same to height transition. Reference: 1, 2
You can use max-height
or max-width
only. The good thing is you write less JavaScript and CSS responsive (media query) also supported without any addition. Bad thing is it just only support one side (width or height).
Full code:
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<style>
img {
margin: auto;
display: block;
padding: 2%;
max-width: 100vw;
box-sizing: border-box;
transition: all .3s;
}
.scaled {
max-width: 50vw;
}
</style>
</head>
<body>
<img class="item" src="images/kitten1.png">
<img class="item" src="images/kitten2.png">
<img class="item" src="images/kitten3.png">
</body>
<script>
$(".item").click(function() {
$(this).toggleClass('scaled');
$(this)[0].scrollIntoView({
behavior: "smooth"
});
});
</script>
</html>
The code below will be use a lot of JavaScript to make CSS transition work properly from width to height. Good thing: of cause support transition between width and height. Bad thing: CSS media query for responsive image will not work properly. Need more JS for that.
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<style>
img {
margin: auto;
display: block;
padding: 2%;
box-sizing: border-box;
transition: all .3s;
height: auto;
width: 90vw;
}
.scaled {
height: 100vh;
width: auto;
}
</style>
</head>
<body>
<img class="item" src="images/kitten1.png">
<img class="item" src="images/kitten2.png">
<img class="item" src="images/kitten3.png">
</body>
<script>
$(window).on("load", function() {
// wait until all images loaded.
// loop each <img> that has class `item` and set height.
$('img.item').each((index, item) => {
$(item).attr('data-original-height', $(item)[0].offsetHeight);
$(item).css({
'height': $(item)[0].offsetHeight
});
});
});
$(".item").click(function() {
if ($(this).hasClass('scaled')) {
// if already has class `scaled`
// going to remove that class after this.
if ($(this).attr('data-scaled-width') === undefined) {
// get and set original width to data attribute.
$(this).attr('data-scaled-width', $(this)[0].offsetWidth);
}
$(this).css({
'height': $(this).data('originalHeight'),
'width': ''
});
$(this).removeAttr('data-original-height');
$(this).removeClass('scaled');
} else {
// if going to add `scaled` class.
if ($(this).attr('data-original-height') === undefined) {
// get and set original height to data attribute.
$(this).attr('data-original-height', $(this)[0].offsetHeight);
}
$(this).css({
'height': '',
'width': $(this).data('scaledWidth')
});
$(this).removeAttr('data-scaled-width');
$(this).addClass('scaled');
// check again to make sure that width has been set.
if ($(this)[0].style.width === '') {
setTimeout(() => {
console.log($(this)[0].style.width);
$(this).css({
'width': $(this)[0].offsetWidth
});
console.log('css width for image was set after added class.');
}, 500);// set timeout more than transition duration in CSS.
}
}
$(this)[0].scrollIntoView({
behavior: "smooth"
});
});
</script>
</html>