Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

picker增加滚动效果, 和点击选择, layer优化~ #18

Merged
merged 1 commit into from
Nov 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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