-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscrollifyReveal.js
More file actions
82 lines (69 loc) · 3.8 KB
/
scrollifyReveal.js
File metadata and controls
82 lines (69 loc) · 3.8 KB
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class ScrollifyReveal {
constructor() {
// Default options for scrolling animations
this.defaultOptions = {
delay: 0, // Deadline before start of animation
distance: '0px', // Vertical travel distance
duration: '500ms', // Animation duration
easing: 'cubic-bezier(0.5, 0, 0, 1)', // Timer function (speed curve)
zoom: 0.8, // Zoom on appear
hideOnExit: true, // Enable or disable disappearance when out of view
opacity: 1, // Final opacity
};
}
reveal(selector, options) {
// Selects all items corresponding to the selector
const elements = document.querySelectorAll(selector);
// Merges default options with supplied options
options = { ...this.defaultOptions, ...options };
// Creates an intersection observer to detect the visibility of elements
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const target = entry.target;
// Checks if the item has not already been revealed
if (!target.classList.contains('revealed')) {
setTimeout(() => {
// Applies appearance animation
target.style.opacity = `${options.opacity}`;
target.style.transform = 'scale(1)';
target.style.transition = `opacity ${options.duration} ${options.easing}, transform ${options.duration} ${options.easing}`;
target.style.transitionDelay = `${options.delay}ms, ${options.delay}ms`;
// Marks element as revealed
target.classList.add('revealed');
// Add a transitionend event listener to remove the scale transform
target.addEventListener('transitionend', () => {
target.style.transform = '';
target.style.transition = '';
target.style.transitionDelay = '';
}, { once: true });
}, options.delay);
}
} else if (options.hideOnExit) {
const target = entry.target;
// Checks if the item has been previously revealed
if (target.classList.contains('revealed')) {
// Applies disappearing animation
target.style.opacity = '0';
// Defines the transformation according to options.zoom
target.style.transform = `translateY(${options.distance}) scale(${options.zoom})`;
target.style.transition = `opacity ${options.duration} ${options.easing}, transform ${options.duration} ${options.easing}`;
target.style.transitionDelay = '0s, 0s';
// Marks element as not revealed
target.classList.remove('revealed');
}
}
});
});
// Initialize styles and observer for each element
elements.forEach(element => {
element.style.opacity = '0';
element.style.transform = `translateY(${options.distance}) scale(${options.zoom})`;
element.style.transition = `opacity ${options.duration} ${options.easing}, transform ${options.duration} ${options.easing}`;
element.style.transitionDelay = '0s, 0s';
// Observe element for visibility changes
observer.observe(element);
});
}
}
const scrollifyReveal = new ScrollifyReveal();