Skip to content

Instantly share code, notes, and snippets.

@thinkgarden
Last active May 23, 2018 05:35
Show Gist options
  • Save thinkgarden/e0184ccf0481f2a64b2e016c56a1fa36 to your computer and use it in GitHub Desktop.
Save thinkgarden/e0184ccf0481f2a64b2e016c56a1fa36 to your computer and use it in GitHub Desktop.
[parallax] A simple parallax animation plugin for jQuery #mobile #parallax #js
!function($) {
var startPos, // 开始触摸点(X/Y坐标)
endPos,
stage, // 用于标识 onStart/onMove/onEnd 流程的第几阶段,解决 onEnd 重复调用
offset, // 偏移距离
direction, // 翻页方向
curPage, // page 当前页
pageCount, // page 数量
pageWidth, // page 宽度
pageHeight, // page 高度
$pages, // page 外部 wrapper
$pageArr, // page 列表
$animateDom, // 所有设置 [data-animate] 的动画元素
options, // 最终配置项
touchDown = false, // 手指已按下 (取消触摸移动时 transition 过渡)
movePrevent = true; // 阻止滑动 (动画过程中手指按下不可阻止)
$.fn.parallax = function(opts) {
options = $.extend({}, $.fn.parallax.defaults, opts);
return this.each(() => {
$pages = $(this);
$pageArr = $pages.find('.page');
init();
})
}
$.fn.parallax.defaults = {
direction: 'vertical',
swipeAnim: 'default',
loading: false,
onchange: function() { },
}
function init() {
if (options.loading) {
} else {
movePrevent = false;
}
//页面数量,当前页,页面高度,宽度,设置Container样式
curPage = 0;
direction = 'stay';
pageCount = $pageArr.length; // 获取 page 数量
pageWidth = document.documentElement.clientWidth; // 获取手机屏幕宽度
pageHeight = document.documentElement.clientHeight; // 获取手机屏幕高度
$animateDom = $('[data-animation]');
for (var i = 0; i < pageCount; i++) { // 批量添加 data-id
$($pageArr[i]).attr('data-id', i + 1);
}
$pages.addClass(options.direction) // 添加 direction 类
.addClass(options.swipeAnim); // 添加 swipeAnim 类
$pageArr.css({ // 初始化 page 宽高
'width': pageWidth + 'px',
'height': pageHeight + 'px'
});
if (!options.loading) {
$($pageArr[curPage]).addClass('current');
options.onchange(curPage, $pageArr[curPage], direction);
// animShow();
}
}
// 当前页动画显示
function animShow() {
$animateDom.css({
'-webkit-animation': 'none',
'display': 'none' // 解决部分 Android 机型 DOM 不自动重绘的 bug
});
}
function animatePage(newPage) {
curPage = newPage;
if (options.swipeAnim === 'default') {
var newOffset = 0;
options.direction === 'horizontal' ?
newOffset = newPage * (-pageWidth) :
newOffset = newPage * (-pageHeight);
options.direction === 'horizontal' ?
$pages.css({ '-webkit-transform': 'matrix(1, 0, 0, 1, ' + newOffset + ', 0)' }) :
$pages.css({ '-webkit-transform': 'matrix(1, 0, 0, 1, 0, ' + newOffset + ')' });
}
}
function dragToMove() {
console.log('dragToMove')
}
function addDirecClass() {
if (options.direction === 'horizontal') {
if (endPos >= startPos) {
$pages.removeClass('forward').addClass('backward');
} else if (endPos < startPos) {
$pages.removeClass('backward').addClass('forward');
}
} else {
if (endPos >= startPos) {
$pages.removeClass('forward').addClass('backward');
} else if (endPos < startPos) {
$pages.removeClass('backward').addClass('forward');
}
}
}
function isHeadOrTail() {
if ((endPos > startPos) && curPage === 0 ||
(endPos <= startPos && curPage === pageCount - 1)) {
return true;
}
return false;
}
const onStart = (e) => {
if (movePrevent === true) {
event.preventDefault();
return false;
}
touchDown = true;
options.direction === 'horizontal' ? startPos = e.pageX : startPos = e.pageY;
if (options.swipeAnim === 'default') {
$pages.addClass('drag'); // 阻止过渡效果
// offset 怎么获得
offset = $pages.css("-webkit-transform")
.replace("matrix(", "")
.replace(")", "")
.split(",");
options.direction === 'horizontal' ?
offset = parseInt(offset[4]) :
offset = parseInt(offset[5]);
}
stage = 1;
}
const onMove = (e) => {
if (movePrevent === true || touchDown === false) {
event.preventDefault();
return false;
}
event.preventDefault();
options.direction === 'horizontal' ? endPos = e.pageX : endPos = e.pageY;
addDirecClass(); // 添加方向类
if (options.drag && !isHeadOrTail()) { // 拖拽时调用
dragToMove();
}
stage = 2;
}
const onEnd = (e) => {
if (movePrevent === true || stage !== 2) {
// event.preventDefault();
// return false;
} else {
touchDown = false;
options.direction === 'horizontal' ? endPos = e.pageX : endPos = e.pageY;
if (options.swipeAnim === 'default' && !isHeadOrTail()) {
$pages.removeClass('drag');
if (Math.abs(endPos - startPos) <= 50) {
animatePage(curPage);
direction = 'stay';
}
else if (endPos >= startPos) {
animatePage(curPage - 1);
direction = 'backward';
}
else if (endPos < startPos) {
animatePage(curPage + 1);
direction = 'forward';
}
}
stage = 3;
}
}
// 事件代理绑定
$(document).on('touchstart', '.page', (e) => {
onStart(e.changedTouches[0])
}).on('touchmove', '.page', (e) => {
onMove(e.changedTouches[0]);
}).on('touchend', '.page', (e) => {
onEnd(e.changedTouches[0]);
}).on('webkitAnimationEnd webkitTransitionEnd', '.pages', function() {
if (direction !== 'stay') {
setTimeout(function() {
$(".back").hide().removeClass("back");
$(".front").show().removeClass("front");
$pages.removeClass('forward backward animate');
}, 10);
$($pageArr.removeClass('current').get(curPage)).addClass('current');
options.onchange(curPage, $pageArr[curPage], direction); // 执行回调函数
// animShow();
}
});
}(Zepto)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment