UNPKG

gui-one-nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

215 lines (214 loc) 8.04 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React__default, { useRef, useState, useEffect } from 'react'; import { P as Popup } from './popup.taro-33d0bbc8.js'; import { S as Swiper } from './swiper.taro-f314d67a.js'; import { S as SwiperItem } from './swiperitem-86a3578a.js'; var defaultProps = { images: [], videos: [], show: false, autoplay: 3000, initNo: 1, contentClose: false, paginationVisible: false, paginationColor: '#fff', onClose: function onClose() {} }; var ImagePreview = function ImagePreview(props) { var images = props.images, videos = props.videos, show = props.show, initNo = props.initNo, paginationColor = props.paginationColor, paginationVisible = props.paginationVisible, autoplay = props.autoplay, contentClose = props.contentClose, onClose = props.onClose; var nutImagePreview = useRef(null); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), showPop = _useState2[0], setShowPop = _useState2[1]; var _useState3 = useState(1), _useState4 = _slicedToArray(_useState3, 2), active = _useState4[0], setActive = _useState4[1]; var _useState5 = useState(1), _useState6 = _slicedToArray(_useState5, 2), maxNo = _useState6[0], setMaxNo = _useState6[1]; var _useState7 = useState({ scale: 1, moveable: false }), _useState8 = _slicedToArray(_useState7, 2), store = _useState8[0], setStore = _useState8[1]; var _useState9 = useState(0), _useState10 = _slicedToArray(_useState9, 2), lastTouchEndTime = _useState10[0], setLastTouchEndTime = _useState10[1]; // 用来辅助监听双击 var onTouchStart = function onTouchStart(event) { var touches = event.touches; var events = touches[0]; var events2 = touches[1]; // 如果已经放大,双击应变回原尺寸;如果是原尺寸,双击应放大 var curTouchTime = new Date().getTime(); if (curTouchTime - lastTouchEndTime < 300) { var _store = store; if (_store.scale > 1) { _store.scale = 1; } else if (_store.scale === 1) { _store.scale = 2; } scaleNow(); } var store1 = store; store1.moveable = true; if (events2) { // 如果开始两指操作,记录初始时刻两指间的距离 store1.oriDistance = getDistance({ x: events.pageX, y: events.pageY }, { x: events2.pageX, y: events2.pageY }); } // 取到开始两指操作时的放大(缩小比例),store.scale 存储的是当前的放缩比(相对于标准大小 scale 为 1 的情况的放大缩小比) store1.originScale = store1.scale || 1; }; var onTouchMove = function onTouchMove(event) { var touches = event.touches; var events = touches[0]; var events2 = touches[1]; if (!store.moveable) { return; } var store1 = store; // 双指移动 if (events2) { // 获得当前两点间的距离 var curDistance = getDistance({ x: events.pageX, y: events.pageY }, { x: events2.pageX, y: events2.pageY }); /** 此处计算倍数,距离放大(缩小) k 倍则 scale 也 扩大(缩小) k 倍。距离放大(缩小)倍数 = 结束时两点距离 除以 开始时两点距离 * 注意此处的 scale 变化是基于 store.scale 的。 * store.scale 是一个暂存值,比如第一次放大 2 倍,则 store.scale 为 2。 * 再次两指触碰的时候,store.originScale 就为 store.scale 的值,基于此时的 store.scale 继续放大缩小。 * */ var curScale = curDistance / store1.oriDistance; store1.scale = store1.originScale * curScale; // 最大放大 3 倍,缩小后松手要弹回原比例 if (store1.scale > 3) { store1.scale = 3; } scaleNow(); } }; var onTouchEnd = function onTouchEnd() { setLastTouchEndTime(new Date().getTime()); var store1 = store; store1.moveable = false; if (store1.scale < 1.1 && store1.scale > 1 || store1.scale < 1) { store1.scale = 1; scaleNow(); } }; var init = function init() { document.addEventListener('touchmove', onTouchMove); document.addEventListener('touchend', onTouchEnd); document.addEventListener('touchcancel', onTouchEnd); }; useEffect(function () { if (show !== undefined) { setShowPop(show); init(); } }, [show]); useEffect(function () { if (initNo !== undefined) { setActive(initNo); } if (show !== undefined) { setShowPop(show); } if (images && videos) { setMaxNo(images.length + videos.length); } }, []); var scaleNow = function scaleNow() { if (nutImagePreview.current) { nutImagePreview.current.style.transform = "scale(".concat(store.scale, ")"); } }; var onCloseInner = function onCloseInner() { setShowPop(false); setActive(1); scaleNow(); onClose && onClose(); setStore(_objectSpread(_objectSpread({}, store), {}, { scale: 1 })); }; // 计算两个点的距离 var getDistance = function getDistance(first, second) { // 计算两个点起始时刻的距离和终止时刻的距离,终止时刻距离变大了则放大,变小了则缩小 // 放大 k 倍则 scale 也 扩大 k 倍 return Math.hypot(Math.abs(second.x - first.x), Math.abs(second.y - first.y)); }; var slideChangeEnd = function slideChangeEnd(page) { setActive(page + 1); }; var closeOnImg = function closeOnImg() { // 点击内容区域的图片是否可以关闭弹层(视频区域由于nut-video做了限制,无法关闭弹层) if (contentClose) { onCloseInner(); } }; return React__default.createElement(Popup, { visible: showPop, popClass: "custom-pop", style: { width: '100%' }, onClick: onCloseInner }, React__default.createElement("div", { className: "nut-imagepreview", ref: nutImagePreview, onClick: closeOnImg, onTouchStart: onTouchStart }, React__default.createElement(Swiper, { autoPlay: autoplay, className: "nut-imagepreview-swiper", loop: true, isPreventDefault: false, style: { display: showPop ? 'block' : 'none' }, direction: "horizontal", onChange: slideChangeEnd, initPage: initNo && (initNo > maxNo ? maxNo - 1 : initNo - 1), paginationColor: paginationColor, paginationVisible: paginationVisible }, images && images.length > 0 ? images.map(function (item, index) { return React__default.createElement(SwiperItem, { key: index }, React__default.createElement("img", { src: item.src, alt: "", className: "nut-imagepreview-img" })); }) : [])), React__default.createElement("div", { className: "nut-imagepreview-index" }, active, "/", (images ? images.length : 0) + (videos ? videos.length : 0))); }; ImagePreview.defaultProps = defaultProps; ImagePreview.displayName = 'NutImagePreview'; export { ImagePreview as I };