關(guān)于Swiper,這里就不再多說。
ionic的ion-slides組件也是基于Swiper的再封裝。
Swiper官網(wǎng)地址:http://idangero.us/swiper/#.Vmc1J-ODFBc
ion-slides文檔地址:https://ionicframework.com/docs/v1/api/directive/ionSlides/
Note
我們需要用到ngTouch.js來監(jiān)聽touch事件。
大家最好在項目中引用ngTouch.js,而不是ngTouch.min.js,因為我們可能會在ngTouch.js里面屏蔽幾句代碼。
如果你的項目中還沒有這個插件,也請自行下載之。
下載地址:https://github.com/nglar/ngTouch
閑話不多說,直接上代碼!
HTML代碼:
<div class='imc-swiper-container'>
<div class='imc-swiper-wrapper' ng-touchend="onTouchEnd($event)" ng-touchmove="onTouchMove($event)" ng-touchstart="onTouchStart($event)">
<div ng-repeat='slide in imcSlides' class='imc-swiper-slide'>[YOUR DOM ELEMENTS]</div>
</div>
</div>
CSS代碼:
.imc-swiper-container {
min-height: 120px;
height: 100%;
overflow: hidden;
position: relative;
}
.imc-swiper-wrapper {
display: flex;
align-items: flex-start;
height: 100%;
transition-property: transform;
}
.imc-swiper-slider {
display: block;
width: 100%;
height: 100%;
min-height: 120px;
flex-shrink: 0;
}
JS代碼:
var startX = 0;
var startY = 0;
var currentIndex = 0;
var minMoveDistance = 100;
var itemWidth = document.body.offsetWidth;
var isUpDown;
$scope.onTouchStart = function (event) {
startX = event.originalEvent.changedTouches[0].pageX;
startY = event.originalEvent.changedTouches[0].pageY;
};
$scope.onTouchMove = function (event) {
var currentX = event.originalEvent.changedTouches[0].pageX;
var currentY = event.originalEvent.changedTouches[0].pageY;
/**
* 本文的重中之重,就是如何判斷你的操作是上下滑動還是左右滑動!!!
* 最開始,是想用滑動的距離來判斷,
* 當x的變化超過某個數(shù)值的時候就表示是左右滑動;
* 當y的變化超過某個數(shù)值的時候就表示是上下滑動。
* 當然想法是美好的,但是現(xiàn)實卻是殘酷的。
* 這樣子做了之后,發(fā)現(xiàn)上下滑動的時候同時也能左右滑動。允悲!
*
* 最后,在閱讀了ion-slides組件的源碼之后,
* 發(fā)現(xiàn)它是用滑動的角度來判定滑動方向的
* touchAngle = Math.atan2(Math.abs(currentY - startY), Math.abs(currentX - startX)) * 180 / Math.PI
* 直接copy過來,確實好用!
*
* 最后的最后,如果你已經(jīng)這樣做了,
* 但是當你手指放在這個組件上不能上下滑動整個屏幕,
* 那么你可能需要屏蔽掉ngTouch.js里面的// event.preventDefault();
*
* */
if (typeof isUpDown === 'undefined') {
var touchAngle = Math.atan2(Math.abs(currentY - startY), Math.abs(currentX - startX)) * 180 / Math.PI;
isUpDown = touchAngle > 45;
}
if (isUpDown) {
return;
}
event.preventDefault();
event.stopPropagation();
var offsetX = currentX - startX;
if (Math.abs(offsetX) > itemWidth) {
offsetX = offsetX > 0 ? itemWidth : -itemWidth;
}
var translateX = (-itemWidth * currentIndex) + offsetX;
angular.element(event.currentTarget).css('transform', 'translate3d(translateX, 0px, 0px)');
angular.element(event.currentTarget).css('transition-duration', '0ms');
};
$scope.onTouchEnd = function (event) {
if (isUpDown) {
isUpDown = undefined;
return;
}
isUpDown = undefined;
var endX = event.originalEvent.changedTouches[0].pageX;
var offset = endX - startX;
if (offset > minMoveDistance) {
// touch move right
var translateX;
if (currentIndex === 0) {
translateX = 0;
} else {
translateX = -itemWidth * (currentIndex - 1);
}
angular.element(event.currentTarget).css('transform', 'translate3d(translateX, 0px, 0px)');
angular.element(childEle).css('transition-duration', '500ms');
if (currentIndex !== 0) {
currentIndex--;
}
} else if (offset < -minMoveDistance) {
// touch move left
var translateX;
if (currentIndex === event.currentTarget.children.length - 1) {
translateX = -itemWidth * currentIndex;
} else {
translateX = -itemWidth * (currentIndex + 1);
}
angular.element(event.currentTarget).css('transform', 'translate3d(translateX, 0px, 0px)');
angular.element(event.currentTarget).css('transition-duration', '500ms');
if (currentIndex !== event.currentTarget.children.length - 1) {
currentIndex++;
}
} else {
var translateX = -itemWidth * currentIndex;
angular.element(event.currentTarget).css('transform', 'translate3d(translateX, 0px, 0px)');
angular.element(event.currentTarget).css('transition-duration', '500ms');
}
};
}
后記
說是造一個簡單的Swiper,其實就是照著ionSlides組件仿了一個粗糙的Swiper。
更像是閱讀了源碼之后交的一份簡單的作業(yè)。
當然,還有很多地方還可以做到更好更加酷炫,大家一起努力吧!
- slide循環(huán)
- 垂直方向滑動
- 手指短時間的滑動切換到下一個slide(使用時間戳計時)
- 加載無限多的slide
- 更加酷炫的轉(zhuǎn)場動畫