Compare commits

...

42 commits

Author SHA1 Message Date
Șandor Sergiu 48f4ee931d
Update README.md 2023-11-05 05:55:04 +02:00
micku7zu 967ab1accf Fix destroy method and update to version 1.8.1 2023-08-15 12:47:15 +03:00
micku7zu f4a557955d Update package-lock.json 2022-12-13 01:08:45 +02:00
micku7zu 7a179baa43 Update to version 1.8.0 2022-12-13 01:08:35 +02:00
micku7zu bfe0c75eb5 Add Andžs Pilskalns to contributors 2022-12-13 01:06:18 +02:00
micku7zu 2a1f867ec1 Update reset-to-start default to true 2022-12-13 01:00:15 +02:00
dependabot[bot] 042c3eac64
Bump decode-uri-component from 0.2.0 to 0.2.2 (#124)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 00:30:46 +02:00
dependabot[bot] 0c73694cb8
Bump qs and gh-pages (#125)
Bumps [qs](https://github.com/ljharb/qs) to 6.5.3 and updates ancestor dependency [gh-pages](https://github.com/tschaub/gh-pages). These dependencies need to be updated together.


Updates `qs` from 6.5.2 to 6.5.3
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3)

Updates `gh-pages` from 0.12.0 to 4.0.0
- [Release notes](https://github.com/tschaub/gh-pages/releases)
- [Changelog](https://github.com/tschaub/gh-pages/blob/main/changelog.md)
- [Commits](https://github.com/tschaub/gh-pages/compare/v0.12.0...v4.0.0)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: gh-pages
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 00:30:37 +02:00
Andžs 475fa30d50
Feature: "reset to start" (#126) 2022-12-13 00:28:57 +02:00
PSJahn ffc28a5bab
Removed unnecessary commas triggering my OCD (#119) 2022-11-03 09:46:11 +02:00
micku7zu 7f606cd52d Update to version 1.7.3 2022-10-29 20:37:19 +03:00
Rosux e80bf21faa
Fix glare on elements with border-radius 2022-10-29 20:21:18 +03:00
Șandor Sergiu 82792cbc9e
Update vanilla-tilt.js 2022-10-27 14:05:23 +03:00
Șandor Sergiu 29d586ce5b
Update README.md 2022-10-27 14:04:15 +03:00
Sheryl Hohman 6315937c6e
typo in README.md (#102) 2022-02-20 20:10:54 +02:00
Șandor Sergiu 61559a399a
Update README.md 2022-01-10 10:03:38 +02:00
Șandor Sergiu 2ee96e937f
Update README.md 2022-01-10 09:59:12 +02:00
Șandor Sergiu f6b73dac54
Revert "Add setting to use px instead of degrees for tilt (#94)" (#97)
This reverts commit 43ca5c53cf.
2021-11-03 09:14:50 +02:00
Eric Castillo 43ca5c53cf
Add setting to use px instead of degrees for tilt (#94) 2021-11-03 09:06:31 +02:00
micku7zu cb1f298d83 Update to 1.7.2 2021-09-04 10:26:25 +03:00
dependabot[bot] 66f7af8fa1
Bump path-parse from 1.0.5 to 1.0.7 (#92)
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.5 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-09-04 10:25:45 +03:00
micku7zu ebcf46cec4 Update to 1.7.2 2021-09-04 10:25:03 +03:00
Foxi 20f9edad9e
Fixing glare being too small when the container's vertical dimension is greater than its horizontal. (#91) 2021-09-04 09:57:02 +03:00
micku7zu 4a644269a1 Fix first interaction skew big distortion and update to 1.7.1 2021-07-28 10:26:28 +03:00
Mateusz Garbaciak d9b26fa40a
update readme on NPM installation (#85) 2021-05-17 14:59:03 +03:00
HimajPatil 129f3e31f1
Added HTML Language Tag (#80)
After adding this tag , users who have enabled browser extension for translation can view the HTML component in that language. It does not make a big difference but it is even recommended by Emmet is Visual Studio Code.
2021-04-19 10:43:38 +03:00
dependabot[bot] df653098f4
Bump y18n from 3.2.1 to 3.2.2 (#79)
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-19 10:42:51 +03:00
HimajPatil e6be1a9dae
Enhanced Documentation (#77)
The changes I made can make the documentation a little more better.
2021-03-29 16:17:16 +03:00
andreas 83e691f58a
Fix documented max option default value (#63) 2020-05-01 02:29:04 +03:00
Șandor Sergiu e0e07613e2
Update README.md 2019-05-06 09:37:34 +03:00
Șandor Sergiu 8a3633a541
Update README.md 2019-04-13 11:02:04 +03:00
Sandor Sergiu d034afe971 Update to version 1.7.0 Refactored some code after many pull requests. 2019-04-13 10:55:36 +03:00
Sandor Sergiu 2595c33eee Update to version 1.6.3. Refactored some code and fixed degrees calculation. 2019-04-13 10:19:56 +03:00
Sander Moolin 5532251af8 Added startX and startY properties (#48)
* Added startX and startY properties

* Added a couple lines of documentation
2019-04-13 10:13:19 +03:00
Șandor Sergiu 581bfc6add
Update contributors 2019-04-13 00:16:22 +03:00
Sandor Sergiu 30a8ec0b87 Version 1.6.2: Add gyroscope samples 2019-04-12 23:57:54 +03:00
Șandor Sergiu 91bc380ef7
Add Internet Explorer Custom Event polyfill details 2019-04-12 23:28:57 +03:00
Sandor Sergiu d3107f0d6f Add test/index.html file for easier debug on the master branch. 2019-04-12 23:14:22 +03:00
rrroyal 7dddcf950b Whole document mouse movement support (#51)
* Whole document mouse movement support

Also updated CONTRIBUTORS.md

* Fixed a typo
2019-04-12 21:48:58 +03:00
Matthew Merryfull 2120d8b87f added updated type definitions for v1.6.1 and entry into package.json (#47)
* added updated type definitions for v1.6.1 and entry into package.json

* updated readme for type usage
2019-04-12 21:47:52 +03:00
Șandor Sergiu fd0cc73b14
Update README.md 2019-04-08 21:34:07 +03:00
Sandor Sergiu b0cc942f99 Fix gyroscope false and update to 1.6.1 2018-12-28 11:10:13 +02:00
14 changed files with 8615 additions and 484 deletions

View file

@ -3,3 +3,6 @@
- [Livio Brunner](https://github.com/BrunnerLivio) <<a href="mailto:contact@brunnerliv.io">contact@brunnerliv.io</a>> (Typings & Glare Effect)
- [Oleg Postoev](https://github.com/Dok11)
- [Matteo Rigon](https://github.com/matteo-rigon) (Device orientation support)
- [Corey Austin](https://github.com/lazyhummingbird) (Initial gyroscope position)
- [rrroyal](https://github.com/rrroyal) (Whole document mouse events listening)
- [Andžs Pilskalns](https://github.com/Pilskalns) ("reset-to-start" feature)

View file

@ -1,7 +1,6 @@
# vanilla-tilt.js
[![npm version](https://badge.fury.io/js/vanilla-tilt.svg)](https://badge.fury.io/js/vanilla-tilt)
[![ghit.me](https://ghit.me/badge.svg?repo=micku7zu/vanilla-tilt.js)](https://ghit.me/repo/micku7zu/vanilla-tilt.js)
A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https://github.com/gijsroge/tilt.js).
@ -11,6 +10,8 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https
```html
<body>
<!-- your markup element -->
<div class="your-element" data-tilt></div>
<!-- at the end of the body -->
@ -18,28 +19,34 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https
</body>
```
If you want to use this library in IE, you need to include a CustomEvent polyfill: https://github.com/micku7zu/vanilla-tilt.js/issues/49#issuecomment-482711876 or maybe consider the [jQuery version](https://github.com/gijsroge/tilt.js).
### Options
```js
{
reverse: false, // reverse the tilt direction
max: 35, // max tilt rotation (degrees)
max: 15, // max tilt rotation (degrees)
startX: 0, // the starting tilt on the X axis, in degrees.
startY: 0, // the starting tilt on the Y axis, in degrees.
perspective: 1000, // Transform perspective, the lower the more extreme the tilt gets.
scale: 1, // 2 = 200%, 1.5 = 150%, etc..
speed: 300, // Speed of the enter/exit transition
transition: true, // Set a transition on enter/exit.
axis: null, // What axis should be disabled. Can be X or Y.
reset: true // If the tilt effect has to be reset on exit.
axis: null, // What axis should be enabled. Can be "x" or "y".
reset: true, // If the tilt effect has to be reset on exit.
"reset-to-start": true, // Whether the exit reset will go to [0,0] (default) or [startX, startY]
easing: "cubic-bezier(.03,.98,.52,.99)", // Easing on enter/exit.
glare: false // if it should have a "glare" effect
glare: false, // if it should have a "glare" effect
"max-glare": 1, // the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
"glare-prerender": false, // false = VanillaTilt creates the glare elements for you, otherwise
// you need to add .js-tilt-glare>.js-tilt-glare-inner by yourself
"mouse-event-element": null // css-selector or link to HTML-element what will be listen mouse events
gyroscope: true // Boolean to enable/disable device orientation detection,
gyroscopeMinAngleX: -45 // This is the bottom limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the left border of the element;
gyroscopeMaxAngleX: 45 // This is the top limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the right border of the element;
gyroscopeMinAngleY: -45 // This is the bottom limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the top border of the element;
gyroscopeMaxAngleY: 45 // This is the top limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the bottom border of the element;
"mouse-event-element": null, // css-selector or link to an HTML-element that will be listening to mouse events
"full-page-listening": false, // If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
gyroscope: true, // Boolean to enable/disable device orientation detection,
gyroscopeMinAngleX: -45, // This is the bottom limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the left border of the element;
gyroscopeMaxAngleX: 45, // This is the top limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the right border of the element;
gyroscopeMinAngleY: -45, // This is the bottom limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the top border of the element;
gyroscopeMaxAngleY: 45, // This is the top limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the bottom border of the element;
gyroscopeSamples: 10 // How many gyroscope moves to decide the starting position.
}
```
@ -72,10 +79,10 @@ VanillaTilt.init(elements);
### Install
You can copy and include any of the following file:
* [dist/vanilla-tilt.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.js) ~ 6kb
* [dist/vanilla-tilt.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.min.js) ~ 3.5kb
* [dist/vanilla-tilt.babel.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.js) ~ 8.5kb
* [dist/vanilla-tilt.babel.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.min.js) ~ 4.3kb
* [dist/vanilla-tilt.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.js) ~ 15kb
* [dist/vanilla-tilt.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.min.js) ~ 8.5kb
* [dist/vanilla-tilt.babel.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.js) ~ 16.5kb
* [dist/vanilla-tilt.babel.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.min.js) ~ 9.5kb
#### NPM
@ -85,13 +92,15 @@ Also available on npm https://www.npmjs.com/package/vanilla-tilt
npm install vanilla-tilt
```
#### Typings
Import it using
Installing typings using npm
```
npm install @types/vanilla-tilt
import VanillaTilt from 'vanilla-tilt';
```
### Known issues
- [Getting weird rendering issues on Safari](https://github.com/micku7zu/vanilla-tilt.js/issues/22)
### Credits
Original library: [Tilt.js](http://gijsroge.github.io/tilt.js/)
@ -103,7 +112,20 @@ Original library author: [Gijs Rogé](https://twitter.com/GijsRoge)
- [Livio Brunner](https://github.com/BrunnerLivio) <<a href="mailto:contact@brunnerliv.io">contact@brunnerliv.io</a>> (Typings & Glare Effect)
- [Oleg Postoev](https://github.com/Dok11)
- [Matteo Rigon](https://github.com/matteo-rigon) (Device orientation support)
- [Corey Austin](https://github.com/lazyhummingbird) (Initial gyroscope position)
- [Sander Moolin](https://github.com/SaFrMo)
- [rrroyal](https://github.com/rrroyal) (Whole document mouse events listening)
- [Andžs Pilskalns](https://github.com/Pilskalns) ("reset-to-start" feature)
### Other projects
#### [Quick Cursor: One-Handed mode](https://play.google.com/store/apps/details?id=com.quickcursor) (Android app)
Play Store link: https://play.google.com/store/apps/details?id=com.quickcursor
### Buy me a beer 🍻
If you want to thank me for vanilla-tilt.js or Quick Cursor Android app, you can donate on PayPal:
- [Donate through PayPal](https://www.paypal.com/donate/?hosted_button_id=XH38XJ986LQFA): https://www.paypal.com/donate/?hosted_button_id=XH38XJ986LQFA
- [Send money through PayPal](https://www.paypal.com/paypalme/micku7zu?locale.x=en_US): https://www.paypal.com/paypalme/micku7zu?locale.x=en_US
### License
MIT License

View file

@ -8,10 +8,10 @@ var classCallCheck = function (instance, Constructor) {
};
/**
* Created by Șandor Sergiu (micku7zu) on 1/27/2017.
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.6.0
* Version 1.8.1
*/
var VanillaTilt = function () {
@ -25,31 +25,55 @@ var VanillaTilt = function () {
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.elementListener = this.getElementListener();
this.reverse = this.settings.reverse ? -1 : 1;
this.resetToStart = VanillaTilt.isSettingTrue(this.settings["reset-to-start"]);
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.glare = this.isSettingTrue(this.settings.glare);
this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]);
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
if (this.resetToStart === false) {
this.settings.startX = 0;
this.settings.startY = 0;
}
}
VanillaTilt.prototype.isSettingTrue = function isSettingTrue(setting) {
VanillaTilt.isSettingTrue = function isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
};
@ -60,8 +84,8 @@ var VanillaTilt = function () {
VanillaTilt.prototype.getElementListener = function getElementListener() {
if (!this.settings || !this.settings["mouse-event-element"]) {
return this.element;
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
@ -75,6 +99,8 @@ var VanillaTilt = function () {
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
};
/**
@ -91,13 +117,16 @@ var VanillaTilt = function () {
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
};
/**
@ -107,11 +136,14 @@ var VanillaTilt = function () {
VanillaTilt.prototype.removeEventListeners = function removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
};
@ -122,7 +154,10 @@ var VanillaTilt = function () {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.element.style.willChange = "";
this.element.style.transition = "";
this.element.style.transform = "";
this.resetGlare();
this.removeEventListeners();
this.element.vanillaTilt = null;
@ -138,14 +173,29 @@ var VanillaTilt = function () {
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
var totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
var totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
var degreesPerPixelX = totalAngleX / this.width;
var degreesPerPixelY = totalAngleY / this.height;
var angleX = event.gamma - this.settings.gyroscopeMinAngleX;
var angleY = event.beta - this.settings.gyroscopeMinAngleY;
var angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
var angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
var posX = angleX / degreesPerPixelX;
var posY = angleY / degreesPerPixelY;
@ -186,15 +236,28 @@ var VanillaTilt = function () {
};
VanillaTilt.prototype.reset = function reset() {
this.event = {
pageX: this.left + this.width / 2,
pageY: this.top + this.height / 2
};
this.onMouseEnter();
if (this.element && this.element.style) {
this.element.style.transform = "perspective(" + this.settings.perspective + "px) " + "rotateX(0deg) " + "rotateY(0deg) " + "scale3d(1, 1, 1)";
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width,
clientY: this.top + (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height
};
}
var backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
};
VanillaTilt.prototype.resetGlare = function resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
@ -202,14 +265,22 @@ var VanillaTilt = function () {
};
VanillaTilt.prototype.getValues = function getValues() {
var x = (this.event.clientX - this.left) / this.width;
var y = (this.event.clientY - this.top) / this.height;
var x = void 0,
y = void 0;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
var tiltX = (this.reverse * (this.settings.max / 2 - x * this.settings.max)).toFixed(2);
var tiltY = (this.reverse * (y * this.settings.max - this.settings.max / 2)).toFixed(2);
var tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
var tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
var angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
@ -281,7 +352,8 @@ var VanillaTilt = function () {
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
"pointer-events": "none",
"border-radius": "inherit"
});
Object.assign(this.glareElement.style, {
@ -290,23 +362,34 @@ var VanillaTilt = function () {
"left": "50%",
"pointer-events": "none",
"background-image": "linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",
"width": this.element.offsetWidth * 2 + "px",
"height": this.element.offsetWidth * 2 + "px",
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0"
});
this.updateGlareSize();
};
VanillaTilt.prototype.updateGlareSize = function updateGlareSize() {
Object.assign(this.glareElement.style, {
"width": "" + this.element.offsetWidth * 2,
"height": "" + this.element.offsetWidth * 2
});
if (this.glare) {
var glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": glareSize + "px",
"height": glareSize + "px"
});
}
};
VanillaTilt.prototype.updateClientSize = function updateClientSize() {
this.clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
this.clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
};
VanillaTilt.prototype.onWindowResize = function onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
};
VanillaTilt.prototype.setTransition = function setTransition() {
@ -328,26 +411,33 @@ var VanillaTilt = function () {
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {string|null} settings.axis - What axis should be enabled. Can be "x" or "y"
* @param {boolean} settings.glare - if it should have a "glare" effect
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {boolean} settings.reset-to-start - true = On reset event (mouse leave) will return to initial start angle (if startX or startY is set)
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
VanillaTilt.prototype.extendSettings = function extendSettings(settings) {
var defaultSettings = {
reverse: false,
max: 35,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
@ -357,13 +447,16 @@ var VanillaTilt = function () {
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
"reset-to-start": true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
var newSettings = {};

File diff suppressed because one or more lines are too long

177
dist/vanilla-tilt.js vendored
View file

@ -2,10 +2,10 @@ var VanillaTilt = (function () {
'use strict';
/**
* Created by Șandor Sergiu (micku7zu) on 1/27/2017.
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.6.0
* Version 1.8.1
*/
class VanillaTilt {
@ -16,31 +16,55 @@ class VanillaTilt {
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.elementListener = this.getElementListener();
this.reverse = this.settings.reverse ? -1 : 1;
this.resetToStart = VanillaTilt.isSettingTrue(this.settings["reset-to-start"]);
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.glare = this.isSettingTrue(this.settings.glare);
this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]);
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
if (this.resetToStart === false) {
this.settings.startX = 0;
this.settings.startY = 0;
}
}
isSettingTrue(setting) {
static isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
}
@ -49,8 +73,8 @@ class VanillaTilt {
* @return {Node}
*/
getElementListener() {
if (!this.settings || !this.settings["mouse-event-element"]) {
return this.element;
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
@ -64,6 +88,8 @@ class VanillaTilt {
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
}
/**
@ -78,13 +104,16 @@ class VanillaTilt {
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
}
/**
@ -92,11 +121,14 @@ class VanillaTilt {
*/
removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
}
@ -107,7 +139,10 @@ class VanillaTilt {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.element.style.willChange = "";
this.element.style.transition = "";
this.element.style.transform = "";
this.resetGlare();
this.removeEventListeners();
this.element.vanillaTilt = null;
@ -123,14 +158,29 @@ class VanillaTilt {
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
const degreesPerPixelX = totalAngleX / this.width;
const degreesPerPixelY = totalAngleY / this.height;
const angleX = event.gamma - this.settings.gyroscopeMinAngleX;
const angleY = event.beta - this.settings.gyroscopeMinAngleY;
const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
const posX = angleX / degreesPerPixelX;
const posY = angleY / degreesPerPixelY;
@ -171,18 +221,28 @@ class VanillaTilt {
}
reset() {
this.event = {
pageX: this.left + this.width / 2,
pageY: this.top + this.height / 2
};
this.onMouseEnter();
if (this.element && this.element.style) {
this.element.style.transform = `perspective(${this.settings.perspective}px) ` +
`rotateX(0deg) ` +
`rotateY(0deg) ` +
`scale3d(1, 1, 1)`;
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width),
clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height)
};
}
let backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
}
resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
@ -190,14 +250,21 @@ class VanillaTilt {
}
getValues() {
let x = (this.event.clientX - this.left) / this.width;
let y = (this.event.clientY - this.top) / this.height;
let x, y;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
let tiltX = (this.reverse * (this.settings.max / 2 - x * this.settings.max)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max - this.settings.max / 2)).toFixed(2);
let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
@ -270,7 +337,8 @@ class VanillaTilt {
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
"pointer-events": "none",
"border-radius": "inherit"
});
Object.assign(this.glareElement.style, {
@ -279,23 +347,38 @@ class VanillaTilt {
"left": "50%",
"pointer-events": "none",
"background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
"width": `${this.element.offsetWidth * 2}px`,
"height": `${this.element.offsetWidth * 2}px`,
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0",
"opacity": "0"
});
this.updateGlareSize();
}
updateGlareSize() {
Object.assign(this.glareElement.style, {
"width": `${this.element.offsetWidth * 2}`,
"height": `${this.element.offsetWidth * 2}`,
});
if (this.glare) {
const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": `${glareSize}px`,
"height": `${glareSize}px`,
});
}
}
updateClientSize() {
this.clientWidth = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
this.clientHeight = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
}
setTransition() {
@ -316,24 +399,31 @@ class VanillaTilt {
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {string|null} settings.axis - What axis should be enabled. Can be "x" or "y"
* @param {boolean} settings.glare - if it should have a "glare" effect
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {boolean} settings.reset-to-start - true = On reset event (mouse leave) will return to initial start angle (if startX or startY is set)
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
extendSettings(settings) {
let defaultSettings = {
reverse: false,
max: 35,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
@ -343,13 +433,16 @@ class VanillaTilt {
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
"reset-to-start": true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
let newSettings = {};

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,6 @@
# vanilla-tilt.js
[![npm version](https://badge.fury.io/js/vanilla-tilt.svg)](https://badge.fury.io/js/vanilla-tilt)
[![ghit.me](https://ghit.me/badge.svg?repo=micku7zu/vanilla-tilt.js)](https://ghit.me/repo/micku7zu/vanilla-tilt.js)
A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https://github.com/gijsroge/tilt.js).
@ -11,6 +10,8 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https
```html
<body>
<!-- your markup element -->
<div class="your-element" data-tilt></div>
<!-- at the end of the body -->
@ -18,23 +19,34 @@ A smooth 3D tilt javascript library forked from [Tilt.js (jQuery version)](https
</body>
```
If you want to use this library in IE, you need to include a CustomEvent polyfill: https://github.com/micku7zu/vanilla-tilt.js/issues/49#issuecomment-482711876 or maybe consider the [jQuery version](https://github.com/gijsroge/tilt.js).
### Options
```js
{
reverse: false, // reverse the tilt direction
max: 35, // max tilt rotation (degrees)
max: 15, // max tilt rotation (degrees)
startX: 0, // the starting tilt on the X axis, in degrees.
startY: 0, // the starting tilt on the Y axis, in degrees.
perspective: 1000, // Transform perspective, the lower the more extreme the tilt gets.
scale: 1, // 2 = 200%, 1.5 = 150%, etc..
speed: 300, // Speed of the enter/exit transition
transition: true, // Set a transition on enter/exit.
axis: null, // What axis should be disabled. Can be X or Y.
reset: true // If the tilt effect has to be reset on exit.
axis: null, // What axis should be enabled. Can be "x" or "y".
reset: true, // If the tilt effect has to be reset on exit.
"reset-to-start": true, // Whether the exit reset will go to [0,0] (default) or [startX, startY]
easing: "cubic-bezier(.03,.98,.52,.99)", // Easing on enter/exit.
glare: false // if it should have a "glare" effect
glare: false, // if it should have a "glare" effect
"max-glare": 1, // the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
"glare-prerender": false, // false = VanillaTilt creates the glare elements for you, otherwise
// you need to add .js-tilt-glare>.js-tilt-glare-inner by yourself
"mouse-event-element": null // css-selector or link to HTML-element what will be listen mouse events
"mouse-event-element": null, // css-selector or link to an HTML-element that will be listening to mouse events
"full-page-listening": false, // If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
gyroscope: true, // Boolean to enable/disable device orientation detection,
gyroscopeMinAngleX: -45, // This is the bottom limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the left border of the element;
gyroscopeMaxAngleX: 45, // This is the top limit of the device angle on X axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the right border of the element;
gyroscopeMinAngleY: -45, // This is the bottom limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the top border of the element;
gyroscopeMaxAngleY: 45, // This is the top limit of the device angle on Y axis, meaning that a device rotated at this angle would tilt the element as if the mouse was on the bottom border of the element;
gyroscopeSamples: 10 // How many gyroscope moves to decide the starting position.
}
```
@ -67,10 +79,10 @@ VanillaTilt.init(elements);
### Install
You can copy and include any of the following file:
* [dist/vanilla-tilt.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.js) ~ 6kb
* [dist/vanilla-tilt.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.min.js) ~ 3.5kb
* [dist/vanilla-tilt.babel.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.js) ~ 8.5kb
* [dist/vanilla-tilt.babel.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.min.js) ~ 4.3kb
* [dist/vanilla-tilt.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.js) ~ 15kb
* [dist/vanilla-tilt.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.min.js) ~ 8.5kb
* [dist/vanilla-tilt.babel.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.js) ~ 16.5kb
* [dist/vanilla-tilt.babel.min.js](https://raw.githubusercontent.com/micku7zu/vanilla-tilt.js/master/dist/vanilla-tilt.babel.min.js) ~ 9.5kb
#### NPM
@ -80,19 +92,39 @@ Also available on npm https://www.npmjs.com/package/vanilla-tilt
npm install vanilla-tilt
```
#### Typings
Import it using
Installing typings using npm
```
npm install @types/vanilla-tilt
import VanillaTilt from 'vanilla-tilt';
```
### Known issues
- [Getting weird rendering issues on Safari](https://github.com/micku7zu/vanilla-tilt.js/issues/22)
### Credits
Original library: [Tilt.js](http://gijsroge.github.io/tilt.js/)
Original library author: [Gijs Rogé](https://twitter.com/GijsRoge)
#### Contributors
- [Livio Brunner](https://github.com/BrunnerLivio) <<a href="mailto:contact@brunnerliv.io">contact@brunnerliv.io</a>> (Typings & Glare Effect)
- [Oleg Postoev](https://github.com/Dok11)
- [Matteo Rigon](https://github.com/matteo-rigon) (Device orientation support)
- [Corey Austin](https://github.com/lazyhummingbird) (Initial gyroscope position)
- [Sander Moolin](https://github.com/SaFrMo)
- [rrroyal](https://github.com/rrroyal) (Whole document mouse events listening)
- [Andžs Pilskalns](https://github.com/Pilskalns) ("reset-to-start" feature)
### Other projects
#### [Quick Cursor: One-Handed mode](https://play.google.com/store/apps/details?id=com.quickcursor) (Android app)
Play Store link: https://play.google.com/store/apps/details?id=com.quickcursor
### Buy me a beer 🍻
If you want to thank me for vanilla-tilt.js or Quick Cursor Android app, you can [donate on PayPal](https://www.paypal.me/micku7zu?locale.x=en_US): https://www.paypal.me/micku7zu?locale.x=en_US
### License
MIT License

View file

@ -1,8 +1,8 @@
/**
* Created by Șandor Sergiu (micku7zu) on 1/27/2017.
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.6.0
* Version 1.8.1
*/
class VanillaTilt {
@ -13,31 +13,55 @@ class VanillaTilt {
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.elementListener = this.getElementListener();
this.reverse = this.settings.reverse ? -1 : 1;
this.resetToStart = VanillaTilt.isSettingTrue(this.settings["reset-to-start"]);
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.glare = this.isSettingTrue(this.settings.glare);
this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]);
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
if (this.resetToStart === false) {
this.settings.startX = 0;
this.settings.startY = 0;
}
}
isSettingTrue(setting) {
static isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
}
@ -46,8 +70,8 @@ class VanillaTilt {
* @return {Node}
*/
getElementListener() {
if (!this.settings || !this.settings["mouse-event-element"]) {
return this.element;
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
@ -61,6 +85,8 @@ class VanillaTilt {
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
}
/**
@ -75,13 +101,16 @@ class VanillaTilt {
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
}
/**
@ -89,11 +118,14 @@ class VanillaTilt {
*/
removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
}
@ -104,7 +136,10 @@ class VanillaTilt {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.element.style.willChange = "";
this.element.style.transition = "";
this.element.style.transform = "";
this.resetGlare();
this.removeEventListeners();
this.element.vanillaTilt = null;
@ -120,14 +155,29 @@ class VanillaTilt {
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
const degreesPerPixelX = totalAngleX / this.width;
const degreesPerPixelY = totalAngleY / this.height;
const angleX = event.gamma - this.settings.gyroscopeMinAngleX;
const angleY = event.beta - this.settings.gyroscopeMinAngleY;
const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
const posX = angleX / degreesPerPixelX;
const posY = angleY / degreesPerPixelY;
@ -168,18 +218,28 @@ class VanillaTilt {
}
reset() {
this.event = {
pageX: this.left + this.width / 2,
pageY: this.top + this.height / 2
};
this.onMouseEnter();
if (this.element && this.element.style) {
this.element.style.transform = `perspective(${this.settings.perspective}px) ` +
`rotateX(0deg) ` +
`rotateY(0deg) ` +
`scale3d(1, 1, 1)`;
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width),
clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height)
};
}
let backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
}
resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
@ -187,14 +247,21 @@ class VanillaTilt {
}
getValues() {
let x = (this.event.clientX - this.left) / this.width;
let y = (this.event.clientY - this.top) / this.height;
let x, y;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
let tiltX = (this.reverse * (this.settings.max / 2 - x * this.settings.max)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max - this.settings.max / 2)).toFixed(2);
let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
@ -267,7 +334,8 @@ class VanillaTilt {
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
"pointer-events": "none",
"border-radius": "inherit"
});
Object.assign(this.glareElement.style, {
@ -276,23 +344,38 @@ class VanillaTilt {
"left": "50%",
"pointer-events": "none",
"background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
"width": `${this.element.offsetWidth * 2}px`,
"height": `${this.element.offsetWidth * 2}px`,
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0",
"opacity": "0"
});
this.updateGlareSize();
}
updateGlareSize() {
Object.assign(this.glareElement.style, {
"width": `${this.element.offsetWidth * 2}`,
"height": `${this.element.offsetWidth * 2}`,
});
if (this.glare) {
const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": `${glareSize}px`,
"height": `${glareSize}px`,
});
}
}
updateClientSize() {
this.clientWidth = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
this.clientHeight = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
}
setTransition() {
@ -313,24 +396,31 @@ class VanillaTilt {
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {string|null} settings.axis - What axis should be enabled. Can be "x" or "y"
* @param {boolean} settings.glare - if it should have a "glare" effect
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {boolean} settings.reset-to-start - true = On reset event (mouse leave) will return to initial start angle (if startX or startY is set)
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
extendSettings(settings) {
let defaultSettings = {
reverse: false,
max: 35,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
@ -340,13 +430,16 @@ class VanillaTilt {
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
"reset-to-start": true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
let newSettings = {};

View file

@ -7,10 +7,10 @@ var classCallCheck = function (instance, Constructor) {
};
/**
* Created by Șandor Sergiu (micku7zu) on 1/27/2017.
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.6.0
* Version 1.8.1
*/
var VanillaTilt = function () {
@ -24,31 +24,55 @@ var VanillaTilt = function () {
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.elementListener = this.getElementListener();
this.reverse = this.settings.reverse ? -1 : 1;
this.resetToStart = VanillaTilt.isSettingTrue(this.settings["reset-to-start"]);
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.glare = this.isSettingTrue(this.settings.glare);
this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]);
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
if (this.resetToStart === false) {
this.settings.startX = 0;
this.settings.startY = 0;
}
}
VanillaTilt.prototype.isSettingTrue = function isSettingTrue(setting) {
VanillaTilt.isSettingTrue = function isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
};
@ -59,8 +83,8 @@ var VanillaTilt = function () {
VanillaTilt.prototype.getElementListener = function getElementListener() {
if (!this.settings || !this.settings["mouse-event-element"]) {
return this.element;
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
@ -74,6 +98,8 @@ var VanillaTilt = function () {
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
};
/**
@ -90,13 +116,16 @@ var VanillaTilt = function () {
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
};
/**
@ -106,11 +135,14 @@ var VanillaTilt = function () {
VanillaTilt.prototype.removeEventListeners = function removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
};
@ -121,7 +153,10 @@ var VanillaTilt = function () {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.element.style.willChange = "";
this.element.style.transition = "";
this.element.style.transform = "";
this.resetGlare();
this.removeEventListeners();
this.element.vanillaTilt = null;
@ -137,14 +172,29 @@ var VanillaTilt = function () {
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
var totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
var totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
var degreesPerPixelX = totalAngleX / this.width;
var degreesPerPixelY = totalAngleY / this.height;
var angleX = event.gamma - this.settings.gyroscopeMinAngleX;
var angleY = event.beta - this.settings.gyroscopeMinAngleY;
var angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
var angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
var posX = angleX / degreesPerPixelX;
var posY = angleY / degreesPerPixelY;
@ -185,15 +235,28 @@ var VanillaTilt = function () {
};
VanillaTilt.prototype.reset = function reset() {
this.event = {
pageX: this.left + this.width / 2,
pageY: this.top + this.height / 2
};
this.onMouseEnter();
if (this.element && this.element.style) {
this.element.style.transform = "perspective(" + this.settings.perspective + "px) " + "rotateX(0deg) " + "rotateY(0deg) " + "scale3d(1, 1, 1)";
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width,
clientY: this.top + (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height
};
}
var backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
};
VanillaTilt.prototype.resetGlare = function resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
@ -201,14 +264,22 @@ var VanillaTilt = function () {
};
VanillaTilt.prototype.getValues = function getValues() {
var x = (this.event.clientX - this.left) / this.width;
var y = (this.event.clientY - this.top) / this.height;
var x = void 0,
y = void 0;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
var tiltX = (this.reverse * (this.settings.max / 2 - x * this.settings.max)).toFixed(2);
var tiltY = (this.reverse * (y * this.settings.max - this.settings.max / 2)).toFixed(2);
var tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
var tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
var angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
@ -280,7 +351,8 @@ var VanillaTilt = function () {
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
"pointer-events": "none",
"border-radius": "inherit"
});
Object.assign(this.glareElement.style, {
@ -289,23 +361,34 @@ var VanillaTilt = function () {
"left": "50%",
"pointer-events": "none",
"background-image": "linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)",
"width": this.element.offsetWidth * 2 + "px",
"height": this.element.offsetWidth * 2 + "px",
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0"
});
this.updateGlareSize();
};
VanillaTilt.prototype.updateGlareSize = function updateGlareSize() {
Object.assign(this.glareElement.style, {
"width": "" + this.element.offsetWidth * 2,
"height": "" + this.element.offsetWidth * 2
});
if (this.glare) {
var glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": glareSize + "px",
"height": glareSize + "px"
});
}
};
VanillaTilt.prototype.updateClientSize = function updateClientSize() {
this.clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
this.clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
};
VanillaTilt.prototype.onWindowResize = function onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
};
VanillaTilt.prototype.setTransition = function setTransition() {
@ -327,26 +410,33 @@ var VanillaTilt = function () {
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {string|null} settings.axis - What axis should be enabled. Can be "x" or "y"
* @param {boolean} settings.glare - if it should have a "glare" effect
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {boolean} settings.reset-to-start - true = On reset event (mouse leave) will return to initial start angle (if startX or startY is set)
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
VanillaTilt.prototype.extendSettings = function extendSettings(settings) {
var defaultSettings = {
reverse: false,
max: 35,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
@ -356,13 +446,16 @@ var VanillaTilt = function () {
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
"reset-to-start": true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
var newSettings = {};

7794
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,12 @@
{
"name": "vanilla-tilt",
"version": "1.6.0",
"version": "1.8.1",
"description": "A smooth 3D tilt javascript library forked from Tilt.js",
"main": "lib/vanilla-tilt.js",
"module_es2015": "lib/vanilla-tilt.es2015.js",
"jsnext:main": "lib/vanilla-tilt.es2015.js",
"distrib": "dist/vanilla-tilt.js",
"types": "vanilla-tilt.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npm run build:lib && cp ./README.md ./lib",
@ -28,7 +29,7 @@
"babelrc-rollup": "^3.0.0",
"cash-cp": "^0.2.0",
"cross-env": "^3.1.4",
"gh-pages": "^0.12.0",
"gh-pages": "^4.0.0",
"release-script": "^1.0.2",
"rollup": "^0.41.4",
"rollup-plugin-babel": "^2.7.1",

View file

@ -1,8 +1,8 @@
/**
* Created by Șandor Sergiu (micku7zu) on 1/27/2017.
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.6.0
* Version 1.8.1
*/
export default class VanillaTilt {
@ -13,31 +13,55 @@ export default class VanillaTilt {
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.elementListener = this.getElementListener();
this.reverse = this.settings.reverse ? -1 : 1;
this.resetToStart = VanillaTilt.isSettingTrue(this.settings["reset-to-start"]);
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.glare = this.isSettingTrue(this.settings.glare);
this.glarePrerender = this.isSettingTrue(this.settings["glare-prerender"]);
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
if (this.resetToStart === false) {
this.settings.startX = 0;
this.settings.startY = 0;
}
}
isSettingTrue(setting) {
static isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
}
@ -46,8 +70,8 @@ export default class VanillaTilt {
* @return {Node}
*/
getElementListener() {
if (!this.settings || !this.settings["mouse-event-element"]) {
return this.element;
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
@ -61,6 +85,8 @@ export default class VanillaTilt {
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
}
/**
@ -75,13 +101,16 @@ export default class VanillaTilt {
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
}
/**
@ -89,11 +118,14 @@ export default class VanillaTilt {
*/
removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.glare) {
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
}
@ -104,7 +136,10 @@ export default class VanillaTilt {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.element.style.willChange = "";
this.element.style.transition = "";
this.element.style.transform = "";
this.resetGlare();
this.removeEventListeners();
this.element.vanillaTilt = null;
@ -120,14 +155,29 @@ export default class VanillaTilt {
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
const degreesPerPixelX = totalAngleX / this.width;
const degreesPerPixelY = totalAngleY / this.height;
const angleX = event.gamma - this.settings.gyroscopeMinAngleX;
const angleY = event.beta - this.settings.gyroscopeMinAngleY;
const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
const posX = angleX / degreesPerPixelX;
const posY = angleY / degreesPerPixelY;
@ -168,18 +218,28 @@ export default class VanillaTilt {
}
reset() {
this.event = {
pageX: this.left + this.width / 2,
pageY: this.top + this.height / 2
};
this.onMouseEnter();
if (this.element && this.element.style) {
this.element.style.transform = `perspective(${this.settings.perspective}px) ` +
`rotateX(0deg) ` +
`rotateY(0deg) ` +
`scale3d(1, 1, 1)`;
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width),
clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height)
};
}
let backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
}
resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
@ -187,14 +247,21 @@ export default class VanillaTilt {
}
getValues() {
let x = (this.event.clientX - this.left) / this.width;
let y = (this.event.clientY - this.top) / this.height;
let x, y;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
let tiltX = (this.reverse * (this.settings.max / 2 - x * this.settings.max)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max - this.settings.max / 2)).toFixed(2);
let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
@ -267,7 +334,8 @@ export default class VanillaTilt {
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
"pointer-events": "none",
"border-radius": "inherit"
});
Object.assign(this.glareElement.style, {
@ -276,23 +344,38 @@ export default class VanillaTilt {
"left": "50%",
"pointer-events": "none",
"background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
"width": `${this.element.offsetWidth * 2}px`,
"height": `${this.element.offsetWidth * 2}px`,
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0",
"opacity": "0"
});
this.updateGlareSize();
}
updateGlareSize() {
Object.assign(this.glareElement.style, {
"width": `${this.element.offsetWidth * 2}`,
"height": `${this.element.offsetWidth * 2}`,
});
if (this.glare) {
const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": `${glareSize}px`,
"height": `${glareSize}px`,
});
}
}
updateClientSize() {
this.clientWidth = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
this.clientHeight = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
}
setTransition() {
@ -313,24 +396,31 @@ export default class VanillaTilt {
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {string|null} settings.axis - What axis should be enabled. Can be "x" or "y"
* @param {boolean} settings.glare - if it should have a "glare" effect
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {boolean} settings.reset-to-start - true = On reset event (mouse leave) will return to initial start angle (if startX or startY is set)
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
extendSettings(settings) {
let defaultSettings = {
reverse: false,
max: 35,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
@ -340,13 +430,16 @@ export default class VanillaTilt {
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
"reset-to-start": true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
let newSettings = {};

140
test/index.html Normal file
View file

@ -0,0 +1,140 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Vanilla-tilt.js</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
}
a {
text-decoration: none;
color: #333;
}
.logo {
display: block;
width: 100%;
max-width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
color: white;
font-size: 2em;
background: #0099F7; /* fallback for old browsers */
background: -webkit-linear-gradient(135deg, #0099F7, #F11712); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(135deg, #0099F7, #F11712); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform: perspective(500px);
transform: perspective(500px);
margin-bottom: 75px;
}
.logo > span {
position: relative;
display: block;
-webkit-transform: translateZ(50px) scale(0.7);
transform: translateZ(50px) scale(0.7);
}
.logo > span:after {
content: "GitHub";
position: absolute;
color: white;
font-size: 18px;
top: 36px;
left: 50%;
transform: translateX(-50%);
opacity: 0.8;
transition: 0.3s ease all;
}
.logo > span:before {
content: "View source";
position: absolute;
color: white;
font-size: 18px;
top: 36px;
left: 50%;
transform: translateX(-50%) translateY(-10px);
opacity: 0;
display: inline-block;
width: 100%;
transition: 0.3s ease all;
}
.logo:hover > span:after {
opacity: 0;
transform: translateX(-50%) translateY(10px);
}
.logo:hover > span:before {
opacity: 0.8;
transform: translateX(-50%);
}
.logo > span > span {
display: block;
font-size: 12px;
}
.logo:after {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: #333;
box-shadow: 0 20px 70px -10px rgba(51, 51, 51, 0.7), 0 50px 100px 0 rgba(51, 51, 51, 0.2);
z-index: -1;
-webkit-transform: translateZ(-50px);
transform: translateZ(-50px);
-webkit-transition: .3s;
transition: .3s;
}
</style>
</head>
<body>
<a href="https://github.com/micku7zu/vanilla-tilt.js" class="logo" id="logo"
data-tilt data-tilt-glare="true"
data-tilt-max-glare="0.5"
data-tilt-speed="400"
data-tilt-scale="1.1"
data-tilt-perspective="500"
data-tilt-max="15"
data-tilt-startX="15"
data-tilt-startY="30"
>
<span>vanilla-tilt.js</span>
</a>
<script type="text/javascript" src="../dist/vanilla-tilt.js"></script>
</body>
</html>

168
vanilla-tilt.d.ts vendored Normal file
View file

@ -0,0 +1,168 @@
// Extended Type definitions for vanilla-tilt 1.8.1
// Project: https://github.com/micku7zu/vanilla-tilt.js
// Definitions by: Livio Brunner <https://github.com/BrunnerLivio>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/**
* Options which configures the tilting
*/
export interface TiltOptions {
/**
* Reverse the tilt direction
*/
reverse?: boolean;
/**
* Max tilt rotation (degrees)
*/
max?: number;
/**
* Starting X tilt rotation (degrees)
*/
startX?: number;
/**
* Starting Y tilt rotation (degrees)
*/
startY?: number;
/**
* Transform perspective, the lower the more extreme the tilt gets.
*/
perspective?: number;
/**
* 2 = 200%, 1.5 = 150%, etc..
*/
scale?: number;
/**
* Speed of the enter/exit transition
*/
speed?: number;
/**
* Set a transition on enter/exit.
*/
transition?: boolean;
/**
* What axis should be enabled. Can be "x" or "y".
*/
axis?: null | "x" | "y";
/**
* If the tilt effect has to be reset on exit.
*/
reset?: boolean;
/**
* Whether the exit reset will go to [0,0] (default) or [startX, startY].
*/
"reset-to-start"?: boolean;
/**
* Easing on enter/exit.
*/
easing?: string;
/**
* if it should have a "glare" effect
*/
glare?: boolean;
/**
* the maximum "glare" opacity
*/
"max-glare"?: number;
/**
* false = VanillaTilt creates the glare elements for you, otherwise
* you need to add .js-tilt-glare>.js-tilt-glare-inner by yourself
*/
"glare-prerender"?: boolean;
// If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
"full-page-listening"?: boolean;
// Boolean to enable/disable device orientation detection,
gyroscope?: boolean;
// css-selector or link to HTML-element what will be listen mouse events
"mouse-event-element"?: string;
// This is the bottom limit of the device angle on X axis,
// meaning that a device rotated at this angle would tilt the element as if
// the mouse was on the left border of the element;
gyroscopeMinAngleX?: number
// This is the top limit of the device angle on X axis,
// meaning that a device rotated at this angle would tilt the element as if
// the mouse was on the right border of the element;
gyroscopeMaxAngleX?: number
// This is the bottom limit of the device angle on Y axis,
// meaning that a device rotated at this angle would tilt the element as if
// the mouse was on the top border of the element;
gyroscopeMinAngleY?: number
// This is the top limit of the device angle on Y axis,
// meaning that a device rotated at this angle would tilt the element as if
// the mouse was on the bottom border of the element;
gyroscopeMaxAngleY?: number
//How many gyroscope moves to decide the starting position.
gyroscopeSamples?: number
}
export interface TiltValues {
/**
* The current tilt on the X axis
*/
tiltX: number;
/**
* The current tilt on the Y axis
*/
tiltY: number;
/**
* The current percentage on the X axis
*/
percentageX: number;
/**
* The current percentage on the Y axis
*/
percentageY: number;
}
export interface HTMLVanillaTiltElement extends HTMLElement {
vanillaTilt: VanillaTilt;
}
/**
* A smooth 3D tilt javascript library forked from Tilt.js (jQuery version).
*/
export default class VanillaTilt {
/**
* Creates a new instance of a VanillaTilt element.
* @param element The element, which should be a VanillaTilt element
* @param settings Settings which configures the element
*/
constructor(element: HTMLElement, settings?: TiltOptions);
/**
* Initializes one or multiple elements
* @param elements The element, which should tilt
* @param settings Settings, which configures the elements
*/
static init(elements: HTMLElement | HTMLElement[], settings?: TiltOptions): void;
/**
* Resets the styling
*/
reset(): void;
/**
* Get values of instance
*/
getValues(): TiltValues;
/**
* Destroys the instance and removes the listeners.
*/
destroy(): void;
/**
* Start listening to events
*/
addEventListeners(): void;
/**
* Stop listening to events
*/
removeEventListener(): void;
}