<section class="supt-section-images-innovation">
<div class="supt-section-images-innovation__inner">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8">
<div class="supt-section-images-innovation__images">
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_002_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_002_16x9.mp4" type="video/mp4">
</video>
</div>
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_003_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_003_16x9.mp4" type="video/mp4">
</video>
</div>
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_001_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_001_16x9.mp4" type="video/mp4">
</video>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
No notes defined.
<section class="supt-section-images-innovation">
<div class="supt-section-images-innovation__inner">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-8">
<div class="supt-section-images-innovation__images">
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_002_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_002_16x9.mp4" type="video/mp4">
</video>
</div>
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_003_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_003_16x9.mp4" type="video/mp4">
</video>
</div>
<div class="supt-section-images-innovation__image">
<video autoplay muted loop playsinline>
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_001_16x9.webm" type="video/webm">
<source src="/sites/gv/files/flmngr/superhuit/innovation/aquila_red_shot_001_16x9.mp4" type="video/mp4">
</video>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
/* No context defined. */
import { animate, onScroll } from 'animejs';
export class SectionImagesInnovation {
$element: HTMLElement;
$container: HTMLElement;
$imagesWrapper: HTMLElement;
$images: NodeListOf<HTMLImageElement>;
$imagesInner: NodeListOf<HTMLImageElement>;
imagesInitialScale: number = 0;
constructor($element: HTMLElement, $container: HTMLElement) {
this.$element = $element;
this.$container = $container;
this.$imagesWrapper = this.$element.querySelector(
'.supt-section-images-innovation__images'
) as HTMLElement;
this.$images = this.$element.querySelectorAll('.supt-section-images-innovation__image');
this.$imagesInner = this.$element.querySelectorAll(
'.supt-section-images-innovation__image video'
) as NodeListOf<HTMLImageElement>;
this.setImagesInitialSize();
this.setupScrollAnimation();
}
setImagesInitialSize() {
// Scale up images wrapper to cover full viewport (100vw x 100vh)
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const imageHeight = this.$images[0].clientHeight;
const imageWidth = this.$images[0].clientWidth;
// Calculate scale needed to cover both width and height
const scaleX = viewportWidth / imageWidth;
const scaleY = viewportHeight / imageHeight;
// Use the larger scale to ensure full coverage
this.imagesInitialScale = Math.max(scaleX, scaleY);
// Apply scale transform
this.$imagesWrapper.style.transform = `scale(${this.imagesInitialScale})`;
}
setupScrollAnimation() {
// Update container background on scroll
const $darkBackground = this.$container.querySelector(
'.supt-innovation-overview-page__background.-dark'
) as HTMLElement;
animate($darkBackground, {
opacity: [0, 1],
autoplay: onScroll({
container: document.body,
target: this.$element,
enter: 'bottom top',
leave: 'center top',
sync: true,
}),
});
// Zoom out images
animate(this.$imagesWrapper, {
scale: [this.imagesInitialScale, 1],
y: ['0%', '10%', '0%'],
autoplay: onScroll({
container: document.body,
target: this.$element,
enter: 'top top',
leave: 'top 40%',
sync: true,
}),
});
// Add parallax effect to images, so they completely scroll out and disappear
this.$images.forEach(($image, index) => {
const parallaxOffset = (index + 1) * 15; // Each image moves with increasing speed
const yMovement = `${-parallaxOffset}%`; // Move up enough to completely exit viewport
animate($image, {
y: ['0%', yMovement],
autoplay: onScroll({
container: document.body,
target: this.$element,
enter: 'top 40%',
leave: 'top bottom',
sync: true,
}),
});
});
// Add inner parallax effect to images, to have a moving effect
animate(this.$imagesInner, {
scale: [1.4, 1],
y: ['-20%', 0],
ease: 'linear',
autoplay: onScroll({
container: document.body,
target: this.$element,
enter: 'bottom top',
leave: 'top bottom',
sync: true,
}),
});
}
}
.supt-section-images-innovation {
height: 200vh;
&__inner {
position: sticky;
top: 0;
overflow: hidden;
}
&__images {
display: flex;
flex-direction: column;
gap: $spacing-12;
transform-origin: top center;
}
&__image {
overflow: hidden;
img,
video {
aspect-ratio: 1037/584;
width: 100%;
height: 100%;
object-fit: cover;
}
}
}