JSFiddle - React, Tailwind, and code Playground
Vue + intersection observers, mixin method
by Travis Almand
HTML
<div id="app">
<section-a></section-a>
<section-b></section-b>
<section-b></section-b>
</div>
CSS
.full-height {
background-color: gainsboro;
min-height: 100vh;
}
.half-height {
background-color: gray;
border: 1px solid black;
min-height: 50vh;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-left-enter-active,
.fade-left-leave-active {
position: absolute;
transition: 0.5s;
}
.fade-left-enter,
.fade-left-leave-to {
opacity: 0;
transform: translate3d(100px, 0, 0);
}
Vue
console.clear();
const intersectionObserver = {
props: {
io_root: {
type: String,
default: null
},
io_rootMargin: {
type: String,
default: '0px'
},
io_threshold: {
type: Array,
default: function () {
return [0, 0.25, 0.5, 0.75, 1];
}
}
},
data: function () {
return {
io_options: {
root: this.io_root,
rootMargin: this.io_rootMargin,
threshold: this.io_threshold
},
io_entries: null,
io_observer: null,
io_ratio_0: false,
io_ratio_25: false,
io_ratio_50: false,
io_ratio_75: false,
io_ratio_100: false
}
},
methods: {
io_callback: function (entries, observer) {
this.io_entries = entries;
this.io_observer = observer;
this.io_ratio_0 = entries[0].intersectionRatio > 0;
this.io_ratio_25 = entries[0].intersectionRatio > 0.25;
this.io_ratio_50 = entries[0].intersectionRatio > 0.5;
this.io_ratio_75 = entries[0].intersectionRatio > 0.75;
this.io_ratio_100 = entries[0].intersectionRatio === 1;
}
},
mounted: function () {
const observer = new IntersectionObserver(this.io_callback, this.io_options);
observer.observe(this.$el);
}
};
Vue.component('section-a', {
mixins: [intersectionObserver],
template: `
<div class="full-height">
section a
</div>`
});
Vue.component('section-b', {
mixins: [intersectionObserver],
template: `
<div class="full-height">
<transition name="fade">
<div v-if="io_ratio_0">greater than 0</div>
</transition>
<transition name="fade">
<div v-if="io_ratio_25">greater than 25</div>
</transition>
<transition name="fade-left">
<div v-if="io_ratio_50">greater than 50</div>
</transition>
<transition name="fade">
<div v-if="io_ratio_75">greater than 75</div>
</transition>
<transition name="fade">
<div v-if="io_ratio_100">at 100</div>
...