Skip to content

Commit

Permalink
add grow attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
cenzhende committed Nov 4, 2016
1 parent 974937d commit 37700c7
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 19 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Branch [0.x (version 0.x.x)](https://github.com/MopTym/vue-waterfall/tree/0.x) i

- [Vertical line](http://app.moptym.com/vue-waterfall/demo/vertical-line.html)
- [Horizontal line](http://app.moptym.com/vue-waterfall/demo/horizontal-line.html)

- [Vertical line with grow](http://app.moptym.com/vue-waterfall/demo/vertical-line-with-grow.html)

## Installation

Expand Down Expand Up @@ -90,7 +90,13 @@ new Vue({
```html
<waterfall :line-gap="200" :watch="items">
<!-- each component is wrapped by a waterfall slot -->
<waterfall-slot v-for="(item, index) in items" :width="item.width" :height="item.height" :order="index" :key="item.id">
<waterfall-slot
v-for="(item, index) in items"
:width="item.width"
:height="item.height"
:order="index"
:key="item.id"
>
<!--
your component
-->
Expand Down Expand Up @@ -141,6 +147,11 @@ new Vue({
<td><code>false</code></td>
<td>Fix slot height when line = <code>v</code> .</td>
</tr>
<tr>
<td>grow</td>
<td>-</td>
<td>Number Array. Slot flex grow factors in horizontal direction when line = <code>v</code> . Ignore <code>*-gap</code> .</td>
</tr>
<tr>
<td>align</td>
<td><code>left</code></td>
Expand Down
86 changes: 86 additions & 0 deletions demo/vertical-line-with-grow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="user-scalable=0">
<title>Vertical Line With Grow</title>
<link rel="stylesheet" href="./common/css/style.css">
<style>
.item-move {
transition: all .5s cubic-bezier(.55,0,.1,1);
-webkit-transition: all .5s cubic-bezier(.55,0,.1,1);
}
</style>
</head>
<body>
<div id="app">
<waterfall
:grow="grow"
:watch="items"
@reflowed="reflowed"
ref="waterfall"
>
<!-- each component is wrapped by a waterfall slot -->
<waterfall-slot
v-for="(item, index) in items"
:width="item.width"
:height="item.height"
:order="index"
:key="item.index"
move-class="item-move"
>
<div class="item" :style="item.style" :index="item.index"></div>
</waterfall-slot>
</waterfall>
</div>
<script src="https://cdn.jsdelivr.net/vue/2.0.3/vue.min.js"></script>
<script src="http://app.moptym.com/cdn/vue-waterfall/vue-waterfall.min.js"></script>
<script src="./common/js/item-factory.js"></script>
<script>

var app = new Vue({
el: '#app',
components: {
'waterfall': Waterfall.waterfall,
'waterfall-slot': Waterfall.waterfallSlot
},
data: {
grow: [3, 2, 1, 2],
items: ItemFactory.get(100),
isBusy: false
},
methods: {
addItems: function () {
if (!this.isBusy && this.items.length < 500) {
this.isBusy = true
this.items.push.apply(this.items, ItemFactory.get(50))
}
},
shuffle: function () {
this.items.sort(function () {
return Math.random() - 0.5
})
},
reflowed: function () {
this.isBusy = false
}
}
})

document.body.addEventListener('click', function () {
app.shuffle()
// app.$refs.waterfall.$emit('reflow') // manually trigger reflow action
}, false)

window.addEventListener('scroll', function () {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop + window.innerHeight >= document.body.clientHeight) {
app.addItems()
}
})

</script>
</body>
</html>
4 changes: 2 additions & 2 deletions lib/vue-waterfall.min.js

Large diffs are not rendered by default.

36 changes: 29 additions & 7 deletions lib/waterfall.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export default {
fixedHeight: {
default: false
},
grow: {
validator: (val) => val instanceof Array
},
watch: {
default: () => ({})
}
Expand Down Expand Up @@ -78,6 +81,7 @@ export default {
this.fixedHeight,
this.watch
), this.reflowHandler)
this.$watch('grow', this.reflowHandler)
},
mounted () {
this.$watch('autoResize', this.autoResizeHandler)
Expand Down Expand Up @@ -148,26 +152,31 @@ function getOptions (vm) {
minLineGap: vm.minLineGap ? +vm.minLineGap : vm.lineGap,
maxLineGap: vm.maxLineGap ? +vm.maxLineGap : vm.lineGap,
singleMaxWidth: Math.max(vm.singleMaxWidth || 0, vm.maxLineGap),
fixedHeight: !!vm.fixedHeight
fixedHeight: !!vm.fixedHeight,
grow: vm.grow && vm.grow.map(val => +val)
}
}
var verticalLineProcessor = (() => {
function calculate (vm, options, metas, rects) {
let width = vm.$el.clientWidth
let strategy = getRowStrategy(width, options)
let grow = options.grow
let strategy = grow
? getRowStrategyWithGrow(width, grow)
: getRowStrategy(width, options)
let tops = getArrayFillWith(0, strategy.count)
metas.forEach((meta, index) => {
let offset = tops.reduce((last, top, i) => top < tops[last] ? i : last, 0)
let width = strategy.width[offset % strategy.count]
let rect = rects[index]
rect.top = tops[offset]
rect.left = strategy.left + strategy.width * offset
rect.width = strategy.width
rect.height = meta.height * (options.fixedHeight ? 1 : strategy.width / meta.width)
rect.left = strategy.left + (offset ? sum(strategy.width.slice(0, offset)) : 0)
rect.width = width
rect.height = meta.height * (options.fixedHeight ? 1 : width / meta.width)
tops[offset] = tops[offset] + rect.height
})
vm.style.height = Math.max.apply(null, tops) + 'px'
vm.style.height = Math.max.apply(Math, tops) + 'px'
}
function getRowStrategy (width, options) {
Expand Down Expand Up @@ -200,12 +209,21 @@ var verticalLineProcessor = (() => {
}
}
return {
width: slotWidth,
width: getArrayFillWith(slotWidth, count),
count: count,
left: getLeft(width, slotWidth * count, options.align)
}
}
function getRowStrategyWithGrow (width, grow) {
let total = sum(grow)
return {
width: grow.map(val => width * val / total),
count: grow.length,
left: 0
}
}
return {
calculate
}
Expand Down Expand Up @@ -315,6 +333,10 @@ function getLeft (width, contentWidth, align) {
}
}
function sum (arr) {
return arr.reduce((sum, val) => sum + val)
}
function render (rects, metas) {
let metasNeedToMoveByTransform = metas.filter((meta) => meta.moveClass)
let firstRects = getRects(metasNeedToMoveByTransform)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-waterfall",
"version": "1.0.2",
"version": "1.0.3",
"description": "A waterfall layout component for Vue.js",
"main": "lib/vue-waterfall.min.js",
"files": [
Expand Down
36 changes: 29 additions & 7 deletions src/waterfall.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export default {
fixedHeight: {
default: false
},
grow: {
validator: (val) => val instanceof Array
},
watch: {
default: () => ({})
}
Expand Down Expand Up @@ -78,6 +81,7 @@ export default {
this.fixedHeight,
this.watch
), this.reflowHandler)
this.$watch('grow', this.reflowHandler)
},
mounted () {
this.$watch('autoResize', this.autoResizeHandler)
Expand Down Expand Up @@ -148,26 +152,31 @@ function getOptions (vm) {
minLineGap: vm.minLineGap ? +vm.minLineGap : vm.lineGap,
maxLineGap: vm.maxLineGap ? +vm.maxLineGap : vm.lineGap,
singleMaxWidth: Math.max(vm.singleMaxWidth || 0, vm.maxLineGap),
fixedHeight: !!vm.fixedHeight
fixedHeight: !!vm.fixedHeight,
grow: vm.grow && vm.grow.map(val => +val)
}
}
var verticalLineProcessor = (() => {
function calculate (vm, options, metas, rects) {
let width = vm.$el.clientWidth
let strategy = getRowStrategy(width, options)
let grow = options.grow
let strategy = grow
? getRowStrategyWithGrow(width, grow)
: getRowStrategy(width, options)
let tops = getArrayFillWith(0, strategy.count)
metas.forEach((meta, index) => {
let offset = tops.reduce((last, top, i) => top < tops[last] ? i : last, 0)
let width = strategy.width[offset % strategy.count]
let rect = rects[index]
rect.top = tops[offset]
rect.left = strategy.left + strategy.width * offset
rect.width = strategy.width
rect.height = meta.height * (options.fixedHeight ? 1 : strategy.width / meta.width)
rect.left = strategy.left + (offset ? sum(strategy.width.slice(0, offset)) : 0)
rect.width = width
rect.height = meta.height * (options.fixedHeight ? 1 : width / meta.width)
tops[offset] = tops[offset] + rect.height
})
vm.style.height = Math.max.apply(null, tops) + 'px'
vm.style.height = Math.max.apply(Math, tops) + 'px'
}
function getRowStrategy (width, options) {
Expand Down Expand Up @@ -200,12 +209,21 @@ var verticalLineProcessor = (() => {
}
}
return {
width: slotWidth,
width: getArrayFillWith(slotWidth, count),
count: count,
left: getLeft(width, slotWidth * count, options.align)
}
}
function getRowStrategyWithGrow (width, grow) {
let total = sum(grow)
return {
width: grow.map(val => width * val / total),
count: grow.length,
left: 0
}
}
return {
calculate
}
Expand Down Expand Up @@ -315,6 +333,10 @@ function getLeft (width, contentWidth, align) {
}
}
function sum (arr) {
return arr.reduce((sum, val) => sum + val)
}
function render (rects, metas) {
let metasNeedToMoveByTransform = metas.filter((meta) => meta.moveClass)
let firstRects = getRects(metasNeedToMoveByTransform)
Expand Down

0 comments on commit 37700c7

Please sign in to comment.