diff --git a/docs/demos/views/swipe.vue b/docs/demos/views/swipe.vue index 4de4c80e3..37d0218ee 100644 --- a/docs/demos/views/swipe.vue +++ b/docs/demos/views/swipe.vue @@ -27,7 +27,7 @@ - + 1 2 3 @@ -79,11 +79,9 @@ export default { .van-swipe { cursor: pointer; - height: 140px; &-item { color: #fff; - min-height: 140px; font-size: 20px; text-align: center; line-height: 150px; @@ -107,5 +105,13 @@ export default { pointer-events: none; } } + + &--vertical { + height: 200px; + + .van-swipe-item { + line-height: 200px; + } + } } diff --git a/packages/mixins/touch.js b/packages/mixins/touch.js index a5affbfd9..2b8b223d9 100644 --- a/packages/mixins/touch.js +++ b/packages/mixins/touch.js @@ -16,10 +16,7 @@ export default { this.deltaY = touch.clientY - this.startY; this.offsetX = Math.abs(this.deltaX); this.offsetY = Math.abs(this.deltaY); - - if (!this.direction) { - this.direction = this.offsetX > this.offsetY ? 'horizontal' : this.offsetX < this.offsetY ? 'vertical' : ''; - } + this.direction = this.offsetX > this.offsetY ? 'horizontal' : this.offsetX < this.offsetY ? 'vertical' : ''; } } }; diff --git a/packages/swipe/index.vue b/packages/swipe/index.vue index 23730f26f..f78d492e6 100644 --- a/packages/swipe/index.vue +++ b/packages/swipe/index.vue @@ -17,11 +17,10 @@
@@ -67,14 +66,11 @@ export default create({ width: 0, height: 0, offset: 0, - startX: 0, - startY: 0, active: 0, deltaX: 0, deltaY: 0, swipes: [], - direction: '', - currentDuration: 0 + swiping: false }; }, @@ -83,7 +79,7 @@ export default create({ }, destroyed() { - clearTimeout(this.timer); + this.clear(); }, watch: { @@ -97,7 +93,7 @@ export default create({ autoplay(autoplay) { if (!autoplay) { - clearTimeout(this.timer); + this.clear(); } } }, @@ -107,45 +103,41 @@ export default create({ return this.swipes.length; }, - trackStyle() { - const sizeKey = this.vertical ? 'height' : 'width'; - - const style = { - [this.vertical ? 'paddingTop' : 'paddingLeft']: `${this[sizeKey]}px`, - [sizeKey]: `${(this.count + 2) * this[sizeKey]}px`, - transitionDuration: `${this.currentDuration}ms` - }; - - if (this.vertical) { - style.transform = `translate(0, ${this.offset}px)`; - } else { - style.transform = `translate(${this.offset}px, 0)`; - } - - return style; + delta() { + return this.vertical ? this.deltaY : this.deltaX; }, - indicatorsClass() { - return this.vertical ? 'indicators--vertical' : 'indicators'; + size() { + return this[this.vertical ? 'height' : 'width']; + }, + + trackSize() { + return this.count * this.size; }, activeIndicator() { return (this.active + this.count) % this.count; }, - size() { - return this.vertical ? this.height : this.width; + trackStyle() { + return { + [this.vertical ? 'height' : 'width']: `${this.trackSize}px`, + transitionDuration: `${this.swiping ? 0 : this.duration}ms`, + transform: `translate${this.vertical ? 'Y' : 'X'}(${this.offset}px)` + }; } }, methods: { + // initialize swipe position initialize() { - // reset offset when children changes clearTimeout(this.timer); - ({ width: this.width, height: this.height } = this.$el.getBoundingClientRect()); + const rect = this.$el.getBoundingClientRect(); + this.swiping = true; + this.width = rect.width; + this.height = rect.height; this.active = this.initialSwipe; - this.currentDuration = 0; - this.offset = this.count > 1 ? -this.size * (this.active + 1) : 0; + this.offset = this.count > 1 ? -this.size * this.active : 0; this.swipes.forEach(swipe => { swipe.offset = 0; }); @@ -155,64 +147,49 @@ export default create({ onTouchStart(event) { if (!this.touchable) return; - clearTimeout(this.timer); - - this.currentDuration = 0; + this.clear(); + this.swiping = true; this.touchStart(event); - - if (this.active <= -1) { - this.move(this.count); - } - if (this.active >= this.count) { - this.move(-this.count); - } + this.correctPosition(); }, onTouchMove(event) { if (!this.touchable) return; - const delta = this.vertical ? this.deltaY : this.deltaX; - this.touchMove(event); - if (this.vertical && this.direction === 'vertical') { - event.preventDefault(); - event.stopPropagation(); - } else if (this.direction === 'horizontal') { + if ( + (this.vertical && this.direction === 'vertical') || + this.direction === 'horizontal' + ) { event.preventDefault(); event.stopPropagation(); } - this.move(0, this.range(delta, [-this.size, this.size])); - this.move(0, this.range(delta, [-this.size, this.size])); + this.move(0, Math.min(Math.max(this.delta, -this.size), this.size)); }, onTouchEnd() { if (!this.touchable) return; - const { deltaX, deltaY } = this; - - if (deltaX) { - this.move(this.offsetX > 50 ? (deltaX > 0 ? -1 : 1) : 0); - this.currentDuration = this.duration; - } - - if (deltaY) { - this.move(this.offsetY > 50 ? (deltaY > 0 ? -1 : 1) : 0); - this.currentDuration = this.duration; + if (this.delta) { + const offset = this.vertical ? this.offsetY : this.offsetX; + this.move(offset > 50 ? (this.delta > 0 ? -1 : 1) : 0); + this.swiping = false; } this.autoPlay(); }, move(move = 0, offset = 0) { - const { active, count, swipes } = this; - const delta = this.vertical ? this.deltaY : this.deltaX; + const { delta, active, count, swipes, trackSize } = this; + const atFirst = active === 0; + const atLast = active === count - 1; if ( !this.loop && - ((active === 0 && (offset > 0 || move < 0)) || - (active === count - 1 && (offset < 0 || move > 0))) + ((atFirst && (offset > 0 || move < 0)) || + (atLast && (offset < 0 || move > 0))) ) { return; } @@ -221,41 +198,47 @@ export default create({ if (active === -1) { swipes[count - 1].offset = 0; } - swipes[0].offset = active === count - 1 && move > 0 ? count * this.size : 0; + swipes[0].offset = atLast && move > 0 ? trackSize : 0; this.active += move; } else { - if (active === 0) { - swipes[count - 1].offset = delta > 0 ? -count * this.size : 0; - } else if (active === count - 1) { - swipes[0].offset = delta < 0 ? count * this.size : 0; + if (atFirst) { + swipes[count - 1].offset = delta > 0 ? -trackSize : 0; + } else if (atLast) { + swipes[0].offset = delta < 0 ? trackSize : 0; } } - this.offset = offset - (this.active + 1) * this.size; + this.offset = offset - this.active * this.size; + }, + + correctPosition() { + if (this.active <= -1) { + this.move(this.count); + } + if (this.active >= this.count) { + this.move(-this.count); + } + }, + + clear() { + clearTimeout(this.timer); }, autoPlay() { const { autoplay } = this; if (autoplay && this.count > 1) { - clearTimeout(this.timer); + this.clear(); this.timer = setTimeout(() => { - this.currentDuration = 0; - - if (this.active >= this.count) { - this.move(-this.count); - } + this.swiping = true; + this.correctPosition(); setTimeout(() => { - this.currentDuration = this.duration; + this.swiping = false; this.move(1); this.autoPlay(); }, 30); }, autoplay); } - }, - - range(num, arr) { - return Math.min(Math.max(num, arr[0]), arr[1]); } } }); diff --git a/packages/vant-css/src/swipe.css b/packages/vant-css/src/swipe.css index 6d53c6853..2f874a28f 100644 --- a/packages/vant-css/src/swipe.css +++ b/packages/vant-css/src/swipe.css @@ -13,29 +13,30 @@ $van-swipe-indicator: 6px; &__track { height: 100%; - overflow: hidden; } &__indicators { + display: flex; position: absolute; left: 50%; bottom: 10px; - height: $van-swipe-indicator; - transform: translate3d(-50%, 0, 0); + transform: translateX(-50%); &--vertical { - position: absolute; left: 10px; top: 50%; - width: $van-swipe-indicator; - transform: translate3d(0, -50%, 0); + bottom: auto; + flex-direction: column; + transform: translateY(-50%); + + .van-swipe__indicator:not(:last-child) { + margin-bottom: $van-swipe-indicator; + } } } &__indicator { border-radius: 100%; - vertical-align: top; - display: inline-block; background-color: $gray-dark; width: $van-swipe-indicator; height: $van-swipe-indicator;