lulouis-vant
Version:
Lightweight Mobile UI Components built on Vue
304 lines (268 loc) • 7.87 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _touch = _interopRequireDefault(require("../mixins/touch"));
var _event = require("../utils/event");
var _use = (0, _utils.use)('swipe'),
sfc = _use[0],
bem = _use[1];
var _default = sfc({
mixins: [_touch.default],
props: {
width: Number,
height: Number,
autoplay: Number,
vertical: Boolean,
initialSwipe: Number,
indicatorColor: String,
loop: {
type: Boolean,
default: true
},
touchable: {
type: Boolean,
default: true
},
showIndicators: {
type: Boolean,
default: true
},
duration: {
type: Number,
default: 500
}
},
data: function data() {
return {
computedWidth: 0,
computedHeight: 0,
offset: 0,
active: 0,
deltaX: 0,
deltaY: 0,
swipes: [],
swiping: false
};
},
mounted: function mounted() {
this.initialize();
if (!this.$isServer) {
(0, _event.on)(window, 'resize', this.onResize, true);
}
},
activated: function activated() {
if (this.rendered) {
this.initialize();
}
this.rendered = true;
},
destroyed: function destroyed() {
this.clear();
if (!this.$isServer) {
(0, _event.off)(window, 'resize', this.onResize, true);
}
},
watch: {
swipes: function swipes() {
this.initialize();
},
initialSwipe: function initialSwipe() {
this.initialize();
},
autoplay: function autoplay(_autoplay) {
if (!_autoplay) {
this.clear();
} else {
this.autoPlay();
}
}
},
computed: {
count: function count() {
return this.swipes.length;
},
delta: function delta() {
return this.vertical ? this.deltaY : this.deltaX;
},
size: function size() {
return this[this.vertical ? 'computedHeight' : 'computedWidth'];
},
trackSize: function trackSize() {
return this.count * this.size;
},
activeIndicator: function activeIndicator() {
return (this.active + this.count) % this.count;
},
isCorrectDirection: function isCorrectDirection() {
var expect = this.vertical ? 'vertical' : 'horizontal';
return this.direction === expect;
},
trackStyle: function trackStyle() {
var _ref;
var mainAxis = this.vertical ? 'height' : 'width';
var crossAxis = this.vertical ? 'width' : 'height';
return _ref = {}, _ref[mainAxis] = this.trackSize + "px", _ref[crossAxis] = this[crossAxis] ? this[crossAxis] + "px" : '', _ref.transitionDuration = (this.swiping ? 0 : this.duration) + "ms", _ref.transform = "translate" + (this.vertical ? 'Y' : 'X') + "(" + this.offset + "px)", _ref;
},
indicatorStyle: function indicatorStyle() {
return {
backgroundColor: this.indicatorColor
};
}
},
methods: {
// initialize swipe position
initialize: function initialize(active) {
if (active === void 0) {
active = this.initialSwipe;
}
clearTimeout(this.timer);
if (this.$el) {
var rect = this.$el.getBoundingClientRect();
this.computedWidth = this.width || rect.width;
this.computedHeight = this.height || rect.height;
}
this.swiping = true;
this.active = active;
this.offset = this.count > 1 ? -this.size * this.active : 0;
this.swipes.forEach(function (swipe) {
swipe.offset = 0;
});
this.autoPlay();
},
onResize: function onResize() {
this.initialize(this.activeIndicator);
},
onTouchStart: function onTouchStart(event) {
if (!this.touchable) return;
this.clear();
this.swiping = true;
this.touchStart(event);
this.correctPosition();
},
onTouchMove: function onTouchMove(event) {
if (!this.touchable || !this.swiping) return;
this.touchMove(event);
if (this.isCorrectDirection) {
event.preventDefault();
event.stopPropagation();
this.move(0, Math.min(Math.max(this.delta, -this.size), this.size));
}
},
onTouchEnd: function onTouchEnd() {
if (!this.touchable || !this.swiping) return;
if (this.delta && this.isCorrectDirection) {
var offset = this.vertical ? this.offsetY : this.offsetX;
this.move(offset > 0 ? this.delta > 0 ? -1 : 1 : 0);
}
this.swiping = false;
this.autoPlay();
},
move: function move(_move, offset) {
if (_move === void 0) {
_move = 0;
}
if (offset === void 0) {
offset = 0;
}
var delta = this.delta,
active = this.active,
count = this.count,
swipes = this.swipes,
trackSize = this.trackSize;
var atFirst = active === 0;
var atLast = active === count - 1;
var outOfBounds = !this.loop && (atFirst && (offset > 0 || _move < 0) || atLast && (offset < 0 || _move > 0));
if (outOfBounds || count <= 1) {
return;
}
if (swipes[0]) {
swipes[0].offset = atLast && (delta < 0 || _move > 0) ? trackSize : 0;
}
if (swipes[count - 1]) {
swipes[count - 1].offset = atFirst && (delta > 0 || _move < 0) ? -trackSize : 0;
}
if (_move && active + _move >= -1 && active + _move <= count) {
this.active += _move;
}
this.offset = offset - this.active * this.size;
},
swipeTo: function swipeTo(index) {
var _this = this;
this.swiping = true;
this.resetTouchStatus();
this.correctPosition();
setTimeout(function () {
_this.swiping = false;
_this.move(index % _this.count - _this.active);
}, 30);
},
correctPosition: function correctPosition() {
if (this.active <= -1) {
this.move(this.count);
}
if (this.active >= this.count) {
this.move(-this.count);
}
},
clear: function clear() {
clearTimeout(this.timer);
},
autoPlay: function autoPlay() {
var _this2 = this;
var autoplay = this.autoplay;
if (autoplay && this.count > 1) {
this.clear();
this.timer = setTimeout(function () {
_this2.swiping = true;
_this2.resetTouchStatus();
_this2.correctPosition();
setTimeout(function () {
_this2.swiping = false;
_this2.move(1);
_this2.autoPlay();
}, 30);
}, autoplay);
}
},
onTransitionend: function onTransitionend(event) {
event.stopPropagation();
this.$emit('change', this.activeIndicator);
}
},
render: function render(h) {
var _this3 = this;
var count = this.count,
activeIndicator = this.activeIndicator;
var Indicator = this.$slots.indicator || this.showIndicators && count > 1 && h("div", {
"class": bem('indicators', {
vertical: this.vertical
}),
"on": {
"transitionend": _event.stop
}
}, [Array.apply(void 0, Array(count)).map(function (empty, index) {
return h("i", {
"class": bem('indicator', {
active: index === activeIndicator
}),
"style": index === activeIndicator ? _this3.indicatorStyle : null
});
})]);
return h("div", {
"class": bem()
}, [h("div", {
"style": this.trackStyle,
"class": bem('track'),
"on": {
"touchstart": this.onTouchStart,
"touchmove": this.onTouchMove,
"touchend": this.onTouchEnd,
"touchcancel": this.onTouchEnd,
"transitionend": this.onTransitionend
}
}, [this.$slots.default]), Indicator]);
}
});
exports.default = _default;