Skip to content

Commit

Permalink
Merge pull request #18 from deepkolos/picker-fix
Browse files Browse the repository at this point in the history
 picker增加滚动效果, 和点击选择, layer优化~
  • Loading branch information
tianyong90 authored Nov 13, 2017
2 parents 9a8e709 + 91711eb commit 47d1c6c
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 23 deletions.
107 changes: 86 additions & 21 deletions src/components/picker/picker-slot.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="weui-picker__group" v-if="!divider">
<div class="weui-picker__mask"></div>
<div class="weui-picker__indicator"></div>
<div class="weui-picker__indicator" ref="indicator"></div>
<div class="weui-picker__content" ref="listWrapper">
<div class="weui-picker__item" :class="{ 'weui-picker__item_disabled': typeof item === 'object' && item['disabled'] }" v-for="(item, key, index) in mutatingValues" :key="key">{{ typeof item === 'object' && item[valueKey] ? item[valueKey] : item }}</div>
</div>
Expand Down Expand Up @@ -66,7 +66,16 @@
},
valueIndex () {
return this.mutatingValues.indexOf(this.currentValue)
var valueKey = this.valueKey
if(this.currentValue instanceof Object){
//写个顺序查找好了
for(var i = 0, len = this.mutatingValues.length; i < len ; i++){
if(this.currentValue[valueKey] === this.mutatingValues[i][valueKey])
return i
}
return -1
}else
return this.mutatingValues.indexOf(this.currentValue)
}
},
Expand All @@ -78,51 +87,58 @@
if (this.divider) return
const wrapper = this.$refs.listWrapper
const indicator = this.$refs.indicator
Transform(wrapper, true)
this.doOnValueChange()
draggable(this.$el, {
start: (event) => {
this.isDragging = true
let dragState = this.dragState
dragState.start = new Date()
dragState.startPositionY = event.clientY
dragState.startTranslateY = wrapper.translateY
wrapper.style.transition = null
},
drag: (event) => {
let dragState = this.dragState
const deltaY = event.clientY - dragState.startPositionY
const tempTranslateY = dragState.startTranslateY + deltaY
if (tempTranslateY <= this.minTranslateY) {
wrapper.translateY = this.minTranslateY
} else if (tempTranslateY >= this.maxTranslateY) {
wrapper.translateY = this.maxTranslateY
} else {
wrapper.translateY = dragState.startTranslateY + deltaY
}
wrapper.translateY = dragState.startTranslateY + deltaY
dragState.currentPosifionY = event.clientY
dragState.currentTranslateY = wrapper.translateY
dragState.velocityTranslate = dragState.currentTranslateY - dragState.prevTranslateY
dragState.velocityTranslate =
dragState.currentTranslateY - dragState.prevTranslateY
dragState.prevTranslateY = dragState.currentTranslateY
},
end: () => {
this.isDragging = false
end: (event) => {
let dragState = this.dragState
let momentumRatio = 7
let currentTranslate = wrapper.translateY
let duration = new Date() - dragState.start
let distance = Math.abs(dragState.startTranslateY - currentTranslate)
let rect, offset
if(distance < 6){
rect = indicator.getBoundingClientRect()
offset = Math.floor((event.clientY - rect.top)/ITEM_HEIGHT) * ITEM_HEIGHT
if(offset > this.maxTranslateY )
offset = this.maxTranslateY
dragState.velocityTranslate = 0
currentTranslate -= offset
}
let momentumTranslate
if (duration < 300) {
momentumTranslate = currentTranslate + dragState.velocityTranslate * momentumRatio
}
wrapper.style.transition = 'all 200ms ease'
this.$nextTick(() => {
let translate
Expand All @@ -144,8 +160,7 @@
methods: {
value2translate (value) {
const values = this.mutatingValues
const valueIndex = values.indexOf(value)
const valueIndex = this.valueIndex
const offset = Math.floor(VISIBLE_ITEM_COUNT / 2)
if (valueIndex !== -1) {
Expand All @@ -167,6 +182,41 @@
if (this.divider) return
wrapper.translateY = this.value2translate(value)
},
nearby (val, values){
var minOffset, minIndex, offset
if(Array.isArray(values) === false)
return undefined
minIndex = 0
if(typeof val === 'number'){
minOffset = Math.abs(values[0] - val)
values.forEach((value, i)=>{
offset = Math.abs(value - val)
if(offset < minOffset){
minIndex = i
minOffset = offset
}
})
return values[minIndex]
}else if(val instanceof Object){
if(typeof val.value === 'number'){
minOffset = Math.abs(values[0].value - val.value)
values.forEach((value, i)=>{
offset = Math.abs(value.value - val.value)
if(offset < minOffset){
minIndex = i
minOffset = offset
}
})
return values[minIndex]
}
}
return values[0]
}
},
Expand All @@ -177,7 +227,7 @@
mutatingValues (val) {
if (this.valueIndex === -1) {
this.currentValue = (val || [])[0]
this.currentValue = this.nearby(this.currentValue, val)
}
},
Expand All @@ -191,6 +241,21 @@
</script>

<style scoped lang="scss">
.weui-picker__group{
z-index: 0;
overflow: hidden;
}
.weui-picker__mask{
z-index: 2;
height: 238px;
}
.weui-picker__indicator{
z-index: 3;
}
.weui-picker__content{
z-index: 1;
}
.wv-picker-slot-divider {
transform:translateY(106px);
}
Expand Down
18 changes: 16 additions & 2 deletions src/components/picker/picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@
return null
},
setSlotValue (index, value) {
setSlotValue (index, value, taskQueue) {
this.$nextTick(() => {
let slot = this.getSlot(index)
if (slot) {
slot.currentValue = value
if(taskQueue && taskQueue.length > 0)
slot.$nextTick(taskQueue.shift())
}
})
},
Expand All @@ -132,8 +134,15 @@
setSlotValues (index, values) {
this.$nextTick(() => {
let slot = this.getSlot(index)
var oldVal
if (slot) {
oldVal = slot.currentValue
slot.mutatingValues = values
slot.$nextTick(()=>{
if(oldVal !== undefined && oldVal !== null)
slot.doOnValueChange(oldVal)
oldVal = null
})
}
})
},
Expand All @@ -148,9 +157,14 @@
throw new Error('values length is not equal slot count.')
}
var taskQueue = []
values.forEach((value, index) => {
this.setSlotValue(index, value)
if(index !== 0)
taskQueue.push(()=>{
this.setSlotValue(index, value, taskQueue)
})
})
this.setSlotValue(0, values[0], taskQueue)
},
cancel () {
Expand Down

0 comments on commit 47d1c6c

Please sign in to comment.