I want on scroll down, that the images are moving up a bit, like on this website:
example site (digital does)
Down the website on digitaldoes you can see what i mean. The images are moving up a bit if you scroll down. Is it maby a lazy-load with images that are fading in or an animation where the images moving for example 5px up?
Here is a: jsfiddle updated!!!
$(document).ready(function () {
$(".img-scroll").css("display", "none");
$(window).scroll(function() {
$( ".img-scroll" ).addClass("animate");
$( ".img-scroll" ).css("display", "block");
console.log("Hey");
});
});
.img-scroll {
-moz-transition: top 10s;
transition: top 10s;
}
.img-scroll.animate {
top: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
</header>
</div>
<div id="links">
<div class="row">
<div class="col-xxl-1"></div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5">
<div class="card shadow-sm first-image">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #1">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #1</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5">
<div class="card shadow-sm">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #2">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #2" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #2</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
<div class="col-12 col-md-6 col-lg-4 col-xxl-5 img-scroll">
<div class="card shadow-sm first-image">
<a href="https://www.fillmurray.com/1000/1000" title="Test - Logo #3">
<img src="https://www.fillmurray.com/300/150" alt="Test - Logo #3" class="card-img-top logo-hover">
</a>
<div class="card-body">
<p class="card-text">Test - Logo #3</p>
<div class="d-flex justify-content-between align-items-center"></div>
</div>
</div>
</div>
<div class="col-xxl-1"></div>
<div class="col-xxl-1"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script>
I hope, someone can help me...
The most important step is to check if an <img>
element is entering the current viewport.
We can use the Intersection Observer API.
const options = {
rootMargin: "0px",
threshold: 0.5
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let dataSrc = target.getAttribute('data-src');
target.src = dataSrc;
target.classList.replace('lazyload', 'lazyloaded');
}
});
}, options);
By adjusting the threshold value we can define when the intersecting value returns true:
E.g treshold:0.5
=> element is intersection if 50% of it's height is in viewport.
Now we can define a callback:
if(entry.isIntersecting){}
If element is in viewport – set the src
attribute from data-src
and toggle css classes from 'lazyload' to 'lazyloaded'.
Most lazyload libraries use a similar syntax or api concept like this:
<img data-src="https://www.fillmurray.com/480/480" class="lazyload">
The actual image src/URL is defined by a data attribute: data-src
.
Lazy loading can significantly improve the overall performance and user experience by loading images only if they are really required.
The animation is done by toggling between css classes:
E.g .lazyload
(not loaded yet) and lazyloaded
(loaded)
.lazyload {
opacity: 0;
transform: translateY(100%);
}
.lazyloaded {
opacity: 1;
transform: translateY(0%);
}
const options = {
rootMargin: "0px",
threshold: 0.5
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let dataSrc = target.getAttribute('data-src');
target.src = dataSrc;
target.classList.replace('lazyload', 'lazyloaded');
}
});
}, options);
const images = document.querySelectorAll('.lazyload');
images.forEach(function(img, i) {
inViewPortObserver.observe(img);
})
* {
box-sizing: border-box
}
header {
margin-bottom: 40vmin;
}
main {
padding-bottom: 50em;
}
section {
margin-bottom: 20em;
}
.row {
display: flex;
}
.row>* {
flex: 1;
}
.card-img-top {
transition: 2s;
}
.lazyload {
opacity: 0;
transform: translateY(100%);
}
.lazyloaded {
opacity: 1;
transform: translateY(0%);
}
img {
aspect-ratio: 2/1;
display: block;
background-color: #ccc;
width: 100%;
max-width: 100%;
object-fit: cover;
object-position: 50% 50%;
}
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
<p>Please scroll down …</p>
</header>
</div>
<main>
<section>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/480/480" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/300/200" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/200/300" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/400/240" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
</section>
<section>
<div class="row">
<figure>
<img data-src="https://www.fillmurray.com/320/240" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/300/150" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/333/111" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
<figure>
<img data-src="https://www.fillmurray.com/444/333" alt="Test - Logo #1" class="lazyload card-img-top logo-hover">
</figure>
</div>
</section>
</main>
The main difference: we're observing viewport intersections for parent elements like the .card
class.
const options = {
rootMargin: "0px",
threshold: 0.1
};
const inViewPortObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let target = entry.target;
let img = target.querySelector('img');
let dataSrc = img.getAttribute('data-src');
img.src = dataSrc;
target.classList.add('inViewPort');
}
});
}, options);
const cards = document.querySelectorAll('.card');
cards.forEach(function(card, i) {
inViewPortObserver.observe(card);
})
* {
box-sizing: border-box
}
header {
margin-bottom: 60vmin;
}
main {
padding-bottom: 50em;
}
section {
margin-bottom: 20em;
}
.row {
display: flex;
gap: 1em;
}
.row>* {
flex: 1;
}
.card {
transition: 2s;
transform: translateY(100%);
border: 2px solid red;
opacity: 0;
}
/** optional sibling delay */
.row .card:nth-of-type(2) {
transition-delay: 0.5s;
}
.row .card:nth-of-type(3) {
transition-delay: 0.75s;
}
.row .card:nth-of-type(4) {
transition-delay: 1s;
}
.row .card:nth-of-type(5) {
transition-delay: 1.25s;
}
.row .card:nth-of-type(6) {
transition-delay: 1.5s;
}
.inViewPort {
opacity: 1;
transform: translateY(0%);
}
img {
aspect-ratio: 2/1;
display: block;
background-color: #ccc;
width: 100%;
max-width: 100%;
object-fit: cover;
object-position: 50% 50%;
}
<div class="row">
<header class="arbeiten">
<h2>{ Logos }</h2>
<p>Please scroll down …</p>
</header>
</div>
<main>
<section>
<div class="row row1">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/480/480" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/150" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/222" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/247" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>
<section>
<div class="row row2">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/320/240" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/111" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/112" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>
<section>
<div class="row row2">
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/320/240" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/111" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
<div class="card">
<a href="#">
<img data-src="https://www.fillmurray.com/300/112" alt="" class="lazyload card-img-top logo-hover">
</a>
</div>
</div>
</section>