vue-photo-collage
Version:
A photo collage component for Vue.js
670 lines (580 loc) • 20.5 kB
JavaScript
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
const options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
let hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
const originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
const existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
const isOldIE = typeof navigator !== 'undefined' &&
/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());
function createInjector(context) {
return (id, style) => addStyle(id, style);
}
let HEAD;
const styles = {};
function addStyle(id, css) {
const group = isOldIE ? css.media || 'default' : id;
const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] });
if (!style.ids.has(id)) {
style.ids.add(id);
let code = css.source;
if (css.map) {
// https://developer.chrome.com/devtools/docs/javascript-debugging
// this makes source maps inside style tags work properly in Chrome
code += '\n/*# sourceURL=' + css.map.sources[0] + ' */';
// http://stackoverflow.com/a/26603875
code +=
'\n/*# sourceMappingURL=data:application/json;base64,' +
btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
' */';
}
if (!style.element) {
style.element = document.createElement('style');
style.element.type = 'text/css';
if (css.media)
style.element.setAttribute('media', css.media);
if (HEAD === undefined) {
HEAD = document.head || document.getElementsByTagName('head')[0];
}
HEAD.appendChild(style.element);
}
if ('styleSheet' in style.element) {
style.styles.push(code);
style.element.styleSheet.cssText = style.styles
.filter(Boolean)
.join('\n');
}
else {
const index = style.ids.size - 1;
const textNode = document.createTextNode(code);
const nodes = style.element.childNodes;
if (nodes[index])
style.element.removeChild(nodes[index]);
if (nodes.length)
style.element.insertBefore(textNode, nodes[index]);
else
style.element.appendChild(textNode);
}
}
}
/* script */
/* template */
var __vue_render__$8 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-grid",on:{"click":function($event){return _vm.$emit('click')}}},[_vm._t("default")],2)};
var __vue_staticRenderFns__$8 = [];
/* style */
const __vue_inject_styles__$8 = function (inject) {
if (!inject) return
inject("data-v-8ae4027e_0", { source: ".vue-photo-grid[data-v-8ae4027e]{display:flex;position:relative;flex:1;cursor:pointer}.vue-photo-grid+.vue-photo-grid[data-v-8ae4027e]{margin-left:var(--vue-photo-grid-gap)}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$8 = "data-v-8ae4027e";
/* module identifier */
const __vue_module_identifier__$8 = undefined;
/* functional template */
const __vue_is_functional_template__$8 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$8 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$8, staticRenderFns: __vue_staticRenderFns__$8 },
__vue_inject_styles__$8,
{},
__vue_scope_id__$8,
__vue_is_functional_template__$8,
__vue_module_identifier__$8,
false,
createInjector,
undefined,
undefined
);
//
//
//
//
//
//
var script$4 = {
props: {
rowHeight: String,
},
};
/* script */
const __vue_script__$4 = script$4;
/* template */
var __vue_render__$7 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-row",style:({ height: _vm.rowHeight })},[_vm._t("default")],2)};
var __vue_staticRenderFns__$7 = [];
/* style */
const __vue_inject_styles__$7 = function (inject) {
if (!inject) return
inject("data-v-51075f7a_0", { source: ".vue-photo-row[data-v-51075f7a]{display:flex;box-sizing:border-box}.vue-photo-row+.vue-photo-row[data-v-51075f7a]{margin-top:var(--vue-photo-grid-gap)}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$7 = "data-v-51075f7a";
/* module identifier */
const __vue_module_identifier__$7 = undefined;
/* functional template */
const __vue_is_functional_template__$7 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$7 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$7, staticRenderFns: __vue_staticRenderFns__$7 },
__vue_inject_styles__$7,
__vue_script__$4,
__vue_scope_id__$7,
__vue_is_functional_template__$7,
__vue_module_identifier__$7,
false,
createInjector,
undefined,
undefined
);
/* script */
/* template */
var __vue_render__$6 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-mask"},[_vm._t("default")],2)};
var __vue_staticRenderFns__$6 = [];
/* style */
const __vue_inject_styles__$6 = function (inject) {
if (!inject) return
inject("data-v-212f69fa_0", { source: ".vue-photo-mask[data-v-212f69fa]{display:block;background-color:rgba(0,0,0,.4);width:100%;height:100%;z-index:1;position:absolute;cursor:pointer;border-radius:var(--vue-photo-grid-radius)}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$6 = "data-v-212f69fa";
/* module identifier */
const __vue_module_identifier__$6 = undefined;
/* functional template */
const __vue_is_functional_template__$6 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$6 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$6, staticRenderFns: __vue_staticRenderFns__$6 },
__vue_inject_styles__$6,
{},
__vue_scope_id__$6,
__vue_is_functional_template__$6,
__vue_module_identifier__$6,
false,
createInjector,
undefined,
undefined
);
/* script */
/* template */
var __vue_render__$5 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-view-more"},[_vm._t("default")],2)};
var __vue_staticRenderFns__$5 = [];
/* style */
const __vue_inject_styles__$5 = function (inject) {
if (!inject) return
inject("data-v-7fcd875c_0", { source: ".vue-view-more[data-v-7fcd875c]{width:100%;height:100%;position:absolute;z-index:1;cursor:pointer}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$5 = "data-v-7fcd875c";
/* module identifier */
const __vue_module_identifier__$5 = undefined;
/* functional template */
const __vue_is_functional_template__$5 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$5 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$5, staticRenderFns: __vue_staticRenderFns__$5 },
__vue_inject_styles__$5,
{},
__vue_scope_id__$5,
__vue_is_functional_template__$5,
__vue_module_identifier__$5,
false,
createInjector,
undefined,
undefined
);
/* script */
/* template */
var __vue_render__$4 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-num-of-remaining"},[_vm._t("default")],2)};
var __vue_staticRenderFns__$4 = [];
/* style */
const __vue_inject_styles__$4 = function (inject) {
if (!inject) return
inject("data-v-11fbfa4e_0", { source: ".vue-num-of-remaining[data-v-11fbfa4e]{position:absolute;color:#fff;font-size:35px;left:50%;top:50%;transform:translate(-50%,-50%)}.vue-num-of-remaining[data-v-11fbfa4e]:before{content:\"+\"}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$4 = "data-v-11fbfa4e";
/* module identifier */
const __vue_module_identifier__$4 = undefined;
/* functional template */
const __vue_is_functional_template__$4 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$4 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$4, staticRenderFns: __vue_staticRenderFns__$4 },
__vue_inject_styles__$4,
{},
__vue_scope_id__$4,
__vue_is_functional_template__$4,
__vue_module_identifier__$4,
false,
createInjector,
undefined,
undefined
);
//
//
//
//
var script$3 = {
props: {
thumb: String,
},
computed: {
thumbStyle() {
return {
'background-image': `url(${this.thumb})`,
};
}
}
};
/* script */
const __vue_script__$3 = script$3;
/* template */
var __vue_render__$3 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-thumb",style:(_vm.thumbStyle)},[_vm._t("default")],2)};
var __vue_staticRenderFns__$3 = [];
/* style */
const __vue_inject_styles__$3 = function (inject) {
if (!inject) return
inject("data-v-3293d38c_0", { source: ".vue-photo-thumb[data-v-3293d38c]{flex:1;background-position:center;background-size:cover;background-repeat:no-repeat;border-radius:var(--vue-photo-grid-radius)}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$3 = "data-v-3293d38c";
/* module identifier */
const __vue_module_identifier__$3 = undefined;
/* functional template */
const __vue_is_functional_template__$3 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$3 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$3, staticRenderFns: __vue_staticRenderFns__$3 },
__vue_inject_styles__$3,
__vue_script__$3,
__vue_scope_id__$3,
__vue_is_functional_template__$3,
__vue_module_identifier__$3,
false,
createInjector,
undefined,
undefined
);
//
var script$2 = {
components: {
PhotoGrid: __vue_component__$8,
PhotoRow: __vue_component__$7,
ViewMore: __vue_component__$5,
NumOfRemaining: __vue_component__$4,
PhotoMask: __vue_component__$6,
PhotoThumb: __vue_component__$3,
},
props: {
height: String,
photos: Array,
layoutNum: Number,
remainingNum: Number,
showNumOfRemainingPhotos: Boolean,
}
};
/* script */
const __vue_script__$2 = script$2;
/* template */
var __vue_render__$2 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('photo-row',{attrs:{"rowHeight":_vm.height}},_vm._l((_vm.photos),function(data,i){return _c('photo-grid',{key:i,on:{"click":function($event){return _vm.$emit('itemClick', data, i)}}},[(_vm.showNumOfRemainingPhotos && _vm.remainingNum > 0 && data.id === (_vm.layoutNum - 1))?[_c('photo-mask'),_vm._v(" "),_c('view-more',[_c('num-of-remaining',[_vm._v(_vm._s(_vm.remainingNum))])],1)]:_vm._e(),_vm._v(" "),_c('photo-thumb',{attrs:{"thumb":data.source}})],2)}),1)};
var __vue_staticRenderFns__$2 = [];
/* style */
const __vue_inject_styles__$2 = undefined;
/* scoped */
const __vue_scope_id__$2 = undefined;
/* module identifier */
const __vue_module_identifier__$2 = undefined;
/* functional template */
const __vue_is_functional_template__$2 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$2 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
__vue_inject_styles__$2,
__vue_script__$2,
__vue_scope_id__$2,
__vue_is_functional_template__$2,
__vue_module_identifier__$2,
false,
undefined,
undefined,
undefined
);
//
var script$1 = {
components: {
RowPhotos: __vue_component__$2,
},
props: {
disabled: {
type: Boolean,
default: false,
},
width: String,
height: Array,
layout: Array,
layoutPhotoMaps: Object,
layoutNum: Number,
remainingNum: Number,
showNumOfRemainingPhotos: Boolean,
},
computed: {
photoCollageStyle() {
return {
width: this.width,
};
},
},
};
/* script */
const __vue_script__$1 = script$1;
/* template */
var __vue_render__$1 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-collage",class:[_vm.disabled && 'vue-photo-collage--disabled'],style:(_vm.photoCollageStyle)},_vm._l((_vm.layout),function(data,i){return _c('row-photos',{key:i,attrs:{"height":_vm.height[i],"photos":_vm.layoutPhotoMaps[i],"layoutNum":_vm.layoutNum,"remainingNum":_vm.remainingNum,"showNumOfRemainingPhotos":_vm.showNumOfRemainingPhotos},on:{"itemClick":function (data, i) { return !_vm.disabled && _vm.$emit('itemClick', data, i); }}})}),1)};
var __vue_staticRenderFns__$1 = [];
/* style */
const __vue_inject_styles__$1 = function (inject) {
if (!inject) return
inject("data-v-b1ccf3bc_0", { source: ".vue-photo-collage{font-family:inherit}.vue-photo-collage.vue-photo-collage--disabled .vue-photo-grid,.vue-photo-collage.vue-photo-collage--disabled .vue-view-more{cursor:inherit}", map: undefined, media: undefined });
};
/* scoped */
const __vue_scope_id__$1 = undefined;
/* module identifier */
const __vue_module_identifier__$1 = undefined;
/* functional template */
const __vue_is_functional_template__$1 = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$1 = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
__vue_inject_styles__$1,
__vue_script__$1,
__vue_scope_id__$1,
__vue_is_functional_template__$1,
__vue_module_identifier__$1,
false,
createInjector,
undefined,
undefined
);
//
function createPhotoIds(photos) {
return photos.map((data, i) => {
return { ...data, id: i };
});
}
function createLayoutPhotoMaps(layout, photos) {
const newPhotos = createPhotoIds(photos);
const newMaps = {};
layout.reduce((accumulator, currentValue, currentIndex) => {
newMaps[currentIndex] = newPhotos.slice(
accumulator,
accumulator + currentValue
);
return accumulator + currentValue;
}, 0);
return newMaps;
}
var script = {
name: "PhotoCollageWrapper",
components: {
PhotoCollage: __vue_component__$1,
},
props: {
disabled: {
type: Boolean,
default: false,
},
width: {
type: String,
default: "800px",
},
height: {
type: Array,
},
layout: {
type: Array,
default: [],
},
photos: {
type: Array,
default: [],
},
showNumOfRemainingPhotos: {
type: Boolean,
default: false,
},
gapSize: String,
borderRadius: String,
},
data() {
const layout = this.layout;
const internalHeight = this.height;
if (internalHeight.length < layout.length) {
for (let i = 0; i < layout.length; i++) {
internalHeight[i] = "200px";
}
}
return {
internalHeight,
allowRender: false,
layoutPhotoMaps: {},
viewerIsOpen: false,
currentImage: 0,
};
},
watch: {
layoutPhotoMaps: {
handler() {
this.allowRender = !Object.keys(this.layoutPhotoMaps).length;
},
},
gapSize: {
handler() {
this.setGapSize();
},
deep: true,
},
borderRadius: {
handler() {
this.setBorderRadius();
},
deep: true,
},
},
created() {
this.layoutPhotoMaps = createLayoutPhotoMaps(this.layout, this.photos);
this.setGapSize();
this.setBorderRadius();
},
methods: {
setGapSize() {
if (document) {
document.documentElement.style.setProperty(
"--vue-photo-grid-gap",
this.gapSize
);
}
},
setBorderRadius() {
if (document) {
document.documentElement.style.setProperty(
"--vue-photo-grid-radius",
this.borderRadius
);
}
},
},
computed: {
layoutNum() {
return this.layout.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0
);
},
remainingNum() {
return this.photos.length - this.layoutNum;
},
},
};
/* script */
const __vue_script__ = script;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"vue-photo-collage-wrapper"},[_c('photo-collage',{attrs:{"disabled":_vm.disabled,"width":_vm.width,"height":_vm.internalHeight,"layout":_vm.layout,"layoutPhotoMaps":_vm.layoutPhotoMaps,"layoutNum":_vm.layoutNum,"remainingNum":_vm.remainingNum,"showNumOfRemainingPhotos":_vm.showNumOfRemainingPhotos},on:{"itemClick":function (data, i) { return _vm.$emit('itemClick', data, i); }}})],1)};
var __vue_staticRenderFns__ = [];
/* style */
const __vue_inject_styles__ = undefined;
/* scoped */
const __vue_scope_id__ = undefined;
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
export { __vue_component__ as PhotoCollageWrapper };