Skip to content

Instantly share code, notes, and snippets.

@afalchi82
Created September 17, 2017 09:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afalchi82/028299d3448694e6142fe05bd7b5c3d1 to your computer and use it in GitHub Desktop.
Save afalchi82/028299d3448694e6142fe05bd7b5c3d1 to your computer and use it in GitHub Desktop.
Face mosaic
<div id="app">
<!--
<pre>{{ people.length }} </pre>
<pre>remainder {{people.length % (table.cols * table.rows) }} </pre>
<pre>Rows: {{ rows }}</pre>
<pre>length: {{ length }}</pre>
<pre >
<span v-for="c in chunks">{{ hasBig(c) }}</span>
</pre>-->
<!-- mosaic -->
<section class="floats" :style="'width:' + (tileSize * table.cols) + 'px; height:' + (tileSize * table.cols) + 'px;'">
<div class="wrapper" :style="'transform: translateY(' + slideAmount + 'px)'">
<app-person
v-for="person, index in people"
:person="person"
:index="index"
:key="index"
:people="people"
:stop-autoplay="stopAutoplay"
:start-autoplay="startAutoplay"
>
</app-person>
<!--
<div class="person" v-for="item, index in people" :class="{ big: item.size === 2}">
<a href="" :title="item.name.first + ' ' + item.name.last" @mouseover="stopAutoplay()" @mouseout="startAutoplay()">
<img :src="item.picture.large" alt="">
</a>
</div>
-->
</div>
</section>
<!-- mosaic -->
</div>
console.clear();
Vue.component('app-person', {
template: `
<div class="person" :class="{ big: person.size === 2}">
<a href="" :title="person.name.first + ' ' + person.name.last" @mouseover="stopAutoplay()" @mouseout="startAutoplay()">
<img :src="person.picture.large" alt="">
</a>
</div>`,
props: ['people', 'person', 'index', 'stopAutoplay', 'startAutoplay']
});
const app = new Vue({
el: '#app',
data: {
numpeople: 16,
autoplay: true,
autoplayDelay: 4000,
isPaused: false,
people: [],
slideAmount: 0,
tileSize: 120,
table: {
rows: 4,
cols: 4
}
},
computed: {
play () {
return setInterval( () => {
const scrollCondition = Math.abs(this.slideAmount) <= (wrapper.clientHeight - (this.tileSize * (this.table.rows+1)));
if(scrollCondition & !this.isHover) {
this.slideAmount -= this.tileSize * 3;
} else {
this.slideAmount = 0;
}
}, this.autoplayDelay);
},
loadProfiles () {
const people = $.get(`https://randomuser.me/api/?inc=name,picture&results=${this.numpeople}&gender=female`)
.done( response => {
console.log()
this.people = response.results;
this.people.map( item => {
if(Math.round(Math.random()) === 0) {
return item.size = 1;
} else {
return item.size = 2;
}
});
})
//.always ( () => [])
;
return people;
},
length () { return this.people.length; },
rows () { return Math.ceil(this.people.length / this.table.rows); },
chunks () {
let vm = this,
chunks = [],
limit = Math.ceil(vm.people.length / vm.table.cols);
for (let i=0; i < limit; i+=1) {
let sliceStart = i * vm.table.cols,
slideEnd = sliceStart + vm.table.cols;
chunks.push( vm.people.slice(sliceStart, slideEnd) );
}
return chunks;
}
},
methods: {
hasBig (array) {
let has = false;
array.forEach( item => { if(item.size === 2) {has = true}; } );
return has;
},
stopAutoplay () {
this.isPaused = true;
},
startAutoplay () {
this.isPaused = false;
},
animateWrapper () {
const wrapper = this.$el.querySelector('.wrapper');
const interval = setInterval( () => {
const scrollCondition = Math.abs(this.slideAmount) <= (wrapper.clientHeight - (this.tileSize * (this.table.rows+1)));
if(scrollCondition && !this.isPaused) {
this.slideAmount -= this.tileSize * 3;
} else if (!scrollCondition) {
this.slideAmount = 0;
} else if (this.isPaused) {
}
}, this.autoplayDelay);
}
},
mounted: function () {
this.loadProfiles;
if (this.autoplay) {
this.animateWrapper();
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
$size: 120px;
$bgcolor: #fee9e6;
body {
background: $bgcolor;
min-width: 480px;
}
* { box-sizing: border-box; }
#app {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
/* floats */
.floats {
position: relative;
margin: 0 auto;
background: $bgcolor;
overflow: hidden;
.wrapper {
width: 100%;
height: auto;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
transition: transform 2s;
}
.person {
height: $size;
width: $size;
background: $bgcolor;
float:left;
overflow: hidden;
a {
display: block;
background: $bgcolor;
}
img {
width: 100%;
filter: grayscale(100%);
opacity: .7;
transition: opacity .4s, filter .8s, transform .8s;
&:hover {
opacity: 1;
filter: grayscale(0%);
transform: scale(1.1);}
}
&.big {
height: $size * 2;
width: $size * 2;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment