| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 | // Utilsimport { createNamespace } from '../utils';import { isHidden } from '../utils/dom/style';import { preventDefault } from '../utils/dom/event';import { doubleRaf } from '../utils/dom/raf';import { range } from '../utils/format/number'; // Mixinsimport { TouchMixin } from '../mixins/touch';import { ParentMixin } from '../mixins/relation';import { BindEventMixin } from '../mixins/bind-event';var _createNamespace = createNamespace('swipe'),    createComponent = _createNamespace[0],    bem = _createNamespace[1];export default createComponent({  mixins: [TouchMixin, ParentMixin('vanSwipe'), BindEventMixin(function (bind, isBind) {    bind(window, 'resize', this.resize, true);    bind(window, 'orientationchange', this.resize, true);    bind(window, 'visibilitychange', this.onVisibilityChange);    if (isBind) {      this.initialize();    } else {      this.clear();    }  })],  props: {    width: [Number, String],    height: [Number, String],    autoplay: [Number, String],    vertical: Boolean,    lazyRender: Boolean,    indicatorColor: String,    loop: {      type: Boolean,      default: true    },    duration: {      type: [Number, String],      default: 500    },    touchable: {      type: Boolean,      default: true    },    initialSwipe: {      type: [Number, String],      default: 0    },    showIndicators: {      type: Boolean,      default: true    },    stopPropagation: {      type: Boolean,      default: true    }  },  data: function data() {    return {      rect: null,      offset: 0,      active: 0,      deltaX: 0,      deltaY: 0,      swiping: false,      computedWidth: 0,      computedHeight: 0    };  },  watch: {    children: function children() {      this.initialize();    },    initialSwipe: function initialSwipe() {      this.initialize();    },    autoplay: function autoplay(_autoplay) {      if (_autoplay > 0) {        this.autoPlay();      } else {        this.clear();      }    }  },  computed: {    count: function count() {      return this.children.length;    },    maxCount: function maxCount() {      return Math.ceil(Math.abs(this.minOffset) / this.size);    },    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 style = {        transitionDuration: (this.swiping ? 0 : this.duration) + "ms",        transform: "translate" + (this.vertical ? 'Y' : 'X') + "(" + this.offset + "px)"      };      if (this.size) {        var mainAxis = this.vertical ? 'height' : 'width';        var crossAxis = this.vertical ? 'width' : 'height';        style[mainAxis] = this.trackSize + "px";        style[crossAxis] = this[crossAxis] ? this[crossAxis] + "px" : '';      }      return style;    },    indicatorStyle: function indicatorStyle() {      return {        backgroundColor: this.indicatorColor      };    },    minOffset: function minOffset() {      return (this.vertical ? this.rect.height : this.rect.width) - this.size * this.count;    }  },  mounted: function mounted() {    this.bindTouchEvent(this.$refs.track);  },  methods: {    // initialize swipe position    initialize: function initialize(active) {      if (active === void 0) {        active = +this.initialSwipe;      }      if (!this.$el || isHidden(this.$el)) {        return;      }      clearTimeout(this.timer);      var rect = {        width: this.$el.offsetWidth,        height: this.$el.offsetHeight      };      this.rect = rect;      this.swiping = true;      this.active = active;      this.computedWidth = +this.width || rect.width;      this.computedHeight = +this.height || rect.height;      this.offset = this.getTargetOffset(active);      this.children.forEach(function (swipe) {        swipe.offset = 0;      });      this.autoPlay();    },    // @exposed-api    resize: function resize() {      this.initialize(this.activeIndicator);    },    onVisibilityChange: function onVisibilityChange() {      if (document.hidden) {        this.clear();      } else {        this.autoPlay();      }    },    onTouchStart: function onTouchStart(event) {      if (!this.touchable) return;      this.clear();      this.touchStartTime = Date.now();      this.touchStart(event);      this.correctPosition();    },    onTouchMove: function onTouchMove(event) {      if (!this.touchable || !this.swiping) return;      this.touchMove(event);      if (this.isCorrectDirection) {        preventDefault(event, this.stopPropagation);        this.move({          offset: this.delta        });      }    },    onTouchEnd: function onTouchEnd() {      if (!this.touchable || !this.swiping) return;      var size = this.size,          delta = this.delta;      var duration = Date.now() - this.touchStartTime;      var speed = delta / duration;      var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(delta) > size / 2;      if (shouldSwipe && this.isCorrectDirection) {        var offset = this.vertical ? this.offsetY : this.offsetX;        var pace = 0;        if (this.loop) {          pace = offset > 0 ? delta > 0 ? -1 : 1 : 0;        } else {          pace = -Math[delta > 0 ? 'ceil' : 'floor'](delta / size);        }        this.move({          pace: pace,          emitChange: true        });      } else if (delta) {        this.move({          pace: 0        });      }      this.swiping = false;      this.autoPlay();    },    getTargetActive: function getTargetActive(pace) {      var active = this.active,          count = this.count,          maxCount = this.maxCount;      if (pace) {        if (this.loop) {          return range(active + pace, -1, count);        }        return range(active + pace, 0, maxCount);      }      return active;    },    getTargetOffset: function getTargetOffset(targetActive, offset) {      if (offset === void 0) {        offset = 0;      }      var currentPosition = targetActive * this.size;      if (!this.loop) {        currentPosition = Math.min(currentPosition, -this.minOffset);      }      var targetOffset = offset - currentPosition;      if (!this.loop) {        targetOffset = range(targetOffset, this.minOffset, 0);      }      return targetOffset;    },    move: function move(_ref) {      var _ref$pace = _ref.pace,          pace = _ref$pace === void 0 ? 0 : _ref$pace,          _ref$offset = _ref.offset,          offset = _ref$offset === void 0 ? 0 : _ref$offset,          emitChange = _ref.emitChange;      var loop = this.loop,          count = this.count,          active = this.active,          children = this.children,          trackSize = this.trackSize,          minOffset = this.minOffset;      if (count <= 1) {        return;      }      var targetActive = this.getTargetActive(pace);      var targetOffset = this.getTargetOffset(targetActive, offset); // auto move first and last swipe in loop mode      if (loop) {        if (children[0] && targetOffset !== minOffset) {          var outRightBound = targetOffset < minOffset;          children[0].offset = outRightBound ? trackSize : 0;        }        if (children[count - 1] && targetOffset !== 0) {          var outLeftBound = targetOffset > 0;          children[count - 1].offset = outLeftBound ? -trackSize : 0;        }      }      this.active = targetActive;      this.offset = targetOffset;      if (emitChange && targetActive !== active) {        this.$emit('change', this.activeIndicator);      }    },    // @exposed-api    prev: function prev() {      var _this = this;      this.correctPosition();      this.resetTouchStatus();      doubleRaf(function () {        _this.swiping = false;        _this.move({          pace: -1,          emitChange: true        });      });    },    // @exposed-api    next: function next() {      var _this2 = this;      this.correctPosition();      this.resetTouchStatus();      doubleRaf(function () {        _this2.swiping = false;        _this2.move({          pace: 1,          emitChange: true        });      });    },    // @exposed-api    swipeTo: function swipeTo(index, options) {      var _this3 = this;      if (options === void 0) {        options = {};      }      this.correctPosition();      this.resetTouchStatus();      doubleRaf(function () {        var targetIndex;        if (_this3.loop && index === _this3.count) {          targetIndex = _this3.active === 0 ? 0 : index;        } else {          targetIndex = index % _this3.count;        }        if (options.immediate) {          doubleRaf(function () {            _this3.swiping = false;          });        } else {          _this3.swiping = false;        }        _this3.move({          pace: targetIndex - _this3.active,          emitChange: true        });      });    },    correctPosition: function correctPosition() {      this.swiping = true;      if (this.active <= -1) {        this.move({          pace: this.count        });      }      if (this.active >= this.count) {        this.move({          pace: -this.count        });      }    },    clear: function clear() {      clearTimeout(this.timer);    },    autoPlay: function autoPlay() {      var _this4 = this;      var autoplay = this.autoplay;      if (autoplay > 0 && this.count > 1) {        this.clear();        this.timer = setTimeout(function () {          _this4.next();          _this4.autoPlay();        }, autoplay);      }    },    genIndicator: function genIndicator() {      var _this5 = this;      var h = this.$createElement;      var count = this.count,          activeIndicator = this.activeIndicator;      var slot = this.slots('indicator');      if (slot) {        return slot;      }      if (this.showIndicators && count > 1) {        return h("div", {          "class": bem('indicators', {            vertical: this.vertical          })        }, [Array.apply(void 0, Array(count)).map(function (empty, index) {          return h("i", {            "class": bem('indicator', {              active: index === activeIndicator            }),            "style": index === activeIndicator ? _this5.indicatorStyle : null          });        })]);      }    }  },  render: function render() {    var h = arguments[0];    return h("div", {      "class": bem()    }, [h("div", {      "ref": "track",      "style": this.trackStyle,      "class": bem('track', {        vertical: this.vertical      })    }, [this.slots()]), this.genIndicator()]);  }});
 |