@bytedance/mona-client-web
Version:
web for mona
186 lines • 7.29 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { useEffect, useRef, useState } from 'react';
import { formatTouchEvent } from '../utils';
var ANIMATION_READY = false;
function setTransform(_a) {
var ele = _a.ele, current = _a.current, vertical = _a.vertical, circular = _a.circular, duration = _a.duration, noAnimation = _a.noAnimation;
if (ele) {
var width = vertical ? ele.clientHeight : ele.clientWidth;
var realCurrent = current;
if (circular) {
realCurrent = current + 1;
}
var distance = -width * realCurrent;
var targetTransform = "".concat(vertical ? 0 : distance, "px, ").concat(!vertical ? 0 : distance, "px, 0px");
ele.style.transitionDuration = "".concat(noAnimation ? 0 : ANIMATION_READY ? duration : 0, "ms");
ele.style.transform = "translate3d(".concat(targetTransform);
ANIMATION_READY = true;
if (!noAnimation) {
setTimeout(function () {
ele.style.transitionDuration = '0ms';
}, duration);
}
}
}
var tick = 100;
function useCurrent(_a) {
var initCurrent = _a.initCurrent, total = _a.total, duration = _a.duration, circular = _a.circular;
var _b = useState(initCurrent), current = _b[0], setCurrent = _b[1];
var lockRef = useRef(false);
var noAnimationRef = useRef(true);
var min = circular ? -1 : 0;
var max = total ? (circular ? total : total - 1) : 0;
var safelySetCurrent = function (current) {
if (lockRef.current) {
return;
}
noAnimationRef.current = false;
lockRef.current = true;
var target = current < min ? min : current > max ? max : current;
setCurrent(target);
setTimeout(function () {
if (circular) {
if (target === min) {
noAnimationRef.current = true;
setCurrent(total - 1);
}
else if (target === max) {
noAnimationRef.current = true;
setCurrent(0);
}
}
lockRef.current = false;
}, duration + tick);
};
useEffect(function () {
safelySetCurrent(initCurrent);
}, [initCurrent]);
return { current: current, setCurrent: safelySetCurrent, noAnimation: noAnimationRef.current };
}
// add two fake childEle in the tail and head of the container
function preHandleEle(ele, circular) {
if (!ele || ele.children.length === 0) {
return;
}
if (circular) {
var firstChild = ele.children[0];
var lastChild = ele.children[ele.children.length - 1];
var copyedFirstChild_1 = firstChild.cloneNode(true);
var coypedLastChild_1 = lastChild.cloneNode(true);
ele.appendChild(copyedFirstChild_1);
ele.insertBefore(coypedLastChild_1, firstChild);
return function () {
copyedFirstChild_1.remove();
coypedLastChild_1.remove();
};
}
return function () { };
}
export function useSlide(_a) {
var initCurrent = _a.current, total = _a.total, _b = _a.vertical, vertical = _b === void 0 ? false : _b, duration = _a.duration, circular = _a.circular, onChange = _a.onChange;
var ref = useRef(null);
var _c = useCurrent({ initCurrent: initCurrent, total: total, duration: duration, circular: circular }), current = _c.current, setCurrent = _c.setCurrent, noAnimation = _c.noAnimation;
useEffect(function () { return preHandleEle(ref.current, circular); }, [ref.current, circular]);
useEffect(function () {
setTransform({ ele: ref.current, current: current, vertical: vertical, circular: circular, duration: duration, noAnimation: noAnimation });
}, [ref.current, current, vertical, circular, duration, noAnimation]);
var activeIndex = current < 0 ? total - 1 : current >= total ? 0 : current;
var setActiveIndex = function (index, byAuto, e) {
if (typeof onChange === 'function') {
var event_1 = e ? __assign(__assign({}, formatTouchEvent({ event: e, type: 'change' })), { detail: {
current: activeIndex,
source: byAuto ? 'autoplay' : 'touch',
} }) :
{
touches: [],
changedTouches: [],
type: 'change',
target: { id: '', tagName: '', dataset: {} },
currentTarget: { id: '', tagName: '', dataset: {} },
timeStamp: 0,
detail: {
current: activeIndex,
source: byAuto ? 'autoplay' : 'touch',
},
};
onChange(event_1);
}
setCurrent(index >= total ? 0 : index < 0 ? total - 1 : index);
};
var next = function (byAuto, e) {
setActiveIndex(current + 1, byAuto, e);
};
var prev = function (byAuto, e) {
setActiveIndex(current - 1, byAuto, e);
};
return {
next: next,
prev: prev,
wrapperRef: ref,
activeIndex: activeIndex,
};
}
var validTouchDistance = 20;
export function useTouch(_a) {
var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom, duration = _a.duration;
var startRef = useRef({ x: 0, y: 0 });
var lockRef = useRef(false);
var handleTouchStart = function (e) {
var changedTouches = e.changedTouches;
startRef.current = {
x: changedTouches[0].pageX,
y: changedTouches[0].pageY,
};
};
var handleTouchMove = function (e) {
if (lockRef.current) {
return;
}
var changedTouches = e.changedTouches;
var moveX = changedTouches[0].pageX;
var moveY = changedTouches[0].pageY;
var _a = startRef.current, x = _a.x, y = _a.y;
var dx = moveX - x;
var dy = moveY - y;
if (Math.abs(dx) >= Math.abs(dy) && Math.abs(dx) > validTouchDistance) {
lockRef.current = true;
// horizontal move
if (dx > 0) {
// l2r
right && right(e);
}
else {
// r2l
left && left(e);
}
setTimeout(function () {
lockRef.current = false;
}, duration + tick);
}
else if (Math.abs(dx) < Math.abs(dy) && Math.abs(dy) > validTouchDistance) {
lockRef.current = true;
// vertical move
if (dy > 0) {
bottom && bottom(e);
}
else {
top && top(e);
}
setTimeout(function () {
lockRef.current = false;
}, duration + tick);
}
};
return { handleTouchStart: handleTouchStart, handleTouchMove: handleTouchMove };
}
//# sourceMappingURL=hooks.js.map