parallax-js
Advanced tools
Comparing version
{ | ||
"name": "parallax-js", | ||
"description": "Parallax Engine that reacts to the orientation of a smart device.", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"license": "MIT", | ||
@@ -12,6 +12,3 @@ "main": "dist/parallax.js", | ||
}, | ||
"scripts": { | ||
"install": "npm run build", | ||
"build": "rm -rf dist && mkdir dist && browserify src/parallax.js --standalone Parallax -o dist/parallax.js && babel dist/parallax.js --no-babelrc --presets=es2015 --out-file dist/parallax.js && uglifyjs dist/parallax.js -o dist/parallax.min.js --source-map dist/parallax.min.js.map -p relative" | ||
}, | ||
"scripts": {}, | ||
"repository": { | ||
@@ -32,11 +29,13 @@ "type": "git", | ||
"devDependencies": { | ||
"autoprefixer": "^6.7.2", | ||
"autoprefixer": "^7.1.4", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babelify": "^7.3.0", | ||
"browser-sync": "^2.18.7", | ||
"browser-sync": "^2.18.13", | ||
"browserify": "^14.0.0", | ||
"gulp": "^3.9.1", | ||
"gulp-postcss": "^6.3.0", | ||
"gulp-postcss": "^7.0.0", | ||
"gulp-rename": "^1.2.2", | ||
"gulp-sass": "^3.1.0", | ||
"gulp-sourcemaps": "^2.4.0", | ||
"gulp-uglify": "^2.0.1", | ||
"gulp-sourcemaps": "^2.6.1", | ||
"gulp-uglify": "^3.0.0", | ||
"gulp-util": "^3.0.8", | ||
@@ -49,9 +48,5 @@ "node-notifier": "^5.0.2", | ||
"dependencies": { | ||
"babel-cli": "^6.24.1", | ||
"babel-preset-es2015": "^6.24.1", | ||
"browserify": "^14.0.0", | ||
"object-assign": "^4.1.1", | ||
"raf": "^3.3.0", | ||
"uglify-js": "^2.7.5" | ||
"raf": "^3.3.0" | ||
} | ||
} |
455
README.md
@@ -5,222 +5,347 @@  | ||
Check out this **[demo][demo]** to see it in action! | ||
Check out the **[demo](http://wagerfield.github.com/parallax/)** to see it in action! | ||
## Setup | ||
# Table of Contents | ||
Add parallax.js to your project with `npm install --save https://github.com/wagerfield/parallax` or `yarn add https://github.com/wagerfield/parallax`. | ||
Now, you can require or import the library, depending on your favorite workflow. | ||
- [1. Getting started](#1-getting-started) | ||
- [1.1 Installation](#11-installation) | ||
- [1.2 Preparations](#12-preparations) | ||
- [1.3 Run Parallax](#13-run-parallax) | ||
- [2. Configuration](#2-configuration) | ||
- [2.1 Programmatic vs Declarative](#21-programmatic-vs-declarative) | ||
- [2.2 Configuration Options](#22-configuration-options) | ||
- [3. Methods](#3-methods) | ||
- [4. Development](#4-development) | ||
- [4.1 Running the Project](#41-running-the-project) | ||
- [4.2 Opening an Issue](#42-opening-an-issue) | ||
- [5. FAQ](#5-faq) | ||
- [6. Information](#6-information) | ||
- [6.1 License](#61-license) | ||
- [6.2 Contributors](#62-authors) | ||
```javascript | ||
const Parallax = require('parallax-js') | ||
// or | ||
import Parallax from 'parallax-js' | ||
``` | ||
# 1. Getting started | ||
Of course you can also simply copy over the compiled file from the `dist` folder and include it like any other 3rd party script. Make sure to run `npm install` in the Parallax folder to compile the project. Or download the precompiled files from the [release section](https://github.com/wagerfield/parallax/releases). | ||
## 1.1 Installation | ||
```html | ||
<script src="dist/parallax.js"></script> | ||
<!-- or if you prefer minified --> | ||
<script src="dist/parallax.min.js"></script> | ||
``` | ||
### 1.1 a) Beginners | ||
Give each element within your scene a `data-depth` attribute specifying its depth within the scene. A depth of **0** will cause the layer to remain stationary, and a depth of **1** will cause the layer to move by the total effect of the calculated motion. Values inbetween **0** and **1** will cause the layer to move by an amount relative to the supplied ratio. | ||
1. Head over to the [releases](releases) Section | ||
2. Download `compiled.zip` from the latest release | ||
3. Extract the ZIP archive and locate the `parallax.js` and `parallax.min.js` files | ||
- Use `parallax.js` if you want to snoop around in the code | ||
- Use `parallax.min.js` for deployment, because it has a smaller file size | ||
4. Copy the file of your choice into your project directory | ||
5. So far, so good! | ||
```html | ||
<div id="scene"> | ||
<div data-depth="0.00"><img src="layer1.png"></div> | ||
<div data-depth="0.20"><img src="layer2.png"></div> | ||
<div data-depth="0.40"><img src="layer3.png"></div> | ||
<div data-depth="0.60"><img src="layer4.png"></div> | ||
<div data-depth="0.80"><img src="layer5.png"></div> | ||
<div data-depth="1.00"><img src="layer6.png"></div> | ||
</div> | ||
``` | ||
### 1.1 b) Professionals | ||
To kickoff a **Parallax** scene, select your parent DOM Element and pass it to the **Parallax** constructor. | ||
`npm i -s parallax-js` | ||
```javascript | ||
var scene = document.getElementById('scene') | ||
// or, if you use jQuery | ||
var scene = $('#scene').get(0) | ||
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` | ||
var parallax = new Parallax(scene) | ||
``` | ||
## 1.2 Preparations | ||
## Interactivity | ||
### Include the Script | ||
If you need to interact with the layers, don't forget to set the `pointerEvents` option, and adjust your layer CSS. | ||
Then set an absolute position for all layer child elements, just like it's done in `examples/pages/interactive.html`. Alternatively, set `pointer-events: none` on the layers and `pointer-events: all` on the layer child elements. | ||
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: | ||
`<script src="path/to/parallax.js"></script>` | ||
## Understanding Layer Motion Calculations | ||
Of course, when you've installed via npm, and use browserify/babel, you can also simply do: | ||
`import Parallax from 'parallax-js'` or | ||
`const Parallax = require('parallax-js')` | ||
The amount of motion that each layer moves by depends on 3 contributing factors: | ||
### Create your HTML elements | ||
1. The `scalarX` and `scalarY` values (see [Behaviours](#behaviours) below for configuration) | ||
2. The dimensions of the parent DOM element | ||
3. The `depth` of a layer within a parallax scene (specified by it's `data-depth` attribute) | ||
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: | ||
The calculation for this motion is as follows: | ||
```html | ||
<div id="scene"> | ||
</div> | ||
``` | ||
```javascript | ||
xMotion = parentElement.width * (scalarX / 100) * layerDepth | ||
yMotion = parentElement.height * (scalarY / 100) * layerDepth | ||
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: | ||
```html | ||
<div id="scene"> | ||
<div>My first Layer!</div> | ||
<div>My second Layer!</div> | ||
</div> | ||
``` | ||
So for a layer with a `data-depth` value of `0.5` within a scene that has both the `scalarX` and `scalarY` values set to `10` ( *the default* ) where the containing scene element is `1000px x 1000px`, the total motion of the layer in both `x` and `y` would be: | ||
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. | ||
```html | ||
<div id="scene"> | ||
<div data-depth="0.2">My first Layer!</div> | ||
<div data-depth="0.6">My second Layer!</div> | ||
</div> | ||
``` | ||
## 1.3 Run Parallax | ||
As soon as your DOM is ready and loaded, you can create a new Parallax.js instance, providing your scene element as first parameter. | ||
```javascript | ||
xMotion = 1000 * (10 / 100) * 0.5 = 50 // 50px of positive and negative motion in x | ||
yMotion = 1000 * (10 / 100) * 0.5 = 50 // 50px of positive and negative motion in y | ||
var scene = document.getElementById('scene'); | ||
var parallaxInstance = new Parallax(scene); | ||
``` | ||
## Behaviours | ||
That's it, you're running Parallax.js now! | ||
There are a number of behaviours that you can setup for any given **Parallax** instance. These behaviours can either be specified in the markup via data attributes or in JavaScript via the constructor and API. | ||
# 2. Configuration | ||
| Behaviour | Values | Default | Description | | ||
| ------------------- | ------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `relativeInput` | `true` or `false` | `false` | Specifies whether or not to use the coordinate system of the scene. **Mouse input only.** | | ||
| `clipRelativeInput` | `true` or `false` | `false` | Specifies whether or not to clip the mouse input to the scene bounds. No effect in combination with `hoverOnly`. **Mouse input only.** | | ||
| `hoverOnly` | `true` or `false` | `false` | Apply the parallax effect only while the cursor is over the scene. Best together with `relativeInput` set to true. **Mouse input only.** | | ||
| `inputElement` | `null` or HTML element | `null` | Element used for input calculations. Works only with `relativeInput`, might make sense to set `hoverOnly`. When set via `data-input-element` attribute, takes a query selector. **Mouse input only.** | | ||
| `calibrate-x` | `true` or `false` | `false` | Specifies whether or not to cache & calculate the motion relative to the initial `x` axis value on initialisation. | | ||
| `calibrate-y` | `true` or `false` | `true` | Specifies whether or not to cache & calculate the motion relative to the initial `y` axis value on initialisation. | | ||
| `invert-x` | `true` or `false` | `true` | `true` moves layers in opposition to the device motion, `false` slides them away. | | ||
| `invert-y` | `true` or `false` | `true` | `true` moves layers in opposition to the device motion, `false` slides them away. | | ||
| `limit-x` | `number` or `false` | `false` | A numeric value limits the total range of motion in `x`, `false` allows layers to move with complete freedom. | | ||
| `limit-y` | `number` or `false` | `false` | A numeric value limits the total range of motion in `y`, `false` allows layers to move with complete freedom. | | ||
| `scalar-x` | `number` | `10.0` | Multiplies the input motion by this value, increasing or decreasing the sensitivity of the layer motion. | | ||
| `scalar-y` | `number` | `10.0` | Multiplies the input motion by this value, increasing or decreasing the sensitivity of the layer motion. | | ||
| `friction-x` | `number` `0 - 1` | `0.1` | The amount of friction the layers experience. This essentially adds some easing to the layer motion. | | ||
| `friction-y` | `number` `0 - 1` | `0.1` | The amount of friction the layers experience. This essentially adds some easing to the layer motion. | | ||
| `origin-x` | `number` | `0.5` | The `x` origin of the mouse input. Defaults to 0.5 (the center). `0` moves the origin to the left edge, `1` to the right edge. **Mouse input only.** | | ||
| `origin-y` | `number` | `0.5` | The `y` origin of the mouse input. Defaults to 0.5 (the center). `0` moves the origin to the top edge, `1` to the bottom edge. **Mouse input only.** | | ||
| `precision` | `integer` | `1` | Decimals the element positions should be rounded to. Changing this value should not be necessary anytime soon. | | ||
| `pointerEvents` | `true` or `false` | `false` | Leaving this at false might increase the performance in some instances, while removing pointer events for the scene - eg, Links are not clickable | | ||
| `onReady` | `null` or `function` | `null` | Function that will be called as soon as Parallax setup is completed. Might take up to 1000ms (`calibrationDelay * 2`) | | ||
## 2.1 Programmatic vs Declarative | ||
In addition to the behaviours described above, there are the methods `enable()` and `disable()` that *activate* and *deactivate* the **Parallax** instance respectively. | ||
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. | ||
Some options can also be set at run-time via instance methods. | ||
### Behaviours: Data Attributes Example | ||
Declarative: | ||
```html | ||
<div id="scene" | ||
data-relative-input="true" | ||
data-clip-relative-input="false" | ||
data-hover-only="true" | ||
data-input-element="#myinput" | ||
data-calibrate-x="false" | ||
data-calibrate-y="true" | ||
data-invert-x="false" | ||
data-invert-y="true" | ||
data-limit-x="false" | ||
data-limit-y="10" | ||
data-scalar-x="2" | ||
data-scalar-y="8" | ||
data-friction-x="0.2" | ||
data-friction-y="0.8" | ||
data-origin-x="0.0" | ||
data-origin-y="1.0" | ||
data-precision="1" | ||
data-pointer-events="false"> | ||
<div data-depth="0.00"><img src="graphics/layer1.png"></div> | ||
<div data-depth="0.20"><img src="graphics/layer2.png"></div> | ||
<div data-depth="0.40"><img src="graphics/layer3.png"></div> | ||
<div data-depth="0.60"><img src="graphics/layer4.png"></div> | ||
<div data-depth="0.80"><img src="graphics/layer5.png"></div> | ||
<div data-depth="1.00"><img src="graphics/layer6.png"></div> | ||
<div data-relative-input="true" id="scene"> | ||
<div data-depth="0.2">My first Layer!</div> | ||
<div data-depth="0.6">My second Layer!</div> | ||
</div> | ||
``` | ||
### Behaviours: Constructor Object Example | ||
Programmatic: | ||
```javascript | ||
var scene = document.getElementById('scene'); | ||
var parallax = new Parallax(scene, { | ||
relativeInput: true, | ||
clipRelativeInput: false, | ||
hoverOnly: true, | ||
inputElement: document.getElementById('myinput'), | ||
calibrateX: false, | ||
calibrateY: true, | ||
invertX: false, | ||
invertY: true, | ||
limitX: false, | ||
limitY: 10, | ||
scalarX: 2, | ||
scalarY: 8, | ||
frictionX: 0.2, | ||
frictionY: 0.8, | ||
originX: 0.0, | ||
originY: 1.0, | ||
precision: 1, | ||
pointerEvents: false, | ||
onReady: function() { alert('ready!'); } | ||
var parallaxInstance = new Parallax(scene, { | ||
relativeInput: true | ||
}); | ||
``` | ||
### Behaviours: API Example | ||
Using Methods at Runtime: | ||
```javascript | ||
var scene = document.getElementById('scene'); | ||
var parallax = new Parallax(scene); | ||
parallax.enable(); | ||
parallax.disable(); | ||
parallax.updateLayers(); // Useful for reparsing the layers in your scene if you change their data-depth value | ||
parallax.calibrate(false, true); | ||
parallax.invert(false, true); | ||
parallax.limit(false, 10); | ||
parallax.scalar(2, 8); | ||
parallax.friction(0.2, 0.8); | ||
parallax.origin(0.0, 1.0); | ||
parallax.setInputElement(document.getElementById('newinput')); | ||
parallaxInstance.friction(0.2, 0.2); | ||
``` | ||
## iOS | ||
## 2.2 Configuration Options | ||
If you are writing a **native iOS application** and would like to use **parallax.js** within a `UIWebView`, you will need to do a little bit of work to get it running. | ||
### relativeInput | ||
`UIWebView` no longer automatically receives the `deviceorientation` event, so your native application must intercept the events from the gyroscope and reroute them to the `UIWebView`: | ||
Property: **relativeInput** | ||
Attribute: **data-relative-input** | ||
1. Include the **CoreMotion** framework `#import <CoreMotion/CoreMotion.h>` and create a reference to the **UIWebView** `@property(nonatomic, strong) IBOutlet UIWebView *parallaxWebView;` | ||
2. Add a property to the app delegate (or controller that will own the **UIWebView**) `@property(nonatomic, strong) CMMotionManager *motionManager;` | ||
3. Finally, make the following calls: | ||
Value: *boolean* | ||
Default: *false* | ||
```Objective-C | ||
self.motionManager = [[CMMotionManager alloc] init]; | ||
if (self.motionManager.isGyroAvailable && !self.motionManager.isGyroActive) { | ||
[self.motionManager setGyroUpdateInterval:0.5f]; // Set the event update frequency (in seconds) | ||
[self.motionManager startGyroUpdatesToQueue:NSOperationQueue.mainQueue | ||
withHandler:^(CMGyroData *gyroData, NSError *error) { | ||
NSString *js = [NSString stringWithFormat:@"parallax.onDeviceOrientation({beta:%f, gamma:%f})", gyroData.rotationRate.x, gyroData.rotationRate.y]; | ||
[self.parallaxWebView stringByEvaluatingJavaScriptFromString:js]; | ||
}]; | ||
} | ||
``` | ||
Makes mouse input relative to the position of the scene element. | ||
No effect when gyroscope is used. | ||
## Build | ||
### clipRelativeInput | ||
> As a prerequisite, you will need [gulp][gulp] installed: `npm install -g gulp` | ||
Property: **clipRelativeInput** | ||
Attribute: **data-clip-relative-input** | ||
Value: *boolean* | ||
Default: *false* | ||
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. | ||
No effect when gyroscope is used, or `hoverOnly` is active. | ||
### hoverOnly | ||
Property: **hoverOnly** | ||
Attribute: **data-hover-only** | ||
Value: *boolean* | ||
Default: *false* | ||
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`. | ||
No effect when gyroscope is used. | ||
### inputElement | ||
Property: **inputElement** | ||
Attribute: **data-input-element** | ||
Method: **setInputElement(HTMLElement)** | ||
Value: *null* or *HTMLElement* / *String* | ||
Default: *null* | ||
Allows usage of a different element for cursor input. | ||
The configuration property expects an HTMLElement, the data value attribute a query selector string. | ||
Will only work in combination with `relativeInput`, setting `hoverOnly` might make sense too. | ||
No effect when gyroscope is used. | ||
### calibrateX & calibrateY | ||
Property: **calibrateX** & **calibrateY** | ||
Attribute: **data-calibrate-x** & **data-calibrate-y** | ||
Method: **calibrate(x, y)** | ||
Value: *boolean* | ||
Default: *false* for X, *true* for Y | ||
Caches the initial X/Y axis value on initialization and calculates motion relative to this. | ||
No effect when cursor is used. | ||
### invertX & invertY | ||
Property: **invertX** & **invertY** | ||
Attribute: **data-invert-x** & **data-invert-y** | ||
Method: **invert(x, y)** | ||
Value: *boolean* | ||
Default: *true* | ||
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. | ||
### limitX & limitY | ||
Property: **limitX** & **limitY** | ||
Attribute: **data-limit-x** & **data-limit-y** | ||
Method: **limit(x, y)** | ||
Value: *false* or *integer* | ||
Default: *false* | ||
Limits the movement of layers on the respective axis. Leaving this value at false gives complete freedom to the movement. | ||
### scalarX & scalarY | ||
Property: **scalarX** & **scalarY** | ||
Attribute: **data-scalar-x** & **data-scalar-y** | ||
Method: **scalar(x, y)** | ||
Value: *float* | ||
Default: *10.0* | ||
Multiplies the input motion by this value, increasing or decreasing the movement speed and range. | ||
### frictionX & frictionY | ||
Property: **frictionX** & **frictionY** | ||
Attribute: **data-friction-x** & **data-friction-y** | ||
Method: **friction(x, y)** | ||
Value: *float* between *0* and *1* | ||
Default: *0.1* | ||
Amount of friction applied to the layers. At *1* the layers will instantly go to their new positions, everything below 1 adds some easing. | ||
The default value of *0.1* adds some sensible easing. Try *0.15* or *0.075* for some difference. | ||
### originX & originY | ||
Property: **originX** & **originY** | ||
Attribute: **data-origin-x** & **data-origin-y** | ||
Method: **origin(x, y)** | ||
Value: *float* between *0* and *1* | ||
Default: *0.5* | ||
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. | ||
No effect when gyroscope is used. | ||
### precision | ||
Property: **precision** | ||
Attribute: **data-precision** | ||
Value: *integer* | ||
Default: *1* | ||
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. | ||
### selector | ||
Property: **selector** | ||
Attribute: **data-selector** | ||
Value: *null* or *string* | ||
Default: *null* | ||
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. | ||
Use `.layer` for legacy behaviour, selecting only child elements having the class name *layer*. | ||
### pointerEvents | ||
Property: **pointerEvents** | ||
Attribute: **data-pointer-events** | ||
Value: *boolean* | ||
Default: *false* | ||
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. | ||
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. | ||
### onReady | ||
Property: **onReady** | ||
Value: *null* or *function* | ||
Default: *null* | ||
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`). | ||
# 3. Methods | ||
In addition to the configuration methods outlined in the section above, there are a few more publicly accessible methods: | ||
### enable() | ||
Enables a disabled Parallax instance. | ||
### disable() | ||
Disables a running Parallax instance. | ||
### destroy() | ||
Completely destroys a Parallax instance, allowing it to be garbage collected. | ||
### version() | ||
Returns the version number of the Parallax library. | ||
# 4. Development | ||
## 4.1 Running the Project | ||
1. Clone the Repository `git clone git@github.com:wagerfield/parallax.git` | ||
2. Open the working directory `cd parallax` | ||
3. Install dependencies `npm install` | ||
4. Run development server `gulp watch` | ||
5. Open [http://localhost:9000/](http://localhost:9000/) in browser | ||
## 4.2 Opening an Issue | ||
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. | ||
*Do not complain about something not working without giving us some way to help you.* Thank you! | ||
# 5. FAQ | ||
### How can I use this Library with jQuery? | ||
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. | ||
```javascript | ||
var scene = $('#scene').get(0); | ||
var parallaxInstance = new Parallax(scene); | ||
``` | ||
npm install | ||
gulp | ||
``` | ||
gulp will watch the `source` directory for changes and automatically build the `dist` files, serving some demo files with live reload. | ||
### How can I interact with my layers? | ||
## Authors | ||
Check out the section on the configuration option `pointerEvents` above. | ||
Matthew Wagerfield: [@wagerfield][twittermw] | ||
René Roth: [Website][websiterr] | ||
### How do I get the demo files to work? | ||
## License | ||
Either download compiled_with_examples.zip from the [GitHub Releases](https://github.com/wagerfield/parallax/releases) section, or follow section 4.1 | ||
Licensed under [MIT][mit]. Enjoy. | ||
*More to be added soon...* | ||
[demo]: http://wagerfield.github.com/parallax/ | ||
[twittermw]: http://twitter.com/wagerfield | ||
[websiterr]: http://reneroth.org/ | ||
[mit]: http://www.opensource.org/licenses/mit-license.php | ||
[gulp]: http://gulpjs.com/ | ||
# 6. Information | ||
## 6.1 License | ||
This project is licensed under the terms of the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Enjoy! | ||
## 6.2 Authors | ||
Matthew Wagerfield: [@wagerfield](http://twitter.com/wagerfield) | ||
René Roth: [Website](http://reneroth.org/) |
@@ -14,3 +14,3 @@ /** | ||
propertyCache: {}, | ||
vendors: [null,['-webkit-','webkit'],['-moz-','Moz'],['-o-','O'],['-ms-','ms']], | ||
vendors: [null, ['-webkit-','webkit'], ['-moz-','Moz'], ['-o-','O'], ['-ms-','ms']], | ||
@@ -152,3 +152,4 @@ clamp(value, min, max) { | ||
precision: 1, | ||
onReady: null | ||
onReady: null, | ||
selector: null | ||
} | ||
@@ -160,3 +161,2 @@ | ||
this.element = element | ||
this.layers = element.getElementsByClassName('layer') | ||
@@ -181,3 +181,4 @@ const data = { | ||
hoverOnly: helpers.data(this.element, 'hover-only'), | ||
inputElement: document.querySelector(helpers.data(this.element, 'input-element')) | ||
inputElement: document.querySelector(helpers.data(this.element, 'input-element')), | ||
selector: helpers.data(this.element, 'selector') | ||
} | ||
@@ -288,3 +289,12 @@ | ||
updateLayers() { | ||
this.layers = this.element.children | ||
if(this.selector) { | ||
this.layers = this.element.querySelectorAll(this.selector) | ||
} else { | ||
this.layers = this.element.children | ||
} | ||
if(!this.layers.length) { | ||
console.warn('ParallaxJS: Your scene does not have any layers.') | ||
} | ||
this.depthsX = [] | ||
@@ -346,7 +356,7 @@ this.depthsY = [] | ||
window.addEventListener('deviceorientation', this.onDeviceOrientation) | ||
setTimeout(this.onOrientationTimer, this.supportDelay) | ||
this.detectionTimer = setTimeout(this.onOrientationTimer, this.supportDelay) | ||
} else if (this.motionSupport) { | ||
this.portrait = false | ||
window.addEventListener('devicemotion', this.onDeviceMotion) | ||
setTimeout(this.onMotionTimer, this.supportDelay) | ||
this.detectionTimer = setTimeout(this.onMotionTimer, this.supportDelay) | ||
} else { | ||
@@ -568,4 +578,23 @@ this.calibrationX = 0 | ||
destroy() { | ||
this.disable() | ||
clearTimeout(this.calibrationTimer) | ||
clearTimeout(this.detectionTimer) | ||
this.element.removeAttribute('style') | ||
for (let index = 0; index < this.layers.length; index++) { | ||
this.layers[index].removeAttribute('style') | ||
} | ||
delete this.element | ||
delete this.layers | ||
} | ||
version() { | ||
return '3.1.0' | ||
} | ||
} | ||
module.exports = Parallax |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2
-66.67%11
22.22%351
55.31%0
-100%350908
-3.94%16
14.29%1859
-66.5%1
Infinity%5
Infinity%2
100%- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed