forked from facebook/react-native-website
-
Notifications
You must be signed in to change notification settings - Fork 328
/
_dissectionAnimation.js
52 lines (43 loc) · 1.73 KB
/
_dissectionAnimation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
* Copyright (c) Meta Platforms, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export function setupDissectionAnimation() {
const section = document.querySelector('.NativeDevelopment');
const dissection = document.querySelector('.NativeDevelopment .dissection');
const images = dissection.children;
const numImages = images.length;
const fadeDistance = 40;
const navbarHeight = 60;
function clamp(val, min, max) {
return Math.min(max, Math.max(min, val));
}
// Scale the percent so that `min` goes to 0% and `max` goes to 100%
function scalePercent(percent, min, max) {
const scale = max - min;
return clamp((percent - min) / scale, 0, 1);
}
// Get the percentage that the image should be on the screen given
// how much the entire container is scrolled
// so we can fine-tune at what screen % the animation starts and stops
function getImagePercent(index, scrollPercent) {
const start = index / numImages;
return clamp((scrollPercent - start) * numImages, 0, 1);
}
function onScroll() {
const elPos = section.getBoundingClientRect().top - navbarHeight;
const height = window.innerHeight;
const screenPercent = 1 - clamp(elPos / height, 0, 1);
const scaledPercent = scalePercent(screenPercent, 0.2, 0.9);
for (let i = 0; i < numImages; i++) {
const imgPercent = getImagePercent(i, scaledPercent);
images[i].style.opacity = imgPercent;
const translation = fadeDistance * (1 - imgPercent);
images[i].style.left = `${translation}px`;
}
}
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}