vue-js-parallax-component
Version:
Parallax component for Vue
181 lines (161 loc) • 8.05 kB
JavaScript
var VueParallax = (function (exports, vueRuntimeHelpers) {
'use strict';
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
var script = {
props: {
image: { type: String, required: true },
intensity: { type: Number, default: 15 }
},
data: function data() {
return {
el: null,
conatiner: null,
imageHeight: 0,
defaultHeight: 360
};
},
mounted: function mounted() {
var this$1 = this;
// Extract the height from the style property of the container
var h = Number(window.getComputedStyle(this.$el).height.replace("px", ""));
if (!h) {
this.$refs.container.style.height = this.defaultHeight + "px";
h = this.defaultHeight;
}
/* eslint-disable no-console */
this.imageHeight = this.getHeight(h) + "px";
setTimeout(function () {
this$1.animationTrigger(false); // trigger to correct but without animationRequest
}, 25);
this.el = this.$refs.image;
this.container = this.$refs.container;
window.addEventListener("scroll", this.animationTrigger);
},
destroyed: function destroyed() {
window.removeEventListener("scroll", this.animationTrigger);
},
methods: {
animationTrigger: function animationTrigger(animationRequest) {
var this$1 = this;
if ( animationRequest === void 0 ) animationRequest = true;
var vpo = this.container.getBoundingClientRect();
var animate = function () {
if (
vpo.top < window.innerHeight &&
vpo.top * -1 < this$1.container.offsetHeight
) {
// only animate when in range of window
this$1.el.style.transform = "translateY(" + (vpo.top /
this$1.getIntensity()) + "px)";
}
};
if (animationRequest) {
window.requestAnimationFrame(function () {
animate();
});
} else {
animate();
}
},
getIntensity: function getIntensity() {
var intensity = 21 - this.intensity;
if (intensity <= 1) {
return -2;
}
if (intensity >= 20) {
return -19;
}
return intensity * -1;
},
getHeight: function getHeight(h) {
return h + window.innerHeight / (this.getIntensity() * -1);
}
}
};
/* script */
var __vue_script__ = script;
/* template */
var __vue_render__ = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("div", { ref: "container", staticClass: "parallax__container" }, [
_c("div", {
ref: "image",
staticClass: "parallax__image",
style: {
backgroundImage: "url(" + _vm.image + ")",
height: _vm.imageHeight
}
}),
_vm._v(" "),
_c("div", { staticClass: "parallax__slot" }, [_vm._t("default")], 2)
])
};
var __vue_staticRenderFns__ = [];
__vue_render__._withStripped = true;
/* style */
var __vue_inject_styles__ = function (inject) {
if (!inject) { return }
inject("data-v-24d82b59_0", { source: "\n.parallax__container {\n width: 100%;\n position: relative;\n overflow: hidden;\n backface-visibility: hidden;\n}\n.parallax__image {\n width: 100%;\n position: absolute;\n background-size: cover;\n background-position: 50% 50%;\n left: 0;\n}\n.parallax__slot {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 2;\n}\n", map: {"version":3,"sources":["/Users/juriankoning/Sites/vue-parallax/src/vue-parallax.vue"],"names":[],"mappings":";AAuFA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,2BAAA;AACA;AACA;EACA,WAAA;EACA,kBAAA;EACA,sBAAA;EACA,4BAAA;EACA,OAAA;AACA;AACA;EACA,kBAAA;EACA,OAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,UAAA;AACA","file":"vue-parallax.vue","sourcesContent":["<template>\n <div class=\"parallax__container\" ref=\"container\">\n <div\n class=\"parallax__image\"\n ref=\"image\"\n :style=\"{\n backgroundImage: `url(${image})`,\n height: imageHeight\n }\"\n ></div>\n <div class=\"parallax__slot\">\n <slot></slot>\n </div>\n </div>\n</template>\n\n<script>\nexport default {\n props: {\n image: { type: String, required: true },\n intensity: { type: Number, default: 15 }\n },\n data() {\n return {\n el: null,\n conatiner: null,\n imageHeight: 0,\n defaultHeight: 360\n };\n },\n mounted() {\n // Extract the height from the style property of the container\n let h = Number(window.getComputedStyle(this.$el).height.replace(\"px\", \"\"));\n if (!h) {\n this.$refs.container.style.height = this.defaultHeight + \"px\";\n h = this.defaultHeight;\n }\n /* eslint-disable no-console */\n this.imageHeight = this.getHeight(h) + \"px\";\n setTimeout(() => {\n this.animationTrigger(false); // trigger to correct but without animationRequest\n }, 25);\n this.el = this.$refs.image;\n this.container = this.$refs.container;\n window.addEventListener(\"scroll\", this.animationTrigger);\n },\n destroyed() {\n window.removeEventListener(\"scroll\", this.animationTrigger);\n },\n methods: {\n animationTrigger(animationRequest = true) {\n const vpo = this.container.getBoundingClientRect();\n const animate = () => {\n if (\n vpo.top < window.innerHeight &&\n vpo.top * -1 < this.container.offsetHeight\n ) {\n // only animate when in range of window\n this.el.style.transform = `translateY(${vpo.top /\n this.getIntensity()}px)`;\n }\n };\n if (animationRequest) {\n window.requestAnimationFrame(() => {\n animate();\n });\n } else {\n animate();\n }\n },\n getIntensity() {\n const intensity = 21 - this.intensity;\n if (intensity <= 1) {\n return -2;\n }\n if (intensity >= 20) {\n return -19;\n }\n return intensity * -1;\n },\n getHeight(h) {\n return h + window.innerHeight / (this.getIntensity() * -1);\n }\n }\n};\n</script>\n<style>\n.parallax__container {\n width: 100%;\n position: relative;\n overflow: hidden;\n backface-visibility: hidden;\n}\n.parallax__image {\n width: 100%;\n position: absolute;\n background-size: cover;\n background-position: 50% 50%;\n left: 0;\n}\n.parallax__slot {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: 2;\n}\n</style>\n"]}, media: undefined });
};
/* scoped */
var __vue_scope_id__ = undefined;
/* module identifier */
var __vue_module_identifier__ = undefined;
/* functional template */
var __vue_is_functional_template__ = false;
/* style inject SSR */
/* style inject shadow dom */
var __vue_component__ = vueRuntimeHelpers.normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
vueRuntimeHelpers.createInjector,
undefined,
undefined
);
// Import vue component
// Declare install function executed by Vue.use()
function install(Vue) {
if (install.installed) { return; }
install.installed = true;
Vue.component("VueParallax", __vue_component__);
}
// Create module definition for Vue.use()
var plugin = {
install: install
};
// Auto-install when vue is found (eg. in browser via <script> tag)
var GlobalVue = null;
if (typeof window !== "undefined") {
GlobalVue = window.Vue;
} else if (typeof global !== "undefined") {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
exports.default = __vue_component__;
exports.install = install;
return exports;
}({}, vueRuntimeHelpers));