├── README.md
├── index.html
├── script.js
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | # parallax-scroll-animation
2 |
3 | # Technologies used
4 |
5 | * HTML
6 | * CSS
7 | * JavaScript
8 |
9 | ## Live website can be viewed here
10 |
11 | https://peter-kimanzi.github.io/parallax-scroll-animation/
12 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Parallax scroll animation
6 |
7 |
8 |
9 |
10 |
11 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | gsap.registerPlugin(ScrollTrigger);
2 | let speed = 100;
3 |
4 | /* SCENE 1 */
5 | let scene1 = gsap.timeline();
6 | ScrollTrigger.create({
7 | animation: scene1,
8 | trigger: ".scrollElement",
9 | start: "top top",
10 | end: "45% 100%",
11 | scrub: 3,
12 | });
13 |
14 | // hills animation
15 | scene1.to("#h1-1", { y: 3 * speed, x: 1 * speed, scale: 0.9, ease: "power1.in" }, 0)
16 | scene1.to("#h1-2", { y: 2.6 * speed, x: -0.6 * speed, ease: "power1.in" }, 0)
17 | scene1.to("#h1-3", { y: 1.7 * speed, x: 1.2 * speed }, 0.03)
18 | scene1.to("#h1-4", { y: 3 * speed, x: 1 * speed }, 0.03)
19 | scene1.to("#h1-5", { y: 2 * speed, x: 1 * speed }, 0.03)
20 | scene1.to("#h1-6", { y: 2.3 * speed, x: -2.5 * speed }, 0)
21 | scene1.to("#h1-7", { y: 5 * speed, x: 1.6 * speed }, 0)
22 | scene1.to("#h1-8", { y: 3.5 * speed, x: 0.2 * speed }, 0)
23 | scene1.to("#h1-9", { y: 3.5 * speed, x: -0.2 * speed }, 0)
24 |
25 | //animate text
26 | scene1.to("#info", { y: 8 * speed }, 0)
27 |
28 |
29 |
30 | /* Bird */
31 | gsap.fromTo("#bird", { opacity: 1 }, {
32 | y: -250,
33 | x: 800,
34 | ease: "power2.out",
35 | scrollTrigger: {
36 | trigger: ".scrollElement",
37 | start: "15% top",
38 | end: "60% 100%",
39 | scrub: 4,
40 | onEnter: function() { gsap.to("#bird", { scaleX: 1, rotation: 0 }) },
41 | onLeave: function() { gsap.to("#bird", { scaleX: -1, rotation: -15 }) },
42 | }
43 | })
44 |
45 |
46 | /* Clouds */
47 | let clouds = gsap.timeline();
48 | ScrollTrigger.create({
49 | animation: clouds,
50 | trigger: ".scrollElement",
51 | start: "top top",
52 | end: "70% 100%",
53 | scrub: 1,
54 | });
55 |
56 | clouds.to("#cloud1", { x: 500 }, 0)
57 | clouds.to("#cloud2", { x: 1000 }, 0)
58 | clouds.to("#cloud3", { x: -1000 }, 0)
59 | clouds.to("#cloud4", { x: -700, y: 25 }, 0)
60 |
61 |
62 |
63 | /* Sun motion Animation */
64 | let sun = gsap.timeline();
65 | ScrollTrigger.create({
66 | animation: sun,
67 | trigger: ".scrollElement",
68 | start: "top top",
69 | end: "2200 100%",
70 | scrub: 1,
71 | });
72 |
73 | //sun motion
74 | sun.to("#bg_grad", { attr: { cy: "330" } }, 0.00)
75 |
76 | //bg change
77 | sun.to("#sun", { attr: { offset: "0.15" } }, 0.00)
78 | sun.to("#bg_grad stop:nth-child(2)", { attr: { offset: "0.15" } }, 0.00)
79 | sun.to("#bg_grad stop:nth-child(3)", { attr: { offset: "0.18" } }, 0.00)
80 | sun.to("#bg_grad stop:nth-child(4)", { attr: { offset: "0.25" } }, 0.00)
81 | sun.to("#bg_grad stop:nth-child(5)", { attr: { offset: "0.46" } }, 0.00)
82 | sun.to("#bg_grad stop:nth-child(6)", { attr: { "stop-color": "#FF9171" } }, 0)
83 |
84 |
85 |
86 | /* SCENE 2 */
87 | let scene2 = gsap.timeline();
88 | ScrollTrigger.create({
89 | animation: scene2,
90 | trigger: ".scrollElement",
91 | start: "15% top",
92 | end: "40% 100%",
93 | scrub: 4,
94 | });
95 |
96 | scene2.fromTo("#h2-1", { y: 500, opacity: 0 }, { y: 0, opacity: 1 }, 0)
97 | scene2.fromTo("#h2-2", { y: 500 }, { y: 0 }, 0.1)
98 | scene2.fromTo("#h2-3", { y: 700 }, { y: 0 }, 0.1)
99 | scene2.fromTo("#h2-4", { y: 700 }, { y: 0 }, 0.2)
100 | scene2.fromTo("#h2-5", { y: 800 }, { y: 0 }, 0.3)
101 | scene2.fromTo("#h2-6", { y: 900 }, { y: 0 }, 0.3)
102 |
103 |
104 |
105 | /* Bats */
106 | gsap.fromTo("#bats", { opacity: 1, y: 400, scale: 0 }, {
107 | y: 120,
108 | scale: 0.8,
109 | transformOrigin: "50% 50%",
110 | ease: "power3.out",
111 | scrollTrigger: {
112 | trigger: ".scrollElement",
113 | start: "40% top",
114 | end: "70% 100%",
115 | scrub: 3,
116 | onEnter: function() {
117 | gsap.utils.toArray("#bats path").forEach((item, i) => {
118 | gsap.to(item, { scaleX: 0.5, yoyo: true, repeat: 11, duration: 0.15, delay: 0.7 + (i / 10), transformOrigin: "50% 50%" })
119 | });
120 | gsap.set("#bats", { opacity: 1 })
121 | },
122 | onLeave: function() { gsap.to("#bats", { opacity: 0, delay: 2 }) },
123 | }
124 | })
125 |
126 |
127 | /* Sun increase */
128 | let sun2 = gsap.timeline();
129 | ScrollTrigger.create({
130 | animation: sun2,
131 | trigger: ".scrollElement",
132 | start: "2200 top",
133 | end: "5000 100%",
134 | scrub: 1,
135 | });
136 |
137 | sun2.to("#sun", { attr: { offset: "0.6" } }, 0)
138 | sun2.to("#bg_grad stop:nth-child(2)", { attr: { offset: "0.7" } }, 0)
139 | sun2.to("#sun", { attr: { "stop-color": "#ffff00" } }, 0)
140 | sun2.to("#lg4 stop:nth-child(1)", { attr: { "stop-color": "#623951" } }, 0)
141 | sun2.to("#lg4 stop:nth-child(2)", { attr: { "stop-color": "#261F36" } }, 0)
142 | sun2.to("#bg_grad stop:nth-child(6)", { attr: { "stop-color": "#45224A" } }, 0)
143 |
144 |
145 |
146 | /* Transition (from Scene2 to Scene3) */
147 | gsap.set("#scene3", { y: 580, visibility: "visible" })
148 | let sceneTransition = gsap.timeline();
149 | ScrollTrigger.create({
150 | animation: sceneTransition,
151 | trigger: ".scrollElement",
152 | start: "70% top",
153 | end: "bottom 100%",
154 | scrub: 3,
155 | });
156 |
157 | sceneTransition.to("#h2-1", { y: -680, scale: 1.5, transformOrigin: "50% 50%" }, 0)
158 | sceneTransition.to("#bg_grad", { attr: { cy: "-80" } }, 0.00)
159 | sceneTransition.to("#bg2", { y: 0 }, 0)
160 |
161 |
162 |
163 | /* Scene 3 */
164 | let scene3 = gsap.timeline();
165 | ScrollTrigger.create({
166 | animation: scene3,
167 | trigger: ".scrollElement",
168 | start: "80% 50%",
169 | end: "bottom 100%",
170 | scrub: 3,
171 | });
172 |
173 | //Hills motion
174 | scene3.fromTo("#h3-1", { y: 300 }, { y: -550 }, 0)
175 | scene3.fromTo("#h3-2", { y: 800 }, { y: -550 }, 0.03)
176 | scene3.fromTo("#h3-3", { y: 600 }, { y: -550 }, 0.06)
177 | scene3.fromTo("#h3-4", { y: 800 }, { y: -550 }, 0.09)
178 | scene3.fromTo("#h3-5", { y: 1000 }, { y: -550 }, 0.12)
179 |
180 | //stars
181 | scene3.fromTo("#stars", { opacity: 0 }, { opacity: 0.5, y: -500 }, 0)
182 |
183 | // Scroll Back text
184 | scene3.fromTo("#arrow2", { opacity: 0 }, { opacity: 0.7, y: -710 }, 0.25)
185 | scene3.fromTo("#text2", { opacity: 0 }, { opacity: 0.7, y: -710 }, 0.3)
186 |
187 | //gradient value change
188 | scene3.to("#bg2-grad", { attr: { cy: 600 } }, 0)
189 | scene3.to("#bg2-grad", { attr: { r: 500 } }, 0)
190 |
191 |
192 | /* falling star */
193 | gsap.to("#fstar", {
194 | x: -700,
195 | y: -250,
196 | ease: "power4.out",
197 | scrollTrigger: {
198 | trigger: ".scrollElement",
199 | start: "4000 top",
200 | end: "6000 100%",
201 | scrub: 5,
202 | onEnter: function() { gsap.set("#fstar", { opacity: 1 }) },
203 | onLeave: function() { gsap.set("#fstar", { opacity: 0 }) },
204 | }
205 | })
206 |
207 |
208 | //reset scrollbar position after refresh
209 | window.onbeforeunload = function() {
210 | window.scrollTo(0, 0);
211 | }
212 |
213 |
214 | let fullscreen;
215 | let fsEnter = document.getElementById('fullscr');
216 | fsEnter.addEventListener('click', function (e) {
217 | e.preventDefault();
218 | if (!fullscreen) {
219 | fullscreen = true;
220 | document.documentElement.requestFullscreen();
221 | fsEnter.innerHTML = "Exit Fullscreen";
222 | }
223 | else {
224 | fullscreen = false;
225 | document.exitFullscreen();
226 | fsEnter.innerHTML = "Go Fullscreen";
227 | }
228 | });
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | body,
2 | html{
3 | margin: 0;
4 | padding: 0;
5 | height: 100%;
6 | }
7 |
8 | /* Hide scrollbar for Chrome, Safari and Opera */
9 | body::-webkit-scrollbar {
10 | display: none;
11 | }
12 |
13 | /* Hide scrollbar for IE, Edge and Firefox */
14 | body {
15 | -ms-overflow-style: none; /* IE and Edge */
16 | scrollbar-width: none; /* Firefox */
17 | }
18 |
19 | svg {
20 | display: block;
21 | width: 100%;
22 | height: 100vh;
23 | position: fixed;
24 | top: 0;
25 | left: 0;
26 | }
27 |
28 | .scrollElement {
29 | position: absolute;
30 | height: 6000px;
31 | width: 100px;
32 | top: 0;
33 | z-index: 0;
34 | }
35 |
36 | .btn {
37 | position: fixed;
38 | bottom: 5%;
39 | right: 0px;
40 | transform: translateX(-50%);
41 | border: 1px solid #fff;
42 | border-radius: 5px;
43 | font-size: 0.9rem;
44 | padding: 0.5rem 0.7em;
45 | background-color: transparent;
46 | color: #ffffff;
47 | font-family: Verdana, Geneva, Tahoma, sans-serif;
48 | -webkit-font-smoothing: antialiased;
49 | cursor: pointer;
50 | transition: all .3s;
51 | z-index: 11;
52 | }
53 |
54 | .btn_works {
55 | left: 100px;
56 | right: unset;
57 | text-decoration: none;
58 | }
59 |
60 | .btn:hover {
61 | background: #ffffff;
62 | color: #1B1734;
63 | }
--------------------------------------------------------------------------------