Skip to content

Instantly share code, notes, and snippets.

@TravisMullen
Created July 17, 2017 12:03
Show Gist options
  • Save TravisMullen/add7d00d17966b1f13f9d35c39ab2c64 to your computer and use it in GitHub Desktop.
Save TravisMullen/add7d00d17966b1f13f9d35c39ab2c64 to your computer and use it in GitHub Desktop.
<!-- <parallax>
<img class="color" src="static/img/rainbow_main_45q.jpg">
</parallax> -->
<template>
<div :class="[sectionClass]" ref="container">
<!-- foreground-content -->
<div
class="foreground-content"
ref="foreground">
<slot name="foreground"></slot>
</div>
<div
:class="[parallax ? parallaxClass : '', fixed ? fixedClass : '', containerClass]"
ref="parallax"
>
<!-- default slot for main image -->
<slot></slot>
</div>
<!-- background-content -->
<div
class="background-content"
ref="background">
<slot name="background"></slot>
</div>
</div>
</template>
<script>
import 'web-animations-js'
export default {
props: {
parallax: {
default: true,
type: Boolean
},
speedFactor: {
default: 0.15,
type: Number
},
fixed: {
default: false,
type: Boolean
},
breakpoint: {
default: '(min-width: 568px)',
type: String
},
sectionHeight: {
// default: '.parallax > img',
default: 90,
type: Number,
required: false
},
sectionClass: {
type: String,
default: 'container'
},
containerClass: {
type: String,
default: 'parallax-row-content'
},
parallaxClass: {
type: String,
default: 'is-parallax'
},
fixedClass: {
type: String,
default: 'is-fixed'
},
direction: {
type: String,
default: 'up'
}
},
data () {
return {
el: null,
height: 0,
mediaQuery: null,
animationValue: 0
}
},
mounted () {
console.log('this.parallax && !this.fixed', this.parallax && !this.fixed)
if (this.parallax && !this.fixed) {
this.el = this.$refs.parallax
// window.requestAnimationFrame = window.requestAnimationFrame ||
// window.mozRequestAnimationFrame ||
// window.webkitRequestAnimationFrame ||
// window.msRequestAnimationFrame ||
// function (f) {
// setTimeout(f, 1000 / 60)
// }
this.init()
}
// console.log('mounted', this.$refs)
},
beforeDestory () {
window.removeEventListener('scroll', this.scrollHandler, false)
},
methods: {
animateElement () {
const elms = this.$refs.parallax.querySelector('img')
console.log('.parallax > img', elms)
const parentHeight = this.$refs.container.offsetHeight
// console.log('parentHeight', parentHeight)
const parallaxHeight = this.$refs.parallax.offsetHeight
// console.log('parentHeight', parentHeight)
const availableOffset = parallaxHeight - parentHeight
// console.log('availableOffset', availableOffset)
let animationValue = (window.pageYOffset * this.speedFactor)
// console.log('animationValue', animationValue)
if (animationValue <= availableOffset && animationValue >= 0) {
this.animationValue = animationValue * 1
console.log('this.animationValue', this.animationValue)
// this.el.style.transform = `translate3d(0, ${this.animationValue}px ,0)`c
elms.style.marginLeft = elms.style.marginLeft + 20
}
},
scrollHandler () {
// replace request animation frame with web animation
window.requestAnimationFrame(() => {
if (this.isInView(this.$refs.parallax)) {
this.animateElement()
}
})
// debounce and push animation
console.log('scrollHandler')
},
isInView (el) {
// has component come above the fold into view
let rect = el.getBoundingClientRect()
return (
rect.bottom >= 0 &&
rect.top <= (window.innerHeight || document.documentElement.clientHeight)
)
},
setupListener () {
// if (this.mediaQuery.matches) {
window.addEventListener('scroll', this.scrollHandler, false)
// } else {
// window.removeEventListener('scroll', this.scrollHandler, false)
// }
// console.log('setupListener')
},
init () {
// console.log('this.breakpoint', this.breakpoint)
// this.mediaQuery = window.matchMedia(this.breakpoint)
// console.log('this.mediaQuery', this.mediaQuery)
// console.log('this.mediaQuery.matches', this.mediaQuery.matches)
// if (this.mediaQuery) {
// this.mediaQuery.addListener(this.setupListener)
this.setupListener()
// }
console.log('init')
}
},
computed: {
directionValue () {
return this.direction === 'down' ? +1 : -1
}
}
}
</script>
<style lang="scss">
// @import "~@nextindex/next-scss/next-scss";
.container {
position: relative;
min-height: 250px;
max-height: 350px;
scroll-behavior: smooth;
overflow: hidden;
z-index: -1;
&.container-content {
// min-height: 100vh;
// width: 100%;
// overflow: hidden;
// height: 120%;
// img {
height: auto;
max-width: none;
width: 100vw;
// object-fit: cover;
// }
&.is-parallax {
// left: 0;
// position: absolute;
// will-change: transform;
// right: 0;
// height: 10px;
// top: 0;
// > img {
// border: 1px solid red;
// height: auto;
// max-width: 100vw;
// width: 100vw;
// // object-fit: cover;
// }
}
&.is-fixed {
position: fixed;
will-change: transform;
> img {
height: 100vh;
max-width: none;
}
}
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment