UNPKG

antd-mobile

Version:
173 lines (172 loc) 7.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Slide = void 0; var _react = _interopRequireWildcard(require("react")); var _web = require("@react-spring/web"); var _ahooks = require("ahooks"); var _rubberband = require("../../utils/rubberband"); var _useDragAndPinch = require("../../utils/use-drag-and-pinch"); var _bound = require("../../utils/bound"); var mat = _interopRequireWildcard(require("../../utils/matrix")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const classPrefix = `adm-image-viewer`; const Slide = props => { const { dragLockRef, maxZoom } = props; const controlRef = (0, _react.useRef)(null); const imgRef = (0, _react.useRef)(null); const [{ matrix }, api] = (0, _web.useSpring)(() => ({ matrix: mat.create(), config: { tension: 200 } })); const controlSize = (0, _ahooks.useSize)(controlRef); const imgSize = (0, _ahooks.useSize)(imgRef); const pinchLockRef = (0, _react.useRef)(false); const boundMatrix = (nextMatrix, type, last = false) => { if (!controlSize || !imgSize) return nextMatrix; const controlLeft = -controlSize.width / 2; const controlTop = -controlSize.height / 2; const imgLeft = -imgSize.width / 2; const imgTop = -imgSize.height / 2; const zoom = mat.getScaleX(nextMatrix); const scaledImgWidth = zoom * imgSize.width; const scaledImgHeight = zoom * imgSize.height; const [x, y] = mat.apply(nextMatrix, [imgLeft, imgTop]); if (type === 'translate') { let boundedX = x; let boundedY = y; if (scaledImgWidth > controlSize.width) { const minX = controlLeft - (scaledImgWidth - controlSize.width); const maxX = controlLeft; boundedX = last ? (0, _bound.bound)(x, minX, maxX) : (0, _rubberband.rubberbandIfOutOfBounds)(x, minX, maxX, zoom * 50); } else { boundedX = -scaledImgWidth / 2; } if (scaledImgHeight > controlSize.height) { const minY = controlTop - (scaledImgHeight - controlSize.height); const maxY = controlTop; boundedY = last ? (0, _bound.bound)(y, minY, maxY) : (0, _rubberband.rubberbandIfOutOfBounds)(y, minY, maxY, zoom * 50); } else { boundedY = -scaledImgHeight / 2; } return mat.translate(nextMatrix, boundedX - x, boundedY - y); } if (type === 'scale' && last) { const [boundedX, boundedY] = [scaledImgWidth > controlSize.width ? (0, _bound.bound)(x, controlLeft - (scaledImgWidth - controlSize.width), controlLeft) : -scaledImgWidth / 2, scaledImgHeight > controlSize.height ? (0, _bound.bound)(y, controlTop - (scaledImgHeight - controlSize.height), controlTop) : -scaledImgHeight / 2]; return mat.translate(nextMatrix, boundedX - x, boundedY - y); } return nextMatrix; }; (0, _useDragAndPinch.useDragAndPinch)({ onDrag: state => { if (state.first) return; if (state.pinching) return state.cancel(); if (state.tap && state.elapsedTime > 0 && state.elapsedTime < 1000) { // 判断点击时间>0是为了过滤掉非正常操作,例如用户长按选择图片之后的取消操作(也是一次点击) props.onTap(); return; } const currentZoom = mat.getScaleX(matrix.get()); if (dragLockRef) { dragLockRef.current = currentZoom !== 1; } if (!pinchLockRef.current && currentZoom <= 1) { api.start({ matrix: mat.create() }); } else { const currentMatrix = matrix.get(); const offset = [state.offset[0] - mat.getTranslateX(currentMatrix), state.offset[1] - mat.getTranslateY(currentMatrix)]; const nextMatrix = mat.translate(currentMatrix, ...(state.last ? [offset[0] + state.velocity[0] * state.direction[0] * 200, offset[1] + state.velocity[1] * state.direction[1] * 200] : offset)); api.start({ matrix: boundMatrix(nextMatrix, 'translate', state.last), immediate: !state.last }); } }, onPinch: state => { var _a; pinchLockRef.current = !state.last; const [d] = state.offset; if (d < 0) return; let mergedMaxZoom; if (maxZoom === 'auto') { mergedMaxZoom = controlSize && imgSize ? Math.max(controlSize.height / imgSize.height, controlSize.width / imgSize.width) : 1; } else { mergedMaxZoom = maxZoom; } const nextZoom = state.last ? (0, _bound.bound)(d, 1, mergedMaxZoom) : d; (_a = props.onZoomChange) === null || _a === void 0 ? void 0 : _a.call(props, nextZoom); if (state.last && nextZoom <= 1) { api.start({ matrix: mat.create() }); if (dragLockRef) { dragLockRef.current = false; } } else { if (!controlSize) return; const currentMatrix = matrix.get(); const currentZoom = mat.getScaleX(currentMatrix); const originOffsetX = state.origin[0] - controlSize.width / 2; const originOffsetY = state.origin[1] - controlSize.height / 2; let nextMatrix = mat.translate(currentMatrix, -originOffsetX, -originOffsetY); nextMatrix = mat.scale(nextMatrix, nextZoom / currentZoom); nextMatrix = mat.translate(nextMatrix, originOffsetX, originOffsetY); api.start({ matrix: boundMatrix(nextMatrix, 'scale', state.last), immediate: !state.last }); if (dragLockRef) { dragLockRef.current = true; } } } }, { target: controlRef, drag: { // filterTaps: true, from: () => [mat.getTranslateX(matrix.get()), mat.getTranslateY(matrix.get())], pointer: { touch: true } }, pinch: { from: () => [mat.getScaleX(matrix.get()), 0], pointer: { touch: true } } }); return _react.default.createElement("div", { className: `${classPrefix}-slide`, onPointerMove: e => { if (mat.getScaleX(matrix.get()) !== 1) { e.stopPropagation(); } } }, _react.default.createElement("div", { className: `${classPrefix}-control`, ref: controlRef }, _react.default.createElement(_web.animated.div, { className: `${classPrefix}-image-wrapper`, style: { matrix } }, _react.default.createElement("img", { ref: imgRef, src: props.image, draggable: false, alt: props.image })))); }; exports.Slide = Slide;