
Atropos is a JavaScript library that applies interactive and touch-friendly 3D parallax hover effects (also known as parallax tilt effects) to a group of images.
Based on Pointer Events and CSS3 transitions & transforms.
See Also:
- Apple tvOS Style Parallax Hover Effect with Vanilla JavaScript
- 3D Product Card With Interactive Movement Animation
- Interactive Parallax Tilt Effect In Vanilla JavaScript – vanilla-tilt.js
- Apple tv 3D Parallax Effect On Hover
- Apple tv Inspired Interactive Parallax Effect With jQuery And CSS3
- Apple tv Poster Parallax Effect with jQuery and CSS3 – maximusParallaximus
How to use it:
1. Install the Atropos with NPM.
# NPM $ npm i atropos --save
2. Import the Atropos.
import Atropos from './build/esm/atropos.esm'; import './build/atropos.css';
3. Add images to the Atropos container and determine the element’s offset/translate in percentage as follows:
<div href="#" class="atropos atropos-banner">
<div class="atropos-scale">
<div class="atropos-rotate">
<div class="atropos-inner">
<img class="atropos-banner-spacer" src="./i/atropos-bg.svg">
<img data-atropos-offset="-4.5" src="./i/atropos-bg.svg">
<img data-atropos-offset="-2.5" src="./i/atropos-mountains.svg">
<img data-atropos-offset="0" src="./i/atropos-forest-back.svg">
<img data-atropos-offset="2" src="./i/atropos-forest-mid.svg">
<img data-atropos-offset="4" src="./i/atropos-forest-front.svg">
<img data-atropos-offset="5" src="./i/atropos-logo-en.svg">
</div>
</div>
</div>
</div>4. Activate the Atropos and done.
window.atropos = new Atropos({
el: document.querySelectorAll('.atropos')[0],
});5. You can also apply opacity transitions to those parallax images.
<div href="#" class="atropos atropos-banner">
<div class="atropos-scale">
<div class="atropos-rotate">
<div class="atropos-inner">
<img class="atropos-banner-spacer" src="./i/atropos-bg.svg">
<img data-atropos-offset="-4.5" data-atropos-opacity="0.1;0.8" src="./i/atropos-bg.svg">
<img data-atropos-offset="-2.5" src="./i/atropos-mountains.svg">
<img data-atropos-offset="0" data-atropos-opacity="1;0" src="./i/atropos-forest-back.svg">
<img data-atropos-offset="2" src="./i/atropos-forest-mid.svg">
<img data-atropos-offset="4" src="./i/atropos-forest-front.svg">
<img data-atropos-offset="5" data-atropos-opacity="0;1" src="./i/atropos-logo-en.svg">
</div>
</div>
</div>
</div>6. Available configs to customize the 3D parallax hover effect.
window.atropos = new Atropos({
// target element
el: document.querySelectorAll('.atropos')[0],
// keep Atropos "activated"/"entered" all the time
alwaysActive: false,
// active offset in px
activeOffset: 50,
// shadow offset in px
shadowOffset: 50,
// shadow scale factor
shadowScale: 1,
// duration
duration: 300,
// rotate container on pointer move
rotate: true,
// rotate container on touch move
rotateTouch: true,
// max rotation along the X-axis
rotateXMax: 15,
// max rotation along the Y-axis
rotateYMax: 15,
// inverts rotation
rotateXInvert: false,
rotateYInvert: false,
// set translate offset for multiple Atropos elements in the same container
stretchX: 0,
stretchY: 0,
stretchZ: 0,
// for multiple Atropos elements in the same container
commonOrigin: true,
// show shadow
shadow: true,
// enable highlight
highlight: true,
// callbacks
onEnter: function(){
// do something
}
onLeave: function(){
// do something
}
onRotate: function(x, y){
// do something
}
});7. Available properties and API methods.
// get the current element instance.el; // check if is active instance.isActive // get options instance.params; // destroy the instance instance.destroy(); // check if is destroyed instance.destroyed
8. The library also works with React framework.
// main.js
import React from 'react';
import ReactDOM from 'react-dom';
import './build/atropos.css';
import App from './App.jsx';
ReactDOM.render(React.createElement(App), document.getElementById('app'));// app.jsx
import React from 'react';
import Atropos from './build/react';
const App = () => {
return (
<div className="container">
<Atropos className="atropos-banner" highlight={false} onEnter={() => console.log('enter')}>
<img className="atropos-banner-spacer" src="./i/atropos-bg.svg" alt="" />
<img data-atropos-offset="-4.5" src="./i/atropos-bg.svg" alt="" />
<img data-atropos-offset="-2.5" src="./i/atropos-mountains.svg" alt="" />
<img data-atropos-offset="0" src="./i/atropos-forest-back.svg" alt="" />
<img data-atropos-offset="2" src="./i/atropos-forest-mid.svg" alt="" />
<img data-atropos-offset="4" src="./i/atropos-forest-front.svg" alt="" />
<img data-atropos-offset="5" src="./i/atropos-logo-en.svg" alt="" />
</Atropos>
</div>
);
};
export default App;9. And Vue framework.
import { createApp } from 'vue';
import './build/atropos.css';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');// app.vue
<template>
<div class="container">
<Atropos class="atropos-banner" @enter="onEnter">
<img class="atropos-banner-spacer" src="./i/atropos-bg.svg" alt="" />
<img data-atropos-offset="-4.5" src="./i/atropos-bg.svg" alt="" />
<img data-atropos-offset="-2.5" src="./i/atropos-mountains.svg" alt="" />
<img data-atropos-offset="0" src="./i/atropos-forest-back.svg" alt="" />
<img data-atropos-offset="2" src="./i/atropos-forest-mid.svg" alt="" />
<img data-atropos-offset="4" src="./i/atropos-forest-front.svg" alt="" />
<img data-atropos-offset="5" src="./i/atropos-logo-en.svg" alt="" />
</Atropos>
</div>
</template>
<script>
import Atropos from './build/vue';
export default {
components: {
Atropos,
},
setup() {
const onEnter = () => {
console.log('Enter');
};
return {
onEnter,
};
},
};
</script>Changelog:
v2.0.1 (06/28/2023)
- add Atropos web component
- add element types + refactor package structure
- remove Vue and Svelte components
v1.0.2 (02/17/2022)
- Bug Fixes
v1.0.1 (10/18/2021)
- new alwaysActive parameter to keep Atropos “activated”/”entered” all the time
- new stretchZ parameter to set translateZ offset for multiple Atropos elements in same container (with same eventsEl)
- new commonOrigin parameter for multiple Atropos elements in same container (with same eventsEl)
- remove rotateLock functionality in favor of new smooth rotation
v1.0.0beta2 (10/16/2021)
- new alwaysActive parameter to keep Atropos “activated”/”entered” all the time
- new stretchZ parameter to set translateZ offset for multiple Atropos elements in same container (with same eventsEl)
- new commonOrigin parameter for multiple Atropos elements in same container (with same eventsEl)
v1.0.0beta1 (10/15/2021)
- removed durationEnter parameter
- removed durationLeave parameter
- removed rotateLock parameter
- added single duration parameter
v0.10.1 (10/12/2021)
- Bug Fixes
v0.9.6 (09/27/2021)
- Bug Fixes







