utils.js 3.48 KB
Newer Older
xhw committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
function deleteProps(obj) {
	const object = obj;
	Object.keys(object).forEach(key => {
		try {
			object[key] = null;
		} catch (e) { // no getter for object
		}

		try {
			delete object[key];
		} catch (e) { // something got wrong
		}
	});
}

function getTranslate(el, axis = 'x') {
	let curTransform;
	if (axis === 'x') {
		curTransform = el.translate;
	}

	if (axis === 'y') {
		curTransform = el.translate;
	}
	return curTransform || 0;
}

function isObject(o) {
	return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) ===
		'Object';
}

function now() {
	return Date.now();
}

function nextTick(callback, delay = 0) {
	return setTimeout(callback, delay);
}

function extend(...args) {
	const to = Object(args[0]);
	const noExtend = ['__proto__', 'constructor', 'prototype'];

	for (let i = 1; i < args.length; i += 1) {
		const nextSource = args[i];

		if (nextSource !== undefined && nextSource !== null) {
			const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);

			for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
				const nextKey = keysArray[nextIndex];
				const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);

				if (desc !== undefined && desc.enumerable) {
					if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
						if (nextSource[nextKey].__swiper__) {
							to[nextKey] = nextSource[nextKey];
						} else {
							extend(to[nextKey], nextSource[nextKey]);
						}
					} else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
						to[nextKey] = {};

						if (nextSource[nextKey].__swiper__) {
							to[nextKey] = nextSource[nextKey];
						} else {
							extend(to[nextKey], nextSource[nextKey]);
						}
					} else {
						to[nextKey] = nextSource[nextKey];
					}
				}
			}
		}
	}

	return to;
}

function setCSSProperty(el, varName, varValue) {
	el.style.setProperty(varName, varValue);
}

function animateCSSModeScroll({
	swiper,
	targetPosition,
	side
}) {
	const window = getWindow();
	const startPosition = -swiper.translate;
	let startTime = null;
	let time;
	const duration = swiper.params.speed;
	swiper.wrapperEl.style.scrollSnapType = 'none';
	window.cancelAnimationFrame(swiper.cssModeFrameID);
	const dir = targetPosition > startPosition ? 'next' : 'prev';

	const isOutOfBound = (current, target) => {
		return dir === 'next' && current >= target || dir === 'prev' && current <= target;
	};

	const animate = () => {
		time = new Date().getTime();

		if (startTime === null) {
			startTime = time;
		}

		const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
		const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
		let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);

		if (isOutOfBound(currentPosition, targetPosition)) {
			currentPosition = targetPosition;
		}

		swiper.wrapperEl.scrollTo({
			[side]: currentPosition
		});

		if (isOutOfBound(currentPosition, targetPosition)) {
			swiper.wrapperEl.style.overflow = 'hidden';
			swiper.wrapperEl.style.scrollSnapType = '';
			setTimeout(() => {
				swiper.wrapperEl.style.overflow = '';
				swiper.wrapperEl.scrollTo({
					[side]: currentPosition
				});
			});
			window.cancelAnimationFrame(swiper.cssModeFrameID);
			return;
		}

		swiper.cssModeFrameID = window.requestAnimationFrame(animate);
	};

	animate();
}

export {
	deleteProps,
	extend,
	nextTick,
	now,
	setCSSProperty,
	animateCSSModeScroll,
	getTranslate,
	isObject
};