├── .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 |
20 | 27 |
28 | 29 |
30 |
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 | } --------------------------------------------------------------------------------