UNPKG

@meve/ui

Version:

Argon design system components library

453 lines (399 loc) 13.4 kB
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;