UNPKG

@bytedance/mona-client-web

Version:

web for mona

269 lines 11.8 kB
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); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import React, { useRef, useEffect, useState, useCallback } from 'react'; import { formatTouchEvent, genEvent } from '../utils'; import styles from './index.module.less'; import { useHandlers } from '../hooks'; var getDistance = function (start, stop) { return Math.hypot(stop.x - start.x, stop.y - start.y); }; var checkPosi = function (value, wrapperInfo, itemInfo, outOfBounds) { var x = value.x, y = value.y; var wrapperWidth = wrapperInfo.wrapperWidth, wrapperHeight = wrapperInfo.wrapperHeight; var itemWidth = itemInfo.itemWidth, itemHeight = itemInfo.itemHeight; var _a = [true, true], overflowX = _a[0], overflowY = _a[1]; var xLimit = wrapperWidth - itemWidth; var yLimit = wrapperHeight - itemHeight; var _b = [0, xLimit], xMin = _b[0], xMax = _b[1]; var _c = [0, yLimit], yMin = _c[0], yMax = _c[1]; if (outOfBounds) { var xOverflowLimit = (itemWidth / 2) * 0.8; var yOverflowLimit = (itemHeight / 2) * 0.8; xMin -= xOverflowLimit; xMax += xOverflowLimit; yMin -= yOverflowLimit; yMax += yOverflowLimit; } if (x < xMin) { x = xMin; } else if (x > xMax) { x = xMax; } if (x >= 0 && x <= xLimit) { overflowX = false; } if (y < yMin) { y = yMin; } else if (y > yMax) { y = yMax; } if (y >= 0 && y <= yLimit) { overflowY = false; } return { data: { x: x, y: y }, overflow: overflowY || overflowX, }; }; var MovableView = function (props) { var // scale, _a = props.scaleValue, // scale, scaleValue = _a === void 0 ? 1 : _a, _b = props.scaleMax, scaleMax = _b === void 0 ? 10 : _b, _c = props.scaleMin, scaleMin = _c === void 0 ? 0.5 : _c, children = props.children, disabled = props.disabled, _d = props.x, x = _d === void 0 ? 0 : _d, _e = props.y, y = _e === void 0 ? 0 : _e, // onScale, _f = props.damping, // onScale, damping = _f === void 0 ? 20 : _f, _g = props.friction, friction = _g === void 0 ? 2 : _g, //@ts-ignore wrapperWidth = props.wrapperWidth, //@ts-ignore wrapperHeight = props.wrapperHeight, //@ts-ignore wrapperRef = props.wrapperRef, //@ts-ignore scaleArea = props.scaleArea, className = props.className, onHtouchMove = props.onHtouchMove, onVtouchMove = props.onVtouchMove, inertia = props.inertia, outOfBounds = props.outOfBounds, scale = props.scale, animation = props.animation, restProps = __rest(props, ["scaleValue", "scaleMax", "scaleMin", "children", "disabled", "x", "y", "damping", "friction", "wrapperWidth", "wrapperHeight", "wrapperRef", "scaleArea", "className", "onHtouchMove", "onVtouchMove", "inertia", "outOfBounds", "scale", "animation"]); // const ref = useRef<HTMLDivElement>(null); var domRef = useRef(null); var disRef = useRef({ distX: 0, distY: 0 }); var propsRef = useRef(props); var stateRef = useRef({}); var _h = useState({ x: 0, y: 0 }), _j = _h[0], innerX = _j.x, innerY = _j.y, setPosition = _h[1]; var _k = useState(false), executing = _k[0], setExecuting = _k[1]; var _l = useState(scaleValue), innerScale = _l[0], setScale = _l[1]; var _m = useHandlers(restProps), handleClassName = _m.handleClassName, handlerProps = __rest(_m, ["handleClassName"]); useEffect(function () { var sValue = scaleValue < scaleMax ? (scaleValue > scaleMin ? scaleValue : scaleMin) : scaleMax; setScale(sValue); }, [scaleValue, scaleMax, scaleMin]); propsRef.current = props; stateRef.current = { executing: executing, }; var setPositionWithCheck = useCallback(function (posi, outOfBounds, e) { outOfBounds = outOfBounds === undefined ? propsRef.current.outOfBounds : outOfBounds; var check = function (posi) { var _a, _b, _c; var _d = (_a = domRef.current.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {}, realWidth = _d.width, realHeight = _d.height; var _e = checkPosi(posi, { wrapperWidth: wrapperWidth, wrapperHeight: wrapperHeight }, { // 获取scale之后的宽高 itemHeight: realHeight, itemWidth: realWidth, }, !!outOfBounds), data = _e.data, overflow = _e.overflow; var formatEvent; if (e) { formatEvent = formatTouchEvent({ event: e, type: 'change' }); formatEvent.detail = __assign({}, data); if (overflow) { formatEvent.detail.source = 'touch-out-of-bounds'; } else { formatEvent.detail.source = 'touch'; } } else { formatEvent = genEvent({ detail: {}, type: 'change' }); formatEvent.detail = __assign({}, data); formatEvent.detail.source = ''; } (_c = (_b = propsRef.current).onChange) === null || _c === void 0 ? void 0 : _c.call(_b, formatEvent); return { data: data, overflow: overflow }; }; if (typeof posi === 'function') { setPosition(function (pre) { return check(posi(pre)).data; }); } else { setPosition(check(posi).data); } }, [wrapperWidth, wrapperHeight]); useEffect(function () { setExecuting(true); setPositionWithCheck({ x: +x, y: +y }, false); }, [x, y, setPositionWithCheck]); var handleTouchStart = useCallback(function (e) { setExecuting(false); var _a = e.targetTouches[0], clientX = _a.clientX, clientY = _a.clientY; var posInfo = domRef.current.getBoundingClientRect(); disRef.current.distX = clientX - posInfo.left; disRef.current.distY = clientY - posInfo.top; }, []); var handleScale = useCallback(function (e) { var _a = e.targetTouches[0], clientX = _a.clientX, clientY = _a.clientY; var _b = disRef.current, distX = _b.distX, distY = _b.distY; var L = clientX - distX, T = clientY - distY; if (!propsRef.current.scale) { return; } var touches = e.targetTouches; var events = touches[0]; var events2 = touches[1]; var zoom = getDistance({ x: events.pageX, y: events.pageY, }, { x: events2.pageX, y: events2.pageY, }); setScale(function (preScale) { var _a, _b; var _c = propsRef.current, scaleMin = _c.scaleMin, scaleMax = _c.scaleMax; var newScaleValue = preScale * zoom; var res = newScaleValue < scaleMax ? (newScaleValue > scaleMin ? newScaleValue : scaleMin) : scaleMax; var formatEvent = formatTouchEvent({ event: e, type: 'change' }); formatEvent.detail = { x: L, y: T, scale: res, }; (_b = (_a = propsRef.current).onScale) === null || _b === void 0 ? void 0 : _b.call(_a, formatEvent); return res; }); }, []); var handleTouchMove = useCallback(function (e) { var tLength = e.targetTouches.length; var _a = e.targetTouches[0], clientX = _a.clientX, clientY = _a.clientY; var _b = disRef.current, distX = _b.distX, distY = _b.distY; var L = clientX - distX, T = clientY - distY; if (tLength === 1) { var direction = propsRef.current.direction; if (direction === 'horizontal') { setPositionWithCheck(function (pre) { return ({ x: L, y: pre.y }); }, undefined, e); } else if (direction === 'vertical') { setPositionWithCheck(function (pre) { return ({ x: pre.x, y: T }); }, undefined, e); } else if (direction === 'all') { setPositionWithCheck({ x: L, y: T }, undefined, e); } else { return; } } else if (tLength === 2) { !scaleArea && handleScale(e); } }, [setPositionWithCheck, handleScale, scaleArea]); var handleTouchEnd = useCallback(function (e) { setPosition(function (_a) { var _b, _c, _d; var x = _a.x, y = _a.y; var _e = propsRef.current, wrapperWidth = _e.wrapperWidth, wrapperHeight = _e.wrapperHeight; var _f = (_b = domRef.current.getBoundingClientRect()) !== null && _b !== void 0 ? _b : {}, realWidth = _f.width, realHeight = _f.height; var data = checkPosi({ x: x, y: y }, { wrapperWidth: wrapperWidth, wrapperHeight: wrapperHeight }, { itemHeight: realHeight, itemWidth: realWidth, }, false).data; var formatEvent; formatEvent = formatTouchEvent({ event: e, type: 'change' }); formatEvent.detail = __assign({}, data); formatEvent.detail.source = 'out-of-bounds'; if (data.x !== x || data.y !== y) { (_d = (_c = propsRef.current).onChange) === null || _d === void 0 ? void 0 : _d.call(_c, formatEvent); setExecuting(true); } return data; }); }, [setPositionWithCheck]); var animationTime = "".concat(4 / friction / damping, "s"); var transitionStyle = executing ? { transition: "scale ".concat(animationTime, ", transform ").concat(animationTime), } : { transition: "scale ".concat(animationTime) }; useEffect(function () { var wrapperDom = wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current; if (wrapperDom && scaleArea) { wrapperDom.addEventListener('touchmove', handleScale); } return function () { scaleArea && wrapperDom.removeEventListener('touchmove', handleScale); }; }, [handleScale, scaleArea, wrapperRef]); return ( //@ts-ignore React.createElement("span", __assign({ ref: domRef }, handlerProps, { //@ts-ignore onTransitionEnd: function () { return setExecuting(false); }, //@ts-ignore onTouchStart: disabled ? undefined : handleTouchStart, //@ts-ignore onTouchMove: disabled ? undefined : handleTouchMove, //@ts-ignore onTouchEnd: disabled ? undefined : handleTouchEnd, style: __assign({ transform: "translate(".concat(innerX, "px, ").concat(innerY, "px) scale(").concat(innerScale, ")") }, transitionStyle), className: handleClassName([className, styles.touch]) }), children)); }; export default MovableView; MovableView.defaultProps = { direction: 'none', inertia: false, outOfBounds: false, damping: 20, friction: 2, disabled: false, scale: false, scaleMin: 0.5, scaleMax: 10, animation: true, }; //# sourceMappingURL=index.js.map