@meve/ui
Version:
Argon design system components library
453 lines (399 loc) • 13.4 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createNamespace } from '../utils/create';
import { props } from './props';
import { createParentMixin } from '../utils/mixins/relation';
import { isNumber, toNumber } from '../utils/shared';
var _createNamespace = createNamespace('swipe'),
namespace = _createNamespace.namespace,
createComponent = _createNamespace.createComponent;
var SWIPE_DELAY = 250;
var SWIPE_DISTANCE = 20;
var SwipePlugin = createComponent({
mixins: [createParentMixin('swipe')],
props: props,
data: function data() {
return {
size: 0,
trackSize: 0,
sizeUnit: 0,
trackSizeUnit: 0,
translate: 0,
lockDuration: false,
index: 0,
touching: false,
timer: -1,
startX: undefined,
startY: undefined,
startTime: undefined,
prevX: undefined,
prevY: undefined
};
},
computed: {
length: function length() {
return this.children.length;
}
},
watch: {
children: function children() {
this.initIndex();
this.resize();
}
},
mounted: function mounted() {
window.addEventListener('resize', this.resize);
},
beforeDestroy: function beforeDestroy() {
window.removeEventListener('resize', this.resize);
this.stopAutoplay();
},
methods: {
findSwipeItem: function findSwipeItem(idx) {
return this.children.find(function (_ref) {
var index = _ref.index;
return index === idx;
});
},
dispatchBorrower: function dispatchBorrower() {
var translate = this.translate,
trackSize = this.trackSize,
size = this.size,
loop = this.loop,
children = this.children;
var length = children.length;
if (!loop) {
return;
} // track越左边界
if (translate >= 0) {
this.findSwipeItem(length - 1).translate = -trackSize;
} // track越右边界
if (translate <= -(trackSize - size)) {
this.findSwipeItem(0).translate = trackSize;
} // track没越界
if (translate > -(trackSize - size) && translate < 0) {
this.findSwipeItem(length - 1).translate = 0;
this.findSwipeItem(0).translate = 0;
}
},
getSwipeIndex: function getSwipeIndex(targetSwipeIndex) {
var translate = this.translate,
size = this.size,
loop = this.loop,
length = this.length;
var swipeIndex = isNumber(targetSwipeIndex) ? targetSwipeIndex : Math.floor((translate - size / 2) / -size);
if (swipeIndex <= -1) {
return loop ? -1 : 0;
}
if (swipeIndex >= length) {
return loop ? length : length - 1;
}
return swipeIndex;
},
swipeIndexToIndex: function swipeIndexToIndex(swipeIndex) {
var loop = this.loop,
length = this.length;
if (swipeIndex === -1) {
return loop ? length - 1 : 0;
}
if (swipeIndex === length) {
return loop ? 0 : length - 1;
}
return swipeIndex;
},
boundaryIndex: function boundaryIndex(index) {
var loop = this.loop,
length = this.length;
if (index < 0) {
return loop ? length - 1 : 0;
}
if (index > length - 1) {
return loop ? 0 : length - 1;
}
return index;
},
fixPosition: function fixPosition(cb) {
var _this = this;
var translate = this.translate,
size = this.size,
length = this.length,
trackSize = this.trackSize;
var overLeft = translate >= size;
var overRight = translate <= -trackSize;
var leftTranslate = 0;
var rightTranslate = -(trackSize - size);
this.lockDuration = true; // 检测是否有越界情况 越界修正
if (overLeft || overRight) {
this.lockDuration = true;
this.translate = overRight ? leftTranslate : rightTranslate;
this.findSwipeItem(0).translate = 0;
this.findSwipeItem(length - 1).translate = 0;
}
requestAnimationFrame(function () {
_this.lockDuration = false;
cb();
});
},
initIndex: function initIndex() {
this.index = this.boundaryIndex(toNumber(this.initialIndex));
this.resize();
},
startAutoplay: function startAutoplay() {
var _this2 = this;
var autoplay = this.autoplay,
length = this.length;
if (!autoplay || length <= 1) {
return;
}
this.stopAutoplay();
this.timer = window.setTimeout(function () {
_this2.next();
_this2.startAutoplay();
}, toNumber(autoplay));
},
stopAutoplay: function stopAutoplay() {
this.timer && clearTimeout(this.timer);
},
getDirection: function getDirection(x, y) {
if (x > y && x > 10) {
return 'horizontal';
}
if (y > x && y > 10) {
return 'vertical';
}
},
handleTouchstart: function handleTouchstart(event) {
var _this3 = this;
if (this.length <= 1 || !this.touchable) {
return;
}
var _event$touches$ = event.touches[0],
clientX = _event$touches$.clientX,
clientY = _event$touches$.clientY;
this.startX = clientX;
this.startY = clientY;
this.startTime = performance.now();
this.touching = true;
this.stopAutoplay();
this.fixPosition(function () {
_this3.lockDuration = true;
});
},
handleTouchmove: function handleTouchmove(event) {
var touchable = this.touchable,
vertical = this.vertical,
touching = this.touching,
startX = this.startX,
startY = this.startY,
prevX = this.prevX,
prevY = this.prevY;
if (!touching || !touchable) {
return;
}
var _event$touches$2 = event.touches[0],
clientX = _event$touches$2.clientX,
clientY = _event$touches$2.clientY;
var deltaX = Math.abs(clientX - startX);
var deltaY = Math.abs(clientY - startY);
var direction = this.getDirection(deltaX, deltaY);
var expectDirection = vertical ? 'vertical' : 'horizontal';
if (direction === expectDirection) {
event.preventDefault();
var moveX = prevX !== undefined ? clientX - prevX : 0;
var moveY = prevY !== undefined ? clientY - prevY : 0;
this.prevX = clientX;
this.prevY = clientY;
this.translate += vertical ? moveY : moveX;
this.dispatchBorrower();
}
},
handleTouchend: function handleTouchend() {
var touching = this.touching,
vertical = this.vertical,
startX = this.startX,
startY = this.startY,
prevX = this.prevX,
prevY = this.prevY,
startTime = this.startTime,
index = this.index,
size = this.size;
if (!touching) {
return;
}
var positive = vertical ? prevY < startY : prevX < startX;
var distance = vertical ? Math.abs(startY - prevY) : Math.abs(startX - prevX);
var quickSwiping = performance.now() - startTime <= SWIPE_DELAY && distance >= SWIPE_DISTANCE;
var swipeIndex = quickSwiping ? positive ? this.getSwipeIndex(index + 1) : this.getSwipeIndex(index - 1) : this.getSwipeIndex();
this.touching = false;
this.lockDuration = false;
this.prevX = undefined;
this.prevY = undefined;
this.translate = swipeIndex * -size;
var prevIndex = index;
this.index = this.swipeIndexToIndex(swipeIndex);
this.startAutoplay();
prevIndex !== this.index && this.$emit('change', this.index);
},
resize: function resize() {
var _this4 = this;
this.lockDuration = true;
var vertical = this.vertical,
length = this.length,
swipe = this.$refs.swipe,
index = this.index;
this.size = vertical ? swipe.offsetHeight : swipe.offsetWidth;
this.trackSize = this.size * length;
this.translate = index * -this.size;
this.children.forEach(function (child) {
child.translate = 0;
});
this.startAutoplay();
setTimeout(function () {
_this4.lockDuration = false;
});
},
next: function next() {
var _this5 = this;
var length = this.length,
loop = this.loop,
index = this.index,
trackSize = this.trackSize,
size = this.size;
if (length <= 1) {
return;
}
var currentIndex = index;
this.index = this.boundaryIndex(currentIndex + 1);
this.$emit('change', this.index);
this.fixPosition(function () {
if (currentIndex === length - 1 && loop) {
_this5.findSwipeItem(0).translate = trackSize;
_this5.translate = length * -size;
return;
}
if (currentIndex !== length - 1) {
_this5.translate = _this5.index * -size;
}
});
},
prev: function prev() {
var _this6 = this;
var length = this.length,
loop = this.loop,
index = this.index,
trackSize = this.trackSize,
size = this.size;
if (length <= 1) {
return;
}
var currentIndex = index;
this.index = this.boundaryIndex(currentIndex - 1);
this.$emit('change', this.index);
this.fixPosition(function () {
if (currentIndex === 0 && loop) {
_this6.findSwipeItem(length - 1).translate = -trackSize;
_this6.translate = size;
return;
}
if (currentIndex !== 0) {
_this6.translate = _this6.index * -size;
}
});
},
to: function to(idx) {
var length = this.length,
index = this.index;
if (length <= 1 || idx === index) {
return;
}
idx = idx < 0 ? 0 : idx;
idx = idx >= length ? length : idx;
var task = idx > index ? this.next : this.prev;
Array.from({
length: Math.abs(idx - index)
}).forEach(task);
},
renderIndicator: function renderIndicator() {
var _this7 = this;
var h = this.$createElement;
var index = this.index,
length = this.length,
indicator = this.indicator,
vertical = this.vertical,
indicatorColor = this.indicatorColor;
if (this.hasSlots('indicator')) {
return this.slots('indicator', {
index: index,
length: length
});
}
if (indicator && length) {
return h("div", {
"class": [namespace('__indicators'), vertical ? namespace('--indicators-vertical') : null]
}, [Array.from({
length: length
}).map(function (_, idx) {
return h("div", {
"key": idx,
"class": [namespace('__indicator'), index === idx ? namespace('--indicator-active') : null, vertical ? namespace('--indicator-vertical') : null],
"style": {
background: indicatorColor
},
"on": _extends({}, {
"click": function click($event) {
for (var _len = arguments.length, attrs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
attrs[_key - 1] = arguments[_key];
}
(function () {
return _this7.to(idx);
}).apply(void 0, [$event].concat(attrs));
}
})
});
})]);
}
}
},
render: function render() {
var _this8 = this;
var h = arguments[0];
var vertical = this.vertical,
trackSize = this.trackSize,
translate = this.translate,
duration = this.duration,
lockDuration = this.lockDuration;
return h("div", {
"ref": "swipe",
"class": namespace()
}, [h("div", {
"class": [namespace('__track'), vertical ? namespace('--vertical') : null],
"style": {
width: !vertical ? trackSize + "px" : undefined,
height: vertical ? trackSize + "px" : undefined,
transform: "translate" + (vertical ? 'Y' : 'X') + "(" + translate + "px)",
transitionDuration: lockDuration ? "0ms" : toNumber(duration) + "ms"
},
"on": _extends({}, {
"touchstart": function touchstart($event) {
for (var _len2 = arguments.length, attrs = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
attrs[_key2 - 1] = arguments[_key2];
}
_this8.handleTouchstart.apply(_this8, [$event].concat(attrs));
},
"touchmove": function touchmove($event) {
for (var _len3 = arguments.length, attrs = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
attrs[_key3 - 1] = arguments[_key3];
}
_this8.handleTouchmove.apply(_this8, [$event].concat(attrs));
},
"touchend": function touchend($event) {
for (var _len4 = arguments.length, attrs = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
attrs[_key4 - 1] = arguments[_key4];
}
_this8.handleTouchend.apply(_this8, [$event].concat(attrs));
}
})
}, [this.slots()]), this.renderIndicator()]);
}
});
export var _SwipeComponent = SwipePlugin;
export default SwipePlugin;