├── .gitignore
├── .npmignore
├── .nvmrc
├── LICENSE
├── README.md
├── examples
├── assets
│ ├── images
│ │ ├── layer1.png
│ │ ├── layer2.png
│ │ ├── layer3.png
│ │ ├── layer4.png
│ │ ├── layer5.png
│ │ └── layer6.png
│ └── styles.scss
└── pages
│ ├── callback.html
│ ├── destroy.html
│ ├── hoveronly.html
│ ├── input_element.html
│ ├── interactive.html
│ ├── relative.html
│ ├── selector.html
│ ├── separate_axis_data.html
│ └── simple.html
├── gulpfile.js
├── logo.png
├── package-lock.json
├── package.json
└── src
└── parallax.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 | node_modules
3 | dist
4 | **/*.css
5 | npm-debug.log
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | examples
2 | logo.png
3 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 8
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | //============================================================
2 | //
3 | // The MIT License
4 | //
5 | // Copyright (C) 2014 Matthew Wagerfield - @wagerfield
6 | //
7 | // Permission is hereby granted, free of charge, to any
8 | // person obtaining a copy of this software and associated
9 | // documentation files (the "Software"), to deal in the
10 | // Software without restriction, including without limitation
11 | // the rights to use, copy, modify, merge, publish, distribute,
12 | // sublicense, and/or sell copies of the Software, and to
13 | // permit persons to whom the Software is furnished to do
14 | // so, subject to the following conditions:
15 | //
16 | // The above copyright notice and this permission notice
17 | // shall be included in all copies or substantial portions
18 | // of the Software.
19 | //
20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
21 | // OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
24 | // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
25 | // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 | // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
28 | // OR OTHER DEALINGS IN THE SOFTWARE.
29 | //
30 | //============================================================
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://cdnjs.com/libraries/parallax)
4 |
5 | Parallax Engine that reacts to the orientation of a smart device. Where no gyroscope or motion detection hardware is available, the position of the cursor is used instead.
6 |
7 | Check out the **[demo](https://matthew.wagerfield.com/parallax/)** to see it in action!
8 |
9 | # Table of Contents
10 |
11 | - [1. Getting started](#1-getting-started)
12 | - [1.1 Installation](#11-installation)
13 | - [1.2 Preparations](#12-preparations)
14 | - [1.3 Run Parallax](#13-run-parallax)
15 | - [2. Configuration](#2-configuration)
16 | - [2.1 Programmatic vs Declarative](#21-programmatic-vs-declarative)
17 | - [2.2 Configuration Options](#22-configuration-options)
18 | - [3. Methods](#3-methods)
19 | - [4. Development](#4-development)
20 | - [4.1 Running the Project](#41-running-the-project)
21 | - [4.2 Opening an Issue](#42-opening-an-issue)
22 | - [4.3 Known Issues](#43-known-issues)
23 | - [5. FAQ](#5-faq)
24 | - [6. Information](#6-information)
25 | - [6.1 License](#61-license)
26 | - [6.2 Contributors](#62-authors)
27 |
28 | # 1. Getting started
29 |
30 | ## 1.1 Installation
31 |
32 | ### 1.1 a) Using the CDN
33 |
34 | 1. Add `` to your markup
35 | 2. Done!
36 |
37 | Many thanks to the fine folks over at [cdnjs](https://cdnjs.com/) for hosting our library.
38 |
39 | ### 1.1 b) Beginners
40 |
41 | 1. Head over to the [releases](https://github.com/wagerfield/parallax/releases) Section
42 | 2. Download `compiled.zip` from the latest release
43 | 3. Extract the ZIP archive and locate the `parallax.js` and `parallax.min.js` files
44 | - Use `parallax.js` if you want to snoop around in the code
45 | - Use `parallax.min.js` for deployment, because it has a smaller file size
46 | 4. Copy the file of your choice into your project directory
47 | 5. So far, so good!
48 |
49 | ### 1.1 c) Professionals
50 |
51 | `npm i -s parallax-js`
52 |
53 | You will then find the source code in `node_modules/parallax-js/src/parallax.js` and the browserified, babelified, uglified, production-ready version in `node_modules/parallax-js/dist/parallax.min.js`
54 |
55 | ## 1.2 Preparations
56 |
57 | ### Include the Script
58 |
59 | If you use the compiled version, either downloaded from the releases page, or copied from the `dist` folder, include the script like any other Javascript library:
60 | ``
61 |
62 | Of course, when you've installed via npm, and use browserify/babel, you can also simply do:
63 | `import Parallax from 'parallax-js'` or
64 | `const Parallax = require('parallax-js')`
65 |
66 | ### Create your HTML elements
67 |
68 | Each Parallax.js instance needs a container element, the scene. You're free to identify it by any means you want, but for now, let's use an ID:
69 |
70 | ```html
71 |
72 |
73 | ```
74 |
75 | Per default, all direct child elements of the scene will become moving objects, the layers. You can change this to a custom query selector, but again, we're going with the easiest approach for now:
76 |
77 | ```html
78 |
79 |
My first Layer!
80 |
My second Layer!
81 |
82 | ```
83 |
84 | While all other options and parameters are optional, with sane defaults, and can be set programatically, each layer needs a `data-depth` attribute. The movement applied to each layer will be multiplied by its depth attribute.
85 |
86 | ```html
87 |
88 |
My first Layer!
89 |
My second Layer!
90 |
91 | ```
92 |
93 | ## 1.3 Run Parallax
94 |
95 | As soon as your DOM is ready and loaded, you can create a new Parallax.js instance, providing your scene element as first parameter.
96 |
97 | ```javascript
98 | var scene = document.getElementById('scene');
99 | var parallaxInstance = new Parallax(scene);
100 | ```
101 |
102 | That's it, you're running Parallax.js now!
103 |
104 | # 2. Configuration
105 |
106 | ## 2.1 Programmatic vs Declarative
107 |
108 | Most configuration settings can be declared either as data-value attribute of the scene element, or property of the configuration object. The programmatic approach will take priority over the data-value attributes set in the HTML.
109 | Some options can also be set at run-time via instance methods.
110 |
111 | Declarative:
112 |
113 | ```html
114 |
115 |
My first Layer!
116 |
My second Layer!
117 |
118 | ```
119 |
120 | Programmatic:
121 |
122 | ```javascript
123 | var scene = document.getElementById('scene');
124 | var parallaxInstance = new Parallax(scene, {
125 | relativeInput: true
126 | });
127 | ```
128 |
129 | Using Methods at Runtime:
130 |
131 | ```javascript
132 | parallaxInstance.friction(0.2, 0.2);
133 | ```
134 |
135 | ## 2.2 Configuration Options
136 |
137 | ### relativeInput
138 |
139 | Property: **relativeInput**
140 | Attribute: **data-relative-input**
141 |
142 | Value: *boolean*
143 | Default: *false*
144 |
145 | Makes mouse input relative to the position of the scene element.
146 | No effect when gyroscope is used.
147 |
148 | ### clipRelativeInput
149 |
150 | Property: **clipRelativeInput**
151 | Attribute: **data-clip-relative-input**
152 |
153 | Value: *boolean*
154 | Default: *false*
155 |
156 | Clips mouse input to the bounds of the scene. This means the movement stops as soon as the edge of the scene element is reached by the cursor.
157 | No effect when gyroscope is used, or `hoverOnly` is active.
158 |
159 | ### hoverOnly
160 |
161 | Property: **hoverOnly**
162 | Attribute: **data-hover-only**
163 |
164 | Value: *boolean*
165 | Default: *false*
166 |
167 | Parallax will only be in effect while the cursor is over the scene element, otherwise all layers move back to their initial position. Works best in combination with `relativeInput`.
168 | No effect when gyroscope is used.
169 |
170 | ### inputElement
171 |
172 | Property: **inputElement**
173 | Attribute: **data-input-element**
174 | Method: **setInputElement(HTMLElement)**
175 |
176 | Value: *null* or *HTMLElement* / *String*
177 | Default: *null*
178 |
179 | Allows usage of a different element for cursor input.
180 | The configuration property expects an HTMLElement, the data value attribute a query selector string.
181 | Will only work in combination with `relativeInput`, setting `hoverOnly` might make sense too.
182 | No effect when gyroscope is used.
183 |
184 | ### calibrateX & calibrateY
185 |
186 | Property: **calibrateX** & **calibrateY**
187 | Attribute: **data-calibrate-x** & **data-calibrate-y**
188 | Method: **calibrate(x, y)**
189 |
190 | Value: *boolean*
191 | Default: *false* for X, *true* for Y
192 |
193 | Caches the initial X/Y axis value on initialization and calculates motion relative to this.
194 | No effect when cursor is used.
195 |
196 | ### invertX & invertY
197 |
198 | Property: **invertX** & **invertY**
199 | Attribute: **data-invert-x** & **data-invert-y**
200 | Method: **invert(x, y)**
201 |
202 | Value: *boolean*
203 | Default: *true*
204 |
205 | Inverts the movement of the layers relative to the input. Setting both of these values to *false* will cause the layers to move with the device motion or cursor.
206 |
207 | ### limitX & limitY
208 |
209 | Property: **limitX** & **limitY**
210 | Attribute: **data-limit-x** & **data-limit-y**
211 | Method: **limit(x, y)**
212 |
213 | Value: *false* or *integer*
214 | Default: *false*
215 |
216 | Limits the movement of layers on the respective axis. Leaving this value at false gives complete freedom to the movement.
217 |
218 | ### scalarX & scalarY
219 |
220 | Property: **scalarX** & **scalarY**
221 | Attribute: **data-scalar-x** & **data-scalar-y**
222 | Method: **scalar(x, y)**
223 |
224 | Value: *float*
225 | Default: *10.0*
226 |
227 | Multiplies the input motion by this value, increasing or decreasing the movement speed and range.
228 |
229 | ### frictionX & frictionY
230 |
231 | Property: **frictionX** & **frictionY**
232 | Attribute: **data-friction-x** & **data-friction-y**
233 | Method: **friction(x, y)**
234 |
235 | Value: *float* between *0* and *1*
236 | Default: *0.1*
237 |
238 | Amount of friction applied to the layers. At *1* the layers will instantly go to their new positions, everything below 1 adds some easing.
239 | The default value of *0.1* adds some sensible easing. Try *0.15* or *0.075* for some difference.
240 |
241 | ### originX & originY
242 |
243 | Property: **originX** & **originY**
244 | Attribute: **data-origin-x** & **data-origin-y**
245 | Method: **origin(x, y)**
246 |
247 | Value: *float* between *0* and *1*
248 | Default: *0.5*
249 |
250 | X and Y origin of the mouse input. The default of *0.5* refers to the center of the screen or element, *0* is the left (X axis) or top (Y axis) border, 1 the right or bottom.
251 | No effect when gyroscope is used.
252 |
253 | ### precision
254 |
255 | Property: **precision**
256 | Attribute: **data-precision**
257 |
258 | Value: *integer*
259 | Default: *1*
260 |
261 | Decimals the element positions will be rounded to. *1* is a sensible default which you should not need to change in the next few years, unless you have a very interesting and unique setup.
262 |
263 | ### selector
264 |
265 | Property: **selector**
266 | Attribute: **data-selector**
267 |
268 | Value: *null* or *string*
269 | Default: *null*
270 |
271 | String that will be fed to querySelectorAll on the scene element to select the layer elements. When *null*, will simply select all direct child elements.
272 | Use `.layer` for legacy behaviour, selecting only child elements having the class name *layer*.
273 |
274 | ### pointerEvents
275 |
276 | Property: **pointerEvents**
277 | Attribute: **data-pointer-events**
278 |
279 | Value: *boolean*
280 | Default: *false*
281 |
282 | Set to *true* to enable interactions with the scene and layer elements. When set to the default of *false*, the CSS attribute `pointer-events: none` will be applied for performance reasons.
283 | Setting this to *true* alone will not be enough to fully interact with all layers, since they will be overlapping. You have to either set `position: absolute` on all layer child elements, or keep **pointerEvents** at *false* and set `pointer-events: all` for the interactable elements only.
284 |
285 | ### onReady
286 |
287 | Property: **onReady**
288 |
289 | Value: *null* or *function*
290 | Default: *null*
291 |
292 | Callback function that will be called as soon as the Parallax instance has finished its setup. This might currently take up to 1000ms (`calibrationDelay * 2`).
293 |
294 | # 3. Methods
295 |
296 | In addition to the configuration methods outlined in the section above, there are a few more publicly accessible methods:
297 |
298 | ### enable()
299 |
300 | Enables a disabled Parallax instance.
301 |
302 | ### disable()
303 |
304 | Disables a running Parallax instance.
305 |
306 | ### destroy()
307 |
308 | Completely destroys a Parallax instance, allowing it to be garbage collected.
309 |
310 | ### version()
311 |
312 | Returns the version number of the Parallax library.
313 |
314 | # 4. Development
315 |
316 | ## 4.1 Running the Project
317 |
318 | 1. Clone the Repository `git clone git@github.com:wagerfield/parallax.git`
319 | 2. Open the working directory `cd parallax`
320 | 3. Install dependencies `npm install`
321 | 4. Run development server `gulp watch`
322 | 5. Open [http://localhost:9000/](http://localhost:9000/) in browser
323 |
324 | ## 4.2 Opening an Issue
325 |
326 | If you need help relating the direct usage of this library in a project of yours, provide us with a working, running example of your work. This can be a GitHub repository, a ZIP file containing your work, a project on CodePen or JSFiddle, you name it.
327 | *Do not complain about something not working without giving us some way to help you.* Thank you!
328 |
329 | ## 4.3 Known Issues
330 |
331 | ### SVG-Bug in MS Edge
332 |
333 | It seems MS Edge does not support the `children` or `querySelectorAll` methods for SVG elements.
334 |
335 | ### Animation running really slow
336 |
337 | Depending on your site, the GPU might have a bit too much to do. You can try adding the CSS definition `will-change: transform` to the layer elements to speed things up. Use sparingly!
338 |
339 | ### Gyroscope not working on Android
340 |
341 | Android will only allow access to the gyroscope o secure origins (that is, with `https` protocol).
342 |
343 | ### Gyroscope not working on iOS
344 |
345 | Because gyroscope data had been abused to track users, it's disabled on iDevices by default and needs to be enabled by the users. You can try asking for permission via [DeviceOrientationEvent.requestPermission](https://www.w3.org/TR/orientation-event/#dom-deviceorientationevent-requestpermission).
346 |
347 | Do something like:
348 |
349 | ```js
350 | DeviceOrientationEvent
351 | .requestPermission()
352 | .then(() => {
353 | new Parallax(scene)
354 | })
355 | ```
356 |
357 | ### Unable to manually set position of layers
358 |
359 | Since this often lead to issues, this library forces the positioning of the layers to be absolute. If you need to override this, add `!important` to your CSS positioning.
360 |
361 | # 5. FAQ
362 |
363 | ### How can I use this Library with jQuery?
364 |
365 | jQuery will not prevent you from using this library in any way. If you want to use jQuery for selecting your Parallax scene element, you can do so too.
366 |
367 | ```javascript
368 | var scene = $('#scene').get(0);
369 | var parallaxInstance = new Parallax(scene);
370 | ```
371 |
372 | ### How can I interact with my layers?
373 |
374 | Check out the section on the configuration option `pointerEvents` above.
375 |
376 | ### How do I get the demo files to work?
377 |
378 | Either download compiled_with_examples.zip from the [GitHub Releases](https://github.com/wagerfield/parallax/releases) section, or follow section 4.1
379 |
380 |
381 | # 6. Information
382 |
383 | ## 6.1 License
384 |
385 | This project is licensed under the terms of the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Enjoy!
386 |
387 | ## 6.2 Authors
388 |
389 | Matthew Wagerfield: [@wagerfield](http://twitter.com/wagerfield)
390 | René Roth: [Website](http://reneroth.xyz/)
391 |
--------------------------------------------------------------------------------
/examples/assets/images/layer1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer1.png
--------------------------------------------------------------------------------
/examples/assets/images/layer2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer2.png
--------------------------------------------------------------------------------
/examples/assets/images/layer3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer3.png
--------------------------------------------------------------------------------
/examples/assets/images/layer4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer4.png
--------------------------------------------------------------------------------
/examples/assets/images/layer5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer5.png
--------------------------------------------------------------------------------
/examples/assets/images/layer6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wagerfield/parallax/04e53e94665dd55181f8d54312a9a9e63fef52ab/examples/assets/images/layer6.png
--------------------------------------------------------------------------------
/examples/assets/styles.scss:
--------------------------------------------------------------------------------
1 | $color-green: #00ffaa;
2 | $color-background: #111;
3 | $color-text: #555;
4 |
5 |
6 | body {
7 | background: $color-background;
8 | color: $color-text;
9 | font-family: monospace;
10 | font-size: 18px;
11 | margin: 0;
12 | }
13 |
14 | img {
15 | display: block;
16 | width: 100%;
17 | }
18 |
19 | input[type=checkbox] {
20 | display: none;
21 | }
22 |
23 | label {
24 | cursor: pointer;
25 | display: inline-block;
26 | margin-right: 1em;
27 | padding: 0.4em 0;
28 | }
29 |
30 | input[type=checkbox] + label:before {
31 | background: $color-text;
32 | content: '';
33 | display: inline-block;
34 | height: 16px;
35 | margin-right: 8px;
36 | position: relative;
37 | top: 1px;
38 | width: 16px;
39 | }
40 |
41 | input[type=checkbox]:checked + label:before {
42 | background: $color-green;
43 | }
44 |
45 | .container {
46 | margin: 0 auto;
47 | max-width: 600px;
48 | padding: 10px;
49 | position: relative;
50 | }
51 |
52 | .container--offset {
53 | margin-left: 0;
54 | }
55 |
56 | button {
57 | background: $color-text;
58 | border: 10px solid $color-green;
59 | cursor: pointer;
60 | display: block;
61 | font-family: monospace;
62 | font-size: 24px;
63 | height: 80px;
64 | line-height: 60px;
65 | margin: 0;
66 | outline: none;
67 | padding: 0 1.2em;
68 | text-align: right;
69 |
70 | &:hover {
71 | background: $color-green;
72 | }
73 |
74 | deleteme {
75 | margin: 2rem;
76 | }
77 | }
78 |
79 | .scene {
80 | margin: 0;
81 | padding: 0;
82 |
83 | button {
84 | left: 10%;
85 | top: 260px;
86 | width: 80%;
87 | position: absolute;
88 | }
89 | }
90 |
91 | .fill {
92 | bottom: 5%;
93 | left: 5%;
94 | position: absolute;
95 | right: 5%;
96 | top: 5%;
97 | }
98 |
99 | .expand-width {
100 | width: 100%;
101 | }
102 |
103 | .border {
104 | border: 2px dashed $color-green;
105 | }
106 |
107 | .aspect {
108 | opacity: 0.2;
109 | }
110 |
111 | @for $i from 1 through 6 {
112 | .scene > *:nth-child(#{$i}) {
113 | opacity: #{0.15 * $i};
114 |
115 | button {
116 | transform: rotate(#{180 - 30 * $i}deg)
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/examples/pages/callback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Parallax.js | Callback Example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |