├── .gitignore
├── .vscode
└── settings.json
├── assets
├── all-new-rpg.png
└── layers
│ ├── sky.png
│ ├── trees.png
│ ├── far-clouds.png
│ ├── mountains.png
│ ├── near-clouds.png
│ └── far-mountains.png
├── package.json
├── js
└── index.js
├── index.html
└── css
└── style.css
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "liveServer.settings.port": 5502
3 | }
--------------------------------------------------------------------------------
/assets/all-new-rpg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/all-new-rpg.png
--------------------------------------------------------------------------------
/assets/layers/sky.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/sky.png
--------------------------------------------------------------------------------
/assets/layers/trees.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/trees.png
--------------------------------------------------------------------------------
/assets/layers/far-clouds.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/far-clouds.png
--------------------------------------------------------------------------------
/assets/layers/mountains.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/mountains.png
--------------------------------------------------------------------------------
/assets/layers/near-clouds.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/near-clouds.png
--------------------------------------------------------------------------------
/assets/layers/far-mountains.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kibibit/parallax-hero-shot/main/assets/layers/far-mountains.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "parallax-auto",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "author": "",
9 | "license": "ISC",
10 | "description": ""
11 | }
12 |
--------------------------------------------------------------------------------
/js/index.js:
--------------------------------------------------------------------------------
1 | // Define the original widths of the images
2 | const imageSizes = {
3 | 'far-clouds': 128, // example size
4 | 'near-clouds': 144, // example size
5 | 'far-mountains': 160, // example size
6 | 'mountains': 320, // example size
7 | 'trees': 240 // example size
8 | };
9 |
10 | const height = 240;
11 |
12 | // Get the container (parallax element)
13 | const parallax = document.querySelector('.parallax');
14 |
15 | // Function to calculate the ratio and set CSS custom properties
16 | function calculateScrollRatios() {
17 | const containerWidth = parallax.offsetWidth; // Get the current container width
18 | const containerHeight = parallax.offsetHeight; // Get the current container height
19 |
20 | // Loop over each layer and calculate the ratio
21 | document.querySelectorAll('.layer').forEach(layer => {
22 | const layerClass = Array.from(layer.classList).find(cls => imageSizes[cls]);
23 | if (layerClass) {
24 | // calculate width of image based on container height
25 | const ratio = containerHeight / height;
26 | const actualImageWidth = imageSizes[layerClass] * ratio;
27 | // const imageWidth = imageSizes[layerClass]; // Get the corresponding image width
28 | // const ratio = imageWidth / containerWidth; // Calculate the ratio
29 | layer.style.setProperty('--scroll-width', `${ Math.floor(actualImageWidth) }px`);
30 | }
31 | });
32 | }
33 |
34 | // Call the function on page load and on window resize
35 | window.addEventListener('load', calculateScrollRatios);
36 | window.addEventListener('resize', calculateScrollRatios);
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | achievibit parallax demo
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |

41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100dvw;
3 | height: 100dvh;
4 | margin: 0;
5 | padding: 0;
6 | background-color: #212121;
7 | display: flex;
8 | justify-content: start;
9 | align-items: center;
10 | flex-direction: column;
11 | }
12 |
13 | *,
14 | *::before,
15 | *::after {
16 | box-sizing: border-box;
17 | }
18 |
19 | header {
20 | color: white;
21 | position: absolute;
22 | z-index: 10;
23 | top: 0;
24 | left: 0;
25 | width: 100%;
26 | height: 80px;
27 | display: flex;
28 | justify-content: space-between;
29 | flex-wrap: wrap;
30 | padding: 0 1em;
31 | font-size: 1rem;
32 | z-index: 1000;
33 | }
34 |
35 | header .logo {
36 | display: flex;
37 | align-items: center;
38 | height: 100%;
39 | font-family: "Comfortaa", sans-serif;
40 | font-optical-sizing: auto;
41 | font-weight: 400;
42 | font-style: normal;
43 | font-weight: 400;
44 | font-style: normal;
45 | gap: 0.5em;
46 | align-items: end;
47 | }
48 |
49 | header .logo h1 {
50 | font-family: "Righteous", sans-serif;
51 | font-weight: 400;
52 | font-style: normal;
53 | font-size: 2rem;
54 | margin: 0;
55 | text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
56 | }
57 |
58 | header .logo h3 {
59 | margin: 0;
60 | margin-bottom: 0.5em;
61 | font-size: 0.8em;
62 | text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
63 | }
64 |
65 | header .call-to-action {
66 | display: flex;
67 | align-items: center;
68 | height: 100%;
69 | margin-left: 80px;
70 | }
71 |
72 | header .call-to-action button {
73 | font-family: "Comfortaa", sans-serif;
74 | font-optical-sizing: auto;
75 | font-weight: 400;
76 | font-style: normal;
77 | font-weight: 400;
78 |
79 | font-family: "Press Start 2P", system-ui;
80 | font-weight: 400;
81 | font-style: normal;
82 | font-style: normal;
83 | font-size: 0.75em;
84 | background-color: rgba(220, 209, 233, 10%);
85 | color: white;
86 | border: none;
87 | padding: 1em;
88 | border-radius: 0.5em;
89 | cursor: pointer;
90 | transition: background-color 0.3s;
91 | }
92 |
93 | header .call-to-action button:hover {
94 | background-color: rgba(220, 209, 233, 20%);
95 | }
96 |
97 | header .logo img {
98 | height: 100%;
99 | padding: 0.6em 0.6em 0.6em 0;
100 | }
101 |
102 | .parallax {
103 | background-color: #46345D;
104 | background-image: url('../assets/layers/sky.png');
105 | image-rendering: pixelated;
106 | background-size: 100% auto;
107 | background-repeat: no-repeat;
108 | width: 100%;
109 | aspect-ratio: 16 / 7;
110 | max-height: 100%;
111 | position: relative;
112 | flex-shrink: 0;
113 |
114 | min-height: 80dvh;
115 | z-index: 500;
116 | box-shadow: rgba(0, 0, 0, 0.5) 0px 5px 10px;
117 | }
118 |
119 | .layer {
120 | --base-time: 20s;
121 | position: absolute;
122 | top: 0;
123 | left: 0;
124 | width: 100%;
125 | height: 100%;
126 | image-rendering: pixelated;
127 | /* set background size to match the height of the parallax container */
128 | background-size: auto 100%;
129 | /* repeat horizontally */
130 | background-repeat: repeat-x;
131 | pointer-events: none;
132 | }
133 |
134 | /* Pause animation on hover */
135 | /* .parallax:hover .layer {
136 | animation-play-state: paused !important;
137 | } */
138 |
139 | .parallax .layer.layer-1 {
140 | z-index: 1;
141 | animation: scroll calc(5 * var(--base-time)) linear infinite;
142 | }
143 |
144 | .parallax .layer.layer-2 {
145 | z-index: 2;
146 | animation: scroll calc(4 * var(--base-time)) linear infinite;
147 | }
148 |
149 | .parallax .layer.layer-3 {
150 | z-index: 3;
151 | animation: scroll calc(3 * var(--base-time)) linear infinite;
152 | }
153 |
154 | .parallax .layer.layer-4 {
155 | z-index: 4;
156 | animation: scroll calc(2 * var(--base-time)) linear infinite;
157 | }
158 |
159 | .parallax .layer.layer-5 {
160 | z-index: 5;
161 | animation: scroll calc(1 * var(--base-time)) linear infinite;
162 | }
163 |
164 | .parallax .layer.layer-6 {
165 | z-index: 6;
166 | }
167 |
168 | .far-clouds {
169 | --image-width: 128px;
170 | background-image: url('../assets/layers/far-clouds.png');
171 | }
172 |
173 | .near-clouds {
174 | --image-width: 144px;
175 | background-image: url('../assets/layers/near-clouds.png');
176 | }
177 |
178 | .far-mountains {
179 | --image-width: 160px;
180 | background-image: url('../assets/layers/far-mountains.png');
181 | }
182 |
183 | .mountains {
184 | --image-width: 320px;
185 | background-image: url('../assets/layers/mountains.png');
186 | }
187 |
188 | .trees {
189 | --image-width: 240px;
190 | background-image: url('../assets/layers/trees.png');
191 | }
192 |
193 | @keyframes scroll {
194 | 0% {
195 | background-position-x: 0;
196 | }
197 | 100% {
198 | background-position-x: calc(1 * var(--scroll-width));
199 | }
200 | }
201 |
202 | .rpg {
203 | width: 100%;
204 | background-color: #52865A;
205 | display: flex;
206 | flex-direction: column;
207 | align-items: center;
208 | }
209 |
210 | .rpg img {
211 | width: 100%;
212 | max-width: 1200px;
213 | image-rendering: pixelated;
214 | transform: translateY(-10px);
215 | }
--------------------------------------------------------------------------------