index.js 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  4. var React = _interopDefault(require('react'));
  5. var classNames = _interopDefault(require('classnames'));
  6. var reactDom = require('react-dom');
  7. /*! *****************************************************************************
  8. Copyright (c) Microsoft Corporation.
  9. Permission to use, copy, modify, and/or distribute this software for any
  10. purpose with or without fee is hereby granted.
  11. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  12. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  13. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  14. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  16. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  17. PERFORMANCE OF THIS SOFTWARE.
  18. ***************************************************************************** */
  19. /* global Reflect, Promise */
  20. var extendStatics = function(d, b) {
  21. extendStatics = Object.setPrototypeOf ||
  22. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  23. function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  24. return extendStatics(d, b);
  25. };
  26. function __extends(d, b) {
  27. extendStatics(d, b);
  28. function __() { this.constructor = d; }
  29. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  30. }
  31. var __assign = function() {
  32. __assign = Object.assign || function __assign(t) {
  33. for (var s, i = 1, n = arguments.length; i < n; i++) {
  34. s = arguments[i];
  35. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  36. }
  37. return t;
  38. };
  39. return __assign.apply(this, arguments);
  40. };
  41. function __rest(s, e) {
  42. var t = {};
  43. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  44. t[p] = s[p];
  45. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  46. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  47. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  48. t[p[i]] = s[p[i]];
  49. }
  50. return t;
  51. }
  52. var PhotoContext = React.createContext({
  53. onShow: function () { },
  54. addItem: function () { },
  55. removeItem: function () { },
  56. });
  57. function Spinner() {
  58. return (React.createElement("div", { className: "PhotoView__Spinner" },
  59. React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 32 32", width: "36", height: "36", fill: "white" },
  60. React.createElement("path", { opacity: ".25", d: "M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4" }),
  61. React.createElement("path", { d: "M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z" }))));
  62. }
  63. /**
  64. * 获取图片合适的大小
  65. */
  66. function getSuitableImageSize(naturalWidth, naturalHeight, rotate) {
  67. var _a;
  68. var width;
  69. var height;
  70. var y = 0;
  71. var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
  72. var isVertical = rotate % 180 !== 0;
  73. // 若图片不是水平则调换宽高
  74. if (isVertical) {
  75. _a = [innerWidth, innerHeight], innerHeight = _a[0], innerWidth = _a[1];
  76. }
  77. var autoWidth = (naturalWidth / naturalHeight) * innerHeight;
  78. var autoHeight = (naturalHeight / naturalWidth) * innerWidth;
  79. if (naturalWidth < innerWidth && naturalHeight < innerHeight) {
  80. width = naturalWidth;
  81. height = naturalHeight;
  82. }
  83. else if (naturalWidth < innerWidth && naturalHeight >= innerHeight) {
  84. width = autoWidth;
  85. height = innerHeight;
  86. }
  87. else if (naturalWidth >= innerWidth && naturalHeight < innerHeight) {
  88. width = innerWidth;
  89. height = autoHeight;
  90. }
  91. else if (naturalWidth / naturalHeight > innerWidth / innerHeight) {
  92. width = innerWidth;
  93. height = autoHeight;
  94. }
  95. // 长图模式
  96. else if (naturalHeight / naturalWidth >= 3 && !isVertical) {
  97. width = innerWidth;
  98. height = autoHeight;
  99. // 默认定位到顶部区域
  100. y = (height - innerHeight) / 2;
  101. }
  102. else {
  103. width = autoWidth;
  104. height = innerHeight;
  105. }
  106. return {
  107. width: Math.floor(width),
  108. height: Math.floor(height),
  109. x: 0,
  110. y: y,
  111. scale: 1,
  112. };
  113. }
  114. function useMountedState() {
  115. var mountedRef = React.useRef(false);
  116. React.useEffect(function () {
  117. mountedRef.current = true;
  118. return function () {
  119. mountedRef.current = false;
  120. };
  121. });
  122. return React.useCallback(function () { return mountedRef.current; }, []);
  123. }
  124. var Photo = function (props) {
  125. var src = props.src, intro = props.intro, loaded = props.loaded, broken = props.broken, width = props.width, height = props.height, rotate = props.rotate, className = props.className, onImageLoad = props.onImageLoad, loadingElement = props.loadingElement, brokenElement = props.brokenElement, restProps = __rest(props, ["src", "intro", "loaded", "broken", "width", "height", "rotate", "className", "onImageLoad", "loadingElement", "brokenElement"]);
  126. var isMounted = useMountedState();
  127. function handleImageLoaded(e) {
  128. var _a = e.target, naturalWidth = _a.naturalWidth, naturalHeight = _a.naturalHeight;
  129. if (isMounted()) {
  130. onImageLoad(__assign({ loaded: true, naturalWidth: naturalWidth,
  131. naturalHeight: naturalHeight }, getSuitableImageSize(naturalWidth, naturalHeight, rotate)));
  132. }
  133. }
  134. function handleImageBroken() {
  135. if (isMounted()) {
  136. onImageLoad({
  137. broken: true,
  138. });
  139. }
  140. }
  141. React.useEffect(function () {
  142. var currPhoto = new Image();
  143. currPhoto.onload = handleImageLoaded;
  144. currPhoto.onerror = handleImageBroken;
  145. currPhoto.src = src;
  146. }, []);
  147. if (src && !broken) {
  148. if (loaded) {
  149. return (React.createElement("img", __assign({ className: classNames('PhotoView__Photo', className), src: src, width: width, height: height, alt: "" }, restProps)));
  150. }
  151. return loadingElement || React.createElement(Spinner, null);
  152. }
  153. if (brokenElement) {
  154. if (typeof brokenElement === 'function') {
  155. return brokenElement({
  156. src: src,
  157. intro: intro,
  158. });
  159. }
  160. return brokenElement;
  161. }
  162. return null;
  163. };
  164. Photo.displayName = 'Photo';
  165. var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  166. /**
  167. * lodash (Custom Build) <https://lodash.com/>
  168. * Build: `lodash modularize exports="npm" -o ./`
  169. * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  170. * Released under MIT license <https://lodash.com/license>
  171. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  172. * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  173. */
  174. /** Used as the `TypeError` message for "Functions" methods. */
  175. var FUNC_ERROR_TEXT = 'Expected a function';
  176. /** Used as references for various `Number` constants. */
  177. var NAN = 0 / 0;
  178. /** `Object#toString` result references. */
  179. var symbolTag = '[object Symbol]';
  180. /** Used to match leading and trailing whitespace. */
  181. var reTrim = /^\s+|\s+$/g;
  182. /** Used to detect bad signed hexadecimal string values. */
  183. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  184. /** Used to detect binary string values. */
  185. var reIsBinary = /^0b[01]+$/i;
  186. /** Used to detect octal string values. */
  187. var reIsOctal = /^0o[0-7]+$/i;
  188. /** Built-in method references without a dependency on `root`. */
  189. var freeParseInt = parseInt;
  190. /** Detect free variable `global` from Node.js. */
  191. var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
  192. /** Detect free variable `self`. */
  193. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  194. /** Used as a reference to the global object. */
  195. var root = freeGlobal || freeSelf || Function('return this')();
  196. /** Used for built-in method references. */
  197. var objectProto = Object.prototype;
  198. /**
  199. * Used to resolve the
  200. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  201. * of values.
  202. */
  203. var objectToString = objectProto.toString;
  204. /* Built-in method references for those with the same name as other `lodash` methods. */
  205. var nativeMax = Math.max,
  206. nativeMin = Math.min;
  207. /**
  208. * Gets the timestamp of the number of milliseconds that have elapsed since
  209. * the Unix epoch (1 January 1970 00:00:00 UTC).
  210. *
  211. * @static
  212. * @memberOf _
  213. * @since 2.4.0
  214. * @category Date
  215. * @returns {number} Returns the timestamp.
  216. * @example
  217. *
  218. * _.defer(function(stamp) {
  219. * console.log(_.now() - stamp);
  220. * }, _.now());
  221. * // => Logs the number of milliseconds it took for the deferred invocation.
  222. */
  223. var now = function() {
  224. return root.Date.now();
  225. };
  226. /**
  227. * Creates a debounced function that delays invoking `func` until after `wait`
  228. * milliseconds have elapsed since the last time the debounced function was
  229. * invoked. The debounced function comes with a `cancel` method to cancel
  230. * delayed `func` invocations and a `flush` method to immediately invoke them.
  231. * Provide `options` to indicate whether `func` should be invoked on the
  232. * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
  233. * with the last arguments provided to the debounced function. Subsequent
  234. * calls to the debounced function return the result of the last `func`
  235. * invocation.
  236. *
  237. * **Note:** If `leading` and `trailing` options are `true`, `func` is
  238. * invoked on the trailing edge of the timeout only if the debounced function
  239. * is invoked more than once during the `wait` timeout.
  240. *
  241. * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
  242. * until to the next tick, similar to `setTimeout` with a timeout of `0`.
  243. *
  244. * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
  245. * for details over the differences between `_.debounce` and `_.throttle`.
  246. *
  247. * @static
  248. * @memberOf _
  249. * @since 0.1.0
  250. * @category Function
  251. * @param {Function} func The function to debounce.
  252. * @param {number} [wait=0] The number of milliseconds to delay.
  253. * @param {Object} [options={}] The options object.
  254. * @param {boolean} [options.leading=false]
  255. * Specify invoking on the leading edge of the timeout.
  256. * @param {number} [options.maxWait]
  257. * The maximum time `func` is allowed to be delayed before it's invoked.
  258. * @param {boolean} [options.trailing=true]
  259. * Specify invoking on the trailing edge of the timeout.
  260. * @returns {Function} Returns the new debounced function.
  261. * @example
  262. *
  263. * // Avoid costly calculations while the window size is in flux.
  264. * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
  265. *
  266. * // Invoke `sendMail` when clicked, debouncing subsequent calls.
  267. * jQuery(element).on('click', _.debounce(sendMail, 300, {
  268. * 'leading': true,
  269. * 'trailing': false
  270. * }));
  271. *
  272. * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
  273. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
  274. * var source = new EventSource('/stream');
  275. * jQuery(source).on('message', debounced);
  276. *
  277. * // Cancel the trailing debounced invocation.
  278. * jQuery(window).on('popstate', debounced.cancel);
  279. */
  280. function debounce(func, wait, options) {
  281. var lastArgs,
  282. lastThis,
  283. maxWait,
  284. result,
  285. timerId,
  286. lastCallTime,
  287. lastInvokeTime = 0,
  288. leading = false,
  289. maxing = false,
  290. trailing = true;
  291. if (typeof func != 'function') {
  292. throw new TypeError(FUNC_ERROR_TEXT);
  293. }
  294. wait = toNumber(wait) || 0;
  295. if (isObject(options)) {
  296. leading = !!options.leading;
  297. maxing = 'maxWait' in options;
  298. maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
  299. trailing = 'trailing' in options ? !!options.trailing : trailing;
  300. }
  301. function invokeFunc(time) {
  302. var args = lastArgs,
  303. thisArg = lastThis;
  304. lastArgs = lastThis = undefined;
  305. lastInvokeTime = time;
  306. result = func.apply(thisArg, args);
  307. return result;
  308. }
  309. function leadingEdge(time) {
  310. // Reset any `maxWait` timer.
  311. lastInvokeTime = time;
  312. // Start the timer for the trailing edge.
  313. timerId = setTimeout(timerExpired, wait);
  314. // Invoke the leading edge.
  315. return leading ? invokeFunc(time) : result;
  316. }
  317. function remainingWait(time) {
  318. var timeSinceLastCall = time - lastCallTime,
  319. timeSinceLastInvoke = time - lastInvokeTime,
  320. result = wait - timeSinceLastCall;
  321. return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
  322. }
  323. function shouldInvoke(time) {
  324. var timeSinceLastCall = time - lastCallTime,
  325. timeSinceLastInvoke = time - lastInvokeTime;
  326. // Either this is the first call, activity has stopped and we're at the
  327. // trailing edge, the system time has gone backwards and we're treating
  328. // it as the trailing edge, or we've hit the `maxWait` limit.
  329. return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
  330. (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
  331. }
  332. function timerExpired() {
  333. var time = now();
  334. if (shouldInvoke(time)) {
  335. return trailingEdge(time);
  336. }
  337. // Restart the timer.
  338. timerId = setTimeout(timerExpired, remainingWait(time));
  339. }
  340. function trailingEdge(time) {
  341. timerId = undefined;
  342. // Only invoke if we have `lastArgs` which means `func` has been
  343. // debounced at least once.
  344. if (trailing && lastArgs) {
  345. return invokeFunc(time);
  346. }
  347. lastArgs = lastThis = undefined;
  348. return result;
  349. }
  350. function cancel() {
  351. if (timerId !== undefined) {
  352. clearTimeout(timerId);
  353. }
  354. lastInvokeTime = 0;
  355. lastArgs = lastCallTime = lastThis = timerId = undefined;
  356. }
  357. function flush() {
  358. return timerId === undefined ? result : trailingEdge(now());
  359. }
  360. function debounced() {
  361. var time = now(),
  362. isInvoking = shouldInvoke(time);
  363. lastArgs = arguments;
  364. lastThis = this;
  365. lastCallTime = time;
  366. if (isInvoking) {
  367. if (timerId === undefined) {
  368. return leadingEdge(lastCallTime);
  369. }
  370. if (maxing) {
  371. // Handle invocations in a tight loop.
  372. timerId = setTimeout(timerExpired, wait);
  373. return invokeFunc(lastCallTime);
  374. }
  375. }
  376. if (timerId === undefined) {
  377. timerId = setTimeout(timerExpired, wait);
  378. }
  379. return result;
  380. }
  381. debounced.cancel = cancel;
  382. debounced.flush = flush;
  383. return debounced;
  384. }
  385. /**
  386. * Checks if `value` is the
  387. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  388. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  389. *
  390. * @static
  391. * @memberOf _
  392. * @since 0.1.0
  393. * @category Lang
  394. * @param {*} value The value to check.
  395. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  396. * @example
  397. *
  398. * _.isObject({});
  399. * // => true
  400. *
  401. * _.isObject([1, 2, 3]);
  402. * // => true
  403. *
  404. * _.isObject(_.noop);
  405. * // => true
  406. *
  407. * _.isObject(null);
  408. * // => false
  409. */
  410. function isObject(value) {
  411. var type = typeof value;
  412. return !!value && (type == 'object' || type == 'function');
  413. }
  414. /**
  415. * Checks if `value` is object-like. A value is object-like if it's not `null`
  416. * and has a `typeof` result of "object".
  417. *
  418. * @static
  419. * @memberOf _
  420. * @since 4.0.0
  421. * @category Lang
  422. * @param {*} value The value to check.
  423. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  424. * @example
  425. *
  426. * _.isObjectLike({});
  427. * // => true
  428. *
  429. * _.isObjectLike([1, 2, 3]);
  430. * // => true
  431. *
  432. * _.isObjectLike(_.noop);
  433. * // => false
  434. *
  435. * _.isObjectLike(null);
  436. * // => false
  437. */
  438. function isObjectLike(value) {
  439. return !!value && typeof value == 'object';
  440. }
  441. /**
  442. * Checks if `value` is classified as a `Symbol` primitive or object.
  443. *
  444. * @static
  445. * @memberOf _
  446. * @since 4.0.0
  447. * @category Lang
  448. * @param {*} value The value to check.
  449. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  450. * @example
  451. *
  452. * _.isSymbol(Symbol.iterator);
  453. * // => true
  454. *
  455. * _.isSymbol('abc');
  456. * // => false
  457. */
  458. function isSymbol(value) {
  459. return typeof value == 'symbol' ||
  460. (isObjectLike(value) && objectToString.call(value) == symbolTag);
  461. }
  462. /**
  463. * Converts `value` to a number.
  464. *
  465. * @static
  466. * @memberOf _
  467. * @since 4.0.0
  468. * @category Lang
  469. * @param {*} value The value to process.
  470. * @returns {number} Returns the number.
  471. * @example
  472. *
  473. * _.toNumber(3.2);
  474. * // => 3.2
  475. *
  476. * _.toNumber(Number.MIN_VALUE);
  477. * // => 5e-324
  478. *
  479. * _.toNumber(Infinity);
  480. * // => Infinity
  481. *
  482. * _.toNumber('3.2');
  483. * // => 3.2
  484. */
  485. function toNumber(value) {
  486. if (typeof value == 'number') {
  487. return value;
  488. }
  489. if (isSymbol(value)) {
  490. return NAN;
  491. }
  492. if (isObject(value)) {
  493. var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
  494. value = isObject(other) ? (other + '') : other;
  495. }
  496. if (typeof value != 'string') {
  497. return value === 0 ? value : +value;
  498. }
  499. value = value.replace(reTrim, '');
  500. var isBinary = reIsBinary.test(value);
  501. return (isBinary || reIsOctal.test(value))
  502. ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
  503. : (reIsBadHex.test(value) ? NAN : +value);
  504. }
  505. var lodash_debounce = debounce;
  506. /**
  507. * throttle
  508. * @param func
  509. * @param wait
  510. */
  511. function throttle(func, wait) {
  512. return lodash_debounce(func, wait, {
  513. leading: true,
  514. maxWait: wait,
  515. trailing: true,
  516. });
  517. }
  518. /**
  519. * 是否支持触摸设备
  520. */
  521. var isTouchDevice = typeof document !== 'undefined' && 'ontouchstart' in document.documentElement;
  522. /**
  523. * 从 Touch 事件中获取两个触控中心位置
  524. */
  525. function getMultipleTouchPosition(evt) {
  526. var _a = evt.touches[0], clientX = _a.clientX, clientY = _a.clientY;
  527. if (evt.touches.length >= 2) {
  528. var _b = evt.touches[1], nextClientX = _b.clientX, nextClientY = _b.clientY;
  529. return {
  530. clientX: (clientX + nextClientX) / 2,
  531. clientY: (clientY + nextClientY) / 2,
  532. touchLength: Math.sqrt(Math.pow(nextClientX - clientX, 2) + Math.pow(nextClientY - clientY, 2)),
  533. };
  534. }
  535. return { clientX: clientX, clientY: clientY, touchLength: 0 };
  536. }
  537. /**
  538. * 获取移动或缩放之后的中心点
  539. */
  540. function getPositionOnMoveOrScale(_a) {
  541. var x = _a.x, y = _a.y, clientX = _a.clientX, clientY = _a.clientY, _b = _a.offsetX, offsetX = _b === void 0 ? 0 : _b, _c = _a.offsetY, offsetY = _c === void 0 ? 0 : _c, fromScale = _a.fromScale, toScale = _a.toScale;
  542. var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
  543. var centerClientX = innerWidth / 2;
  544. var centerClientY = innerHeight / 2;
  545. // 坐标偏移
  546. var lastPositionX = centerClientX + x;
  547. var lastPositionY = centerClientY + y;
  548. // 放大偏移量
  549. var offsetScale = toScale / fromScale;
  550. // 偏移位置
  551. var originX = clientX - (clientX - lastPositionX) * offsetScale - centerClientX;
  552. var originY = clientY - (clientY - lastPositionY) * offsetScale - centerClientY;
  553. return {
  554. x: originX + offsetX,
  555. y: originY + offsetY,
  556. scale: toScale,
  557. lastMoveClientX: clientX,
  558. lastMoveClientY: clientY,
  559. };
  560. }
  561. /**
  562. * 最大触摸时间
  563. */
  564. var maxTouchTime = 200;
  565. /**
  566. * 最大滑动切换图片距离
  567. */
  568. var maxMoveOffset = 40;
  569. /**
  570. * 图片的间隔
  571. */
  572. var horizontalOffset = 20;
  573. /**
  574. * 最小初始响应距离
  575. */
  576. var minStartTouchOffset = 10;
  577. /**
  578. * 默认背景透明度
  579. */
  580. var defaultOpacity = 1;
  581. /**
  582. * 最小缩放度
  583. */
  584. var minScale = 1;
  585. /**
  586. * 最大缩放度(若图片足够大,则会超出)
  587. */
  588. var maxScale = 6;
  589. /**
  590. * 滑动加速度
  591. */
  592. var slideAcceleration = 0.005;
  593. /**
  594. * 缩放弹性缓冲
  595. */
  596. var scaleBuffer = 0.2;
  597. /**
  598. * 边缘超出状态
  599. */
  600. var CloseEdgeEnum;
  601. (function (CloseEdgeEnum) {
  602. CloseEdgeEnum[CloseEdgeEnum["Normal"] = 0] = "Normal";
  603. CloseEdgeEnum[CloseEdgeEnum["Small"] = 1] = "Small";
  604. CloseEdgeEnum[CloseEdgeEnum["Before"] = 2] = "Before";
  605. CloseEdgeEnum[CloseEdgeEnum["After"] = 3] = "After";
  606. })(CloseEdgeEnum || (CloseEdgeEnum = {}));
  607. /**
  608. * 边缘触发状态
  609. */
  610. var ReachTypeEnum;
  611. (function (ReachTypeEnum) {
  612. ReachTypeEnum[ReachTypeEnum["Normal"] = 0] = "Normal";
  613. ReachTypeEnum[ReachTypeEnum["XReach"] = 1] = "XReach";
  614. ReachTypeEnum[ReachTypeEnum["YReach"] = 2] = "YReach";
  615. })(ReachTypeEnum || (ReachTypeEnum = {}));
  616. /**
  617. * 初始响应状态
  618. */
  619. var TouchStartEnum;
  620. (function (TouchStartEnum) {
  621. TouchStartEnum[TouchStartEnum["Normal"] = 0] = "Normal";
  622. TouchStartEnum[TouchStartEnum["X"] = 1] = "X";
  623. TouchStartEnum[TouchStartEnum["YPush"] = 2] = "YPush";
  624. TouchStartEnum[TouchStartEnum["YPull"] = 3] = "YPull";
  625. })(TouchStartEnum || (TouchStartEnum = {}));
  626. /**
  627. * 动画类型
  628. */
  629. var ShowAnimateEnum;
  630. (function (ShowAnimateEnum) {
  631. ShowAnimateEnum[ShowAnimateEnum["None"] = 0] = "None";
  632. ShowAnimateEnum[ShowAnimateEnum["In"] = 1] = "In";
  633. ShowAnimateEnum[ShowAnimateEnum["Out"] = 2] = "Out";
  634. })(ShowAnimateEnum || (ShowAnimateEnum = {}));
  635. /**
  636. * 接触左边/上边 或 右边/下边边缘
  637. * @param position - x/y
  638. * @param scale
  639. * @param size - width/height
  640. * @param innerSize - innerWidth/innerHeight
  641. * @return CloseEdgeEnum
  642. */
  643. function getClosedEdge(position, scale, size, innerSize) {
  644. var currentWidth = size * scale;
  645. // 图片超出的宽度
  646. var outOffsetX = (currentWidth - innerSize) / 2;
  647. if (currentWidth <= innerSize) {
  648. return CloseEdgeEnum.Small;
  649. }
  650. else if (position > 0 && outOffsetX - position <= 0) {
  651. return CloseEdgeEnum.Before;
  652. }
  653. else if (position < 0 && outOffsetX + position <= 0) {
  654. return CloseEdgeEnum.After;
  655. }
  656. return CloseEdgeEnum.Normal;
  657. }
  658. /**
  659. * 获取接触边缘类型
  660. * @param initialTouchState
  661. * @param horizontalCloseEdge
  662. * @param verticalCloseEdge
  663. * @param reachState
  664. */
  665. function getReachType(_a) {
  666. var initialTouchState = _a.initialTouchState, horizontalCloseEdge = _a.horizontalCloseEdge, verticalCloseEdge = _a.verticalCloseEdge, reachState = _a.reachState;
  667. if ((horizontalCloseEdge > 0 && initialTouchState === TouchStartEnum.X) || reachState === ReachTypeEnum.XReach) {
  668. return ReachTypeEnum.XReach;
  669. }
  670. else if ((verticalCloseEdge > 0 &&
  671. (initialTouchState === TouchStartEnum.YPull || initialTouchState === TouchStartEnum.YPush)) ||
  672. reachState === ReachTypeEnum.YReach) {
  673. return ReachTypeEnum.YReach;
  674. }
  675. return ReachTypeEnum.Normal;
  676. }
  677. /**
  678. * 适应到合适的图片偏移量
  679. */
  680. function slideToPosition(_a) {
  681. var _b;
  682. var x = _a.x, y = _a.y, lastX = _a.lastX, lastY = _a.lastY, width = _a.width, height = _a.height, scale = _a.scale, rotate = _a.rotate, touchedTime = _a.touchedTime;
  683. var moveTime = Date.now() - touchedTime;
  684. // 初始速度
  685. var speedX = (x - lastX) / moveTime;
  686. var speedY = (y - lastY) / moveTime;
  687. // 停下所消耗时间
  688. var slideTimeX = Math.abs(speedX / slideAcceleration);
  689. var slideTimeY = Math.abs(speedY / slideAcceleration);
  690. // 计划滑动位置
  691. var planX = Math.floor(x + speedX * slideTimeX);
  692. var planY = Math.floor(y + speedY * slideTimeY);
  693. // 若图片不是水平则调换属性
  694. if (rotate % 180 !== 0) {
  695. _b = [height, width], width = _b[0], height = _b[1];
  696. }
  697. var currentX = planX;
  698. var currentY = planY;
  699. var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
  700. // 图片超出的长度
  701. var outOffsetX = (width * scale - innerWidth) / 2;
  702. var outOffsetY = (height * scale - innerHeight) / 2;
  703. var horizontalCloseEdge = getClosedEdge(planX, scale, width, innerWidth);
  704. var verticalCloseEdge = getClosedEdge(planY, scale, height, innerHeight);
  705. // x
  706. if (horizontalCloseEdge === CloseEdgeEnum.Small) {
  707. currentX = 0;
  708. }
  709. else if (horizontalCloseEdge === CloseEdgeEnum.Before) {
  710. currentX = outOffsetX;
  711. }
  712. else if (horizontalCloseEdge === CloseEdgeEnum.After) {
  713. currentX = -outOffsetX;
  714. }
  715. // y
  716. if (verticalCloseEdge === CloseEdgeEnum.Small) {
  717. currentY = 0;
  718. }
  719. else if (verticalCloseEdge === CloseEdgeEnum.Before) {
  720. currentY = outOffsetY;
  721. }
  722. else if (verticalCloseEdge === CloseEdgeEnum.After) {
  723. currentY = -outOffsetY;
  724. }
  725. // 时间过长
  726. if (moveTime >= maxTouchTime &&
  727. horizontalCloseEdge === CloseEdgeEnum.Normal &&
  728. verticalCloseEdge === CloseEdgeEnum.Normal) {
  729. return {
  730. x: x,
  731. y: y,
  732. };
  733. }
  734. return {
  735. x: currentX,
  736. y: currentY,
  737. };
  738. }
  739. /**
  740. * 单击和双击事件处理
  741. * @param singleTap - 单击事件
  742. * @param doubleTap - 双击事件
  743. * @return invokeTap
  744. */
  745. function withContinuousTap(singleTap, doubleTap) {
  746. // 当前连续点击次数
  747. var continuousClick = 0;
  748. var withDebounceTap = lodash_debounce(function () {
  749. var args = [];
  750. for (var _i = 0; _i < arguments.length; _i++) {
  751. args[_i] = arguments[_i];
  752. }
  753. continuousClick = 0;
  754. singleTap.apply(void 0, args);
  755. }, 300);
  756. return function invokeTap() {
  757. var args = [];
  758. for (var _i = 0; _i < arguments.length; _i++) {
  759. args[_i] = arguments[_i];
  760. }
  761. continuousClick += 1;
  762. withDebounceTap.apply(void 0, args);
  763. // 双击
  764. if (continuousClick >= 2) {
  765. withDebounceTap.cancel();
  766. continuousClick = 0;
  767. doubleTap.apply(void 0, args);
  768. }
  769. };
  770. }
  771. function getAnimateOrigin(originRect, width, height) {
  772. if (originRect) {
  773. var innerWidth_1 = window.innerWidth, innerHeight_1 = window.innerHeight;
  774. var xOrigin = (width - innerWidth_1) / 2 + originRect.clientX;
  775. var yOrigin = (height - innerHeight_1) / 2 + originRect.clientY;
  776. return xOrigin + "px " + yOrigin + "px";
  777. }
  778. return undefined;
  779. }
  780. /**
  781. * 纠正缩放后偏离中心区域位置
  782. */
  783. function correctSuitablePosition(_a) {
  784. var x = _a.x, y = _a.y, scale = _a.scale;
  785. if (scale <= 1) {
  786. return {
  787. x: 0,
  788. y: 0,
  789. };
  790. }
  791. return {
  792. x: x,
  793. y: y,
  794. };
  795. }
  796. var initialState = {
  797. // 真实宽度
  798. naturalWidth: 1,
  799. // 真实高度
  800. naturalHeight: 1,
  801. // 宽度
  802. width: 1,
  803. // 高度
  804. height: 1,
  805. // 加载成功状态
  806. loaded: false,
  807. // 破碎状态
  808. broken: false,
  809. // 图片 X 偏移量
  810. x: 0,
  811. // 图片 y 偏移量
  812. y: 0,
  813. // 图片缩放程度
  814. scale: 1,
  815. // 图片处于触摸的状态
  816. touched: false,
  817. // 背景处于触摸状态
  818. maskTouched: false,
  819. // 触摸开始时 x 原始坐标
  820. clientX: 0,
  821. // 触摸开始时 y 原始坐标
  822. clientY: 0,
  823. // 触摸开始时图片 x 偏移量
  824. lastX: 0,
  825. // 触摸开始时图片 y 偏移量
  826. lastY: 0,
  827. // 上一个触摸状态 x 原始坐标
  828. lastMoveClientX: 0,
  829. // 上一个触摸状态 y 原始坐标
  830. lastMoveClientY: 0,
  831. // 触摸开始时时间
  832. touchedTime: 0,
  833. // 多指触控间距
  834. lastTouchLength: 0,
  835. // 当前边缘触发状态
  836. reachState: ReachTypeEnum.Normal,
  837. };
  838. var PhotoView = /** @class */ (function (_super) {
  839. __extends(PhotoView, _super);
  840. function PhotoView(props) {
  841. var _this = _super.call(this, props) || this;
  842. _this.state = initialState;
  843. // 初始响应状态
  844. _this.initialTouchState = TouchStartEnum.Normal;
  845. _this.handleImageLoad = function (imageParams) {
  846. _this.setState(imageParams);
  847. };
  848. _this.handleResize = function () {
  849. var _a = _this.props, onPhotoResize = _a.onPhotoResize, rotate = _a.rotate;
  850. var _b = _this.state, loaded = _b.loaded, naturalWidth = _b.naturalWidth, naturalHeight = _b.naturalHeight;
  851. if (loaded) {
  852. _this.setState(getSuitableImageSize(naturalWidth, naturalHeight, rotate));
  853. if (onPhotoResize) {
  854. onPhotoResize();
  855. }
  856. }
  857. };
  858. _this.handleStart = function (clientX, clientY, touchLength) {
  859. if (touchLength === void 0) { touchLength = 0; }
  860. _this.setState(function (prevState) { return ({
  861. touched: true,
  862. clientX: clientX,
  863. clientY: clientY,
  864. lastMoveClientX: clientX,
  865. lastMoveClientY: clientY,
  866. lastX: prevState.x,
  867. lastY: prevState.y,
  868. lastTouchLength: touchLength,
  869. touchedTime: Date.now(),
  870. }); });
  871. };
  872. _this.onMove = function (newClientX, newClientY, touchLength) {
  873. var _a;
  874. if (touchLength === void 0) { touchLength = 0; }
  875. var _b = _this.props, onReachMove = _b.onReachMove, isActive = _b.isActive, rotate = _b.rotate;
  876. var _c = _this.state, naturalWidth = _c.naturalWidth, x = _c.x, y = _c.y, clientX = _c.clientX, clientY = _c.clientY, lastMoveClientX = _c.lastMoveClientX, lastMoveClientY = _c.lastMoveClientY, lastX = _c.lastX, lastY = _c.lastY, scale = _c.scale, lastTouchLength = _c.lastTouchLength, reachState = _c.reachState, touched = _c.touched, maskTouched = _c.maskTouched;
  877. if ((touched || maskTouched) && isActive) {
  878. var _d = _this.state, width = _d.width, height = _d.height;
  879. // 若图片不是水平则调换属性
  880. if (rotate % 180 !== 0) {
  881. _a = [height, width], width = _a[0], height = _a[1];
  882. }
  883. // 单指最小缩放下,以初始移动距离来判断意图
  884. if (touchLength === 0 && _this.initialTouchState === TouchStartEnum.Normal) {
  885. var isStillX = Math.abs(newClientX - clientX) <= minStartTouchOffset;
  886. var isStillY = Math.abs(newClientY - clientY) <= minStartTouchOffset;
  887. // 初始移动距离不足
  888. if (isStillX && isStillY) {
  889. // 方向记录上次移动距离,以便平滑过渡
  890. _this.setState({
  891. lastMoveClientX: newClientX,
  892. lastMoveClientY: newClientY,
  893. });
  894. return;
  895. }
  896. // 设置响应状态
  897. _this.initialTouchState = !isStillX
  898. ? TouchStartEnum.X
  899. : newClientY > clientY
  900. ? TouchStartEnum.YPull
  901. : TouchStartEnum.YPush;
  902. }
  903. var offsetX = newClientX - lastMoveClientX;
  904. var offsetY = newClientY - lastMoveClientY;
  905. // 边缘触发状态
  906. var currentReachState = ReachTypeEnum.Normal;
  907. if (touchLength === 0) {
  908. // 边缘超出状态
  909. var horizontalCloseEdge = getClosedEdge(offsetX + lastX, scale, width, window.innerWidth);
  910. var verticalCloseEdge = getClosedEdge(offsetY + lastY, scale, height, window.innerHeight);
  911. // 边缘触发检测
  912. currentReachState = getReachType({
  913. initialTouchState: _this.initialTouchState,
  914. horizontalCloseEdge: horizontalCloseEdge,
  915. verticalCloseEdge: verticalCloseEdge,
  916. reachState: reachState,
  917. });
  918. // 接触边缘
  919. if (currentReachState != ReachTypeEnum.Normal) {
  920. onReachMove(currentReachState, newClientX, newClientY, scale);
  921. }
  922. }
  923. // 横向边缘触发、背景触发禁用当前滑动
  924. if (currentReachState === ReachTypeEnum.XReach || maskTouched) {
  925. _this.setState({
  926. reachState: ReachTypeEnum.XReach,
  927. });
  928. }
  929. else {
  930. // 目标倍数
  931. var endScale = scale + ((touchLength - lastTouchLength) / 100 / 2) * scale;
  932. // 限制最大倍数和最小倍数
  933. var toScale = Math.max(Math.min(endScale, Math.max(maxScale, naturalWidth / width)), minScale - scaleBuffer);
  934. _this.setState(__assign({ lastTouchLength: touchLength, reachState: currentReachState }, getPositionOnMoveOrScale({
  935. x: x,
  936. y: y,
  937. clientX: newClientX,
  938. clientY: newClientY,
  939. offsetX: offsetX,
  940. offsetY: offsetY,
  941. fromScale: scale,
  942. toScale: toScale,
  943. })));
  944. }
  945. }
  946. };
  947. _this.onPhotoTap = function (clientX, clientY) {
  948. var onPhotoTap = _this.props.onPhotoTap;
  949. if (onPhotoTap) {
  950. onPhotoTap(clientX, clientY);
  951. }
  952. };
  953. _this.onDoubleTap = function (clientX, clientY) {
  954. var _a = _this.state, width = _a.width, naturalWidth = _a.naturalWidth, x = _a.x, y = _a.y, scale = _a.scale, reachState = _a.reachState;
  955. if (reachState !== ReachTypeEnum.Normal) {
  956. return;
  957. }
  958. var position = getPositionOnMoveOrScale({
  959. x: x,
  960. y: y,
  961. clientX: clientX,
  962. clientY: clientY,
  963. fromScale: scale,
  964. // 若图片足够大,则放大适应的倍数
  965. toScale: scale !== 1 ? 1 : Math.max(2, naturalWidth / width),
  966. });
  967. _this.setState(__assign(__assign({ clientX: clientX,
  968. clientY: clientY }, position), correctSuitablePosition(position)));
  969. };
  970. _this.handleWheel = function (e) {
  971. e.stopPropagation();
  972. var clientX = e.clientX, clientY = e.clientY, deltaY = e.deltaY;
  973. var _a = _this.state, width = _a.width, naturalWidth = _a.naturalWidth, reachState = _a.reachState;
  974. if (reachState !== ReachTypeEnum.Normal) {
  975. return;
  976. }
  977. _this.setState(function (_a) {
  978. var x = _a.x, y = _a.y, scale = _a.scale;
  979. var endScale = scale - deltaY / 100 / 2;
  980. // 限制最大倍数和最小倍数
  981. var toScale = Math.max(Math.min(endScale, Math.max(maxScale, naturalWidth / width)), minScale);
  982. var position = getPositionOnMoveOrScale({
  983. x: x,
  984. y: y,
  985. clientX: clientX,
  986. clientY: clientY,
  987. fromScale: scale,
  988. toScale: toScale,
  989. });
  990. return __assign(__assign({ clientX: clientX,
  991. clientY: clientY }, position), correctSuitablePosition(position));
  992. });
  993. };
  994. _this.handleMaskStart = function (clientX, clientY) {
  995. _this.setState(function (prevState) { return ({
  996. maskTouched: true,
  997. clientX: clientX,
  998. clientY: clientY,
  999. lastX: prevState.x,
  1000. lastY: prevState.y,
  1001. }); });
  1002. };
  1003. _this.handleMaskMouseDown = function (e) {
  1004. e.stopPropagation();
  1005. _this.handleMaskStart(e.clientX, e.clientY);
  1006. };
  1007. _this.handleMaskTouchStart = function (e) {
  1008. e.stopPropagation();
  1009. var _a = e.touches[0], clientX = _a.clientX, clientY = _a.clientY;
  1010. _this.handleMaskStart(clientX, clientY);
  1011. };
  1012. _this.handleTouchStart = function (e) {
  1013. e.stopPropagation();
  1014. var _a = getMultipleTouchPosition(e), clientX = _a.clientX, clientY = _a.clientY, touchLength = _a.touchLength;
  1015. _this.handleStart(clientX, clientY, touchLength);
  1016. };
  1017. _this.handleMouseDown = function (e) {
  1018. e.preventDefault();
  1019. e.stopPropagation();
  1020. _this.handleStart(e.clientX, e.clientY, 0);
  1021. };
  1022. _this.handleTouchMove = function (e) {
  1023. e.preventDefault();
  1024. e.stopPropagation();
  1025. var _a = getMultipleTouchPosition(e), clientX = _a.clientX, clientY = _a.clientY, touchLength = _a.touchLength;
  1026. _this.onMove(clientX, clientY, touchLength);
  1027. };
  1028. _this.handleMouseMove = function (e) {
  1029. e.preventDefault();
  1030. e.stopPropagation();
  1031. _this.onMove(e.clientX, e.clientY);
  1032. };
  1033. _this.handleUp = function (newClientX, newClientY) {
  1034. // 重置响应状态
  1035. _this.initialTouchState = TouchStartEnum.Normal;
  1036. var _a = _this.props, onReachUp = _a.onReachUp, onPhotoTap = _a.onPhotoTap, onMaskTap = _a.onMaskTap, isActive = _a.isActive, rotate = _a.rotate;
  1037. var _b = _this.state, width = _b.width, height = _b.height, naturalWidth = _b.naturalWidth, x = _b.x, y = _b.y, lastX = _b.lastX, lastY = _b.lastY, scale = _b.scale, touchedTime = _b.touchedTime, clientX = _b.clientX, clientY = _b.clientY, touched = _b.touched, maskTouched = _b.maskTouched;
  1038. if ((touched || maskTouched) && isActive) {
  1039. var hasMove_1 = clientX !== newClientX || clientY !== newClientY;
  1040. _this.setState(__assign({ touched: false, maskTouched: false,
  1041. // 限制缩放
  1042. scale: Math.max(Math.min(scale, Math.max(maxScale, naturalWidth / width)), minScale), reachState: ReachTypeEnum.Normal }, (hasMove_1
  1043. ? slideToPosition({
  1044. x: x,
  1045. y: y,
  1046. lastX: lastX,
  1047. lastY: lastY,
  1048. width: width,
  1049. height: height,
  1050. scale: scale,
  1051. rotate: rotate,
  1052. touchedTime: touchedTime,
  1053. })
  1054. : {
  1055. x: x,
  1056. y: y,
  1057. })), function () {
  1058. if (onReachUp) {
  1059. onReachUp(newClientX, newClientY);
  1060. }
  1061. // 触发 Tap 事件
  1062. if (!hasMove_1) {
  1063. if (touched && onPhotoTap) {
  1064. _this.handlePhotoTap(newClientX, newClientY);
  1065. }
  1066. else if (maskTouched && onMaskTap) {
  1067. onMaskTap(newClientX, newClientY);
  1068. }
  1069. }
  1070. });
  1071. }
  1072. };
  1073. _this.handleTouchEnd = function (e) {
  1074. var _a = e.changedTouches[0], clientX = _a.clientX, clientY = _a.clientY;
  1075. _this.handleUp(clientX, clientY);
  1076. };
  1077. _this.handleMouseUp = function (e) {
  1078. var clientX = e.clientX, clientY = e.clientY;
  1079. _this.handleUp(clientX, clientY);
  1080. };
  1081. _this.onMove = throttle(_this.onMove, 8);
  1082. _this.handleResize = throttle(_this.handleResize, 8);
  1083. // 单击与双击事件处理
  1084. _this.handlePhotoTap = withContinuousTap(_this.onPhotoTap, _this.onDoubleTap);
  1085. return _this;
  1086. }
  1087. PhotoView.prototype.componentDidMount = function () {
  1088. if (isTouchDevice) {
  1089. window.addEventListener('touchmove', this.handleTouchMove, { passive: false });
  1090. window.addEventListener('touchend', this.handleTouchEnd, { passive: false });
  1091. }
  1092. else {
  1093. window.addEventListener('mousemove', this.handleMouseMove);
  1094. window.addEventListener('mouseup', this.handleMouseUp);
  1095. }
  1096. window.addEventListener('resize', this.handleResize);
  1097. };
  1098. PhotoView.prototype.componentDidUpdate = function (prevProps) {
  1099. var rotate = this.props.rotate;
  1100. if (rotate !== prevProps.rotate) {
  1101. var _a = this.state, naturalWidth = _a.naturalWidth, naturalHeight = _a.naturalHeight;
  1102. this.setState(getSuitableImageSize(naturalWidth, naturalHeight, rotate));
  1103. }
  1104. };
  1105. PhotoView.prototype.componentWillUnmount = function () {
  1106. window.removeEventListener('touchmove', this.handleTouchMove);
  1107. window.removeEventListener('touchend', this.handleTouchEnd);
  1108. window.removeEventListener('mousemove', this.handleMouseMove);
  1109. window.removeEventListener('mouseup', this.handleMouseUp);
  1110. window.removeEventListener('resize', this.handleResize);
  1111. };
  1112. PhotoView.prototype.render = function () {
  1113. var _a = this.props, src = _a.src, intro = _a.intro, viewClassName = _a.viewClassName, className = _a.className, style = _a.style, rotate = _a.rotate, loadingElement = _a.loadingElement, brokenElement = _a.brokenElement, isActive = _a.isActive, showAnimateType = _a.showAnimateType, originRect = _a.originRect;
  1114. var _b = this.state, width = _b.width, height = _b.height, loaded = _b.loaded, x = _b.x, y = _b.y, scale = _b.scale, touched = _b.touched, broken = _b.broken;
  1115. var transform = "translate3d(" + x + "px, " + y + "px, 0) scale(" + scale + ") rotate(" + rotate + "deg)";
  1116. return (React.createElement("div", { className: classNames('PhotoView__PhotoWrap', viewClassName), style: style },
  1117. React.createElement("div", { className: "PhotoView__PhotoMask", onMouseDown: !isTouchDevice && isActive ? this.handleMaskMouseDown : undefined, onTouchStart: isTouchDevice && isActive ? this.handleMaskTouchStart : undefined }),
  1118. React.createElement("div", { className: classNames('PhotoView__PhotoBox', {
  1119. PhotoView__animateIn: loaded && showAnimateType === ShowAnimateEnum.In,
  1120. PhotoView__animateOut: loaded && showAnimateType === ShowAnimateEnum.Out,
  1121. }), style: {
  1122. transformOrigin: loaded ? getAnimateOrigin(originRect, 0, 0) : undefined,
  1123. } },
  1124. React.createElement(Photo, { className: className, src: src, intro: intro, width: width, height: height, loaded: loaded, broken: broken, rotate: rotate, onMouseDown: isTouchDevice ? undefined : this.handleMouseDown, onTouchStart: isTouchDevice ? this.handleTouchStart : undefined, onWheel: this.handleWheel, style: {
  1125. WebkitTransform: transform,
  1126. transform: transform,
  1127. transition: touched ? undefined : 'transform 0.5s cubic-bezier(0.25, 0.8, 0.25, 1)',
  1128. }, onImageLoad: this.handleImageLoad, loadingElement: loadingElement, brokenElement: brokenElement }))));
  1129. };
  1130. PhotoView.displayName = 'PhotoView';
  1131. return PhotoView;
  1132. }(React.Component));
  1133. var SlideWrap = function (_a) {
  1134. var className = _a.className, children = _a.children, restProps = __rest(_a, ["className", "children"]);
  1135. var dialogNode = React.useRef(document.createElement('section'));
  1136. var originalOverflowCallback = React.useRef('');
  1137. React.useEffect(function () {
  1138. document.body.appendChild(dialogNode.current);
  1139. var style = document.body.style;
  1140. originalOverflowCallback.current = style.overflow;
  1141. style.overflow = 'hidden';
  1142. return function () {
  1143. style.overflow = originalOverflowCallback.current;
  1144. // 清除容器
  1145. document.body.removeChild(dialogNode.current);
  1146. };
  1147. }, []);
  1148. return reactDom.createPortal(React.createElement("div", __assign({ className: classNames('PhotoView-SlideWrap', className) }, restProps), children), dialogNode.current);
  1149. };
  1150. SlideWrap.displayName = 'SlideWrap';
  1151. function VisibleAnimationHandle(_a) {
  1152. var visible = _a.visible, currentImage = _a.currentImage, children = _a.children;
  1153. var _b = React.useState(visible), photoVisible = _b[0], updatePhotoVisible = _b[1];
  1154. var _c = React.useState(ShowAnimateEnum.None), showAnimateType = _c[0], updateAnimateStatus = _c[1];
  1155. var _d = React.useState(), originRect = _d[0], updateOriginRect = _d[1];
  1156. function onShowAnimateEnd() {
  1157. updateAnimateStatus(ShowAnimateEnum.None);
  1158. // Close
  1159. if (showAnimateType === ShowAnimateEnum.Out) {
  1160. updatePhotoVisible(false);
  1161. }
  1162. }
  1163. React.useEffect(function () {
  1164. var originRef = (currentImage || {}).originRef;
  1165. if (originRef && originRef.nodeType === 1) {
  1166. // 获取触发时节点位置
  1167. var _a = originRef.getBoundingClientRect(), top_1 = _a.top, left = _a.left, width = _a.width, height = _a.height;
  1168. updateOriginRect({
  1169. clientX: left + width / 2,
  1170. clientY: top_1 + height / 2,
  1171. });
  1172. }
  1173. else if (originRect && !originRef) {
  1174. updateOriginRect(undefined);
  1175. }
  1176. if (visible) {
  1177. updateAnimateStatus(ShowAnimateEnum.In);
  1178. updatePhotoVisible(true);
  1179. }
  1180. else {
  1181. updateAnimateStatus(ShowAnimateEnum.Out);
  1182. }
  1183. }, [visible]);
  1184. return children({
  1185. photoVisible: photoVisible,
  1186. showAnimateType: showAnimateType,
  1187. originRect: originRect,
  1188. onShowAnimateEnd: onShowAnimateEnd,
  1189. });
  1190. }
  1191. function Close(props) {
  1192. return (React.createElement("svg", __assign({ version: "1.1", xmlns: "http://www.w3.org/2000/svg", width: "44", height: "44", viewBox: "0 0 768 768" }, props),
  1193. React.createElement("path", { fill: "#FFF", d: "M607.5 205.5l-178.5 178.5 178.5 178.5-45 45-178.5-178.5-178.5 178.5-45-45 178.5-178.5-178.5-178.5 45-45 178.5 178.5 178.5-178.5z" })));
  1194. }
  1195. function ArrowLeft(props) {
  1196. return (React.createElement("svg", __assign({ version: "1.1", xmlns: "http://www.w3.org/2000/svg", width: "44", height: "44", viewBox: "0 0 768 768" }, props),
  1197. React.createElement("path", { d: "M640.5 352.5v63h-390l178.5 180-45 45-256.5-256.5 256.5-256.5 45 45-178.5 180h390z" })));
  1198. }
  1199. function ArrowRight(props) {
  1200. return (React.createElement("svg", __assign({ version: "1.1", xmlns: "http://www.w3.org/2000/svg", width: "44", height: "44", viewBox: "0 0 768 768" }, props),
  1201. React.createElement("path", { d: "M384 127.5l256.5 256.5-256.5 256.5-45-45 178.5-180h-390v-63h390l-178.5-180z" })));
  1202. }
  1203. var PhotoSlider = /** @class */ (function (_super) {
  1204. __extends(PhotoSlider, _super);
  1205. function PhotoSlider(props) {
  1206. var _this = _super.call(this, props) || this;
  1207. _this.handleClose = function (evt) {
  1208. var onClose = _this.props.onClose;
  1209. var backdropOpacity = _this.state.backdropOpacity;
  1210. onClose(evt);
  1211. _this.setState({
  1212. overlayVisible: true,
  1213. // 记录当前关闭时的透明度
  1214. lastBackdropOpacity: backdropOpacity,
  1215. });
  1216. };
  1217. _this.handlePhotoTap = function () {
  1218. var photoClosable = _this.props.photoClosable;
  1219. if (photoClosable) {
  1220. _this.handleClose();
  1221. }
  1222. else {
  1223. _this.setState(function (prevState) { return ({
  1224. overlayVisible: !prevState.overlayVisible,
  1225. }); });
  1226. }
  1227. };
  1228. _this.handlePhotoMaskTap = function () {
  1229. var maskClosable = _this.props.maskClosable;
  1230. if (maskClosable) {
  1231. _this.handleClose();
  1232. }
  1233. };
  1234. _this.handleResize = function () {
  1235. var innerWidth = window.innerWidth;
  1236. _this.setState(function (_a) {
  1237. var photoIndex = _a.photoIndex;
  1238. return {
  1239. translateX: -(innerWidth + horizontalOffset) * photoIndex,
  1240. lastClientX: undefined,
  1241. lastClientY: undefined,
  1242. shouldTransition: false,
  1243. };
  1244. });
  1245. };
  1246. _this.handleRotate = function (rotating) {
  1247. var _a = _this.state, photoIndex = _a.photoIndex, rotatingMap = _a.rotatingMap;
  1248. rotatingMap.set(photoIndex, rotating);
  1249. _this.setState({
  1250. rotatingMap: rotatingMap,
  1251. });
  1252. };
  1253. _this.handleKeyDown = function (evt) {
  1254. var visible = _this.props.visible;
  1255. if (visible) {
  1256. switch (evt.key) {
  1257. case 'ArrowLeft':
  1258. _this.handlePrevious(false);
  1259. break;
  1260. case 'ArrowRight':
  1261. _this.handleNext(false);
  1262. break;
  1263. case 'Escape':
  1264. _this.handleClose();
  1265. break;
  1266. }
  1267. }
  1268. };
  1269. _this.handleBack = function (evt) {
  1270. evt.stopPropagation();
  1271. console.log("范湖一");
  1272. };
  1273. _this.handleReachVerticalMove = function (clientY, scale) {
  1274. _this.setState(function (_a) {
  1275. var lastClientY = _a.lastClientY, backdropOpacity = _a.backdropOpacity;
  1276. if (lastClientY === undefined) {
  1277. return {
  1278. touched: true,
  1279. lastClientY: clientY,
  1280. backdropOpacity: backdropOpacity,
  1281. canPullClose: true,
  1282. };
  1283. }
  1284. var offsetClientY = Math.abs(clientY - lastClientY);
  1285. var opacity = Math.max(Math.min(defaultOpacity, defaultOpacity - offsetClientY / 100 / 4), 0);
  1286. return {
  1287. touched: true,
  1288. lastClientY: lastClientY,
  1289. backdropOpacity: scale === 1 ? opacity : defaultOpacity,
  1290. canPullClose: scale === 1,
  1291. };
  1292. });
  1293. };
  1294. _this.handleReachHorizontalMove = function (clientX) {
  1295. var innerWidth = window.innerWidth;
  1296. var images = _this.props.images;
  1297. _this.setState(function (_a) {
  1298. var lastClientX = _a.lastClientX, translateX = _a.translateX, photoIndex = _a.photoIndex;
  1299. if (lastClientX === undefined) {
  1300. return {
  1301. touched: true,
  1302. lastClientX: clientX,
  1303. translateX: translateX,
  1304. shouldTransition: true,
  1305. };
  1306. }
  1307. var originOffsetClientX = clientX - lastClientX;
  1308. var offsetClientX = originOffsetClientX;
  1309. // 第一张和最后一张超出距离减半
  1310. if ((photoIndex === 0 && originOffsetClientX > 0) ||
  1311. (photoIndex === images.length - 1 && originOffsetClientX < 0)) {
  1312. offsetClientX = originOffsetClientX / 2;
  1313. }
  1314. return {
  1315. touched: true,
  1316. lastClientX: lastClientX,
  1317. translateX: -(innerWidth + horizontalOffset) * photoIndex + offsetClientX,
  1318. shouldTransition: true,
  1319. };
  1320. });
  1321. };
  1322. _this.handleIndexChange = function (photoIndex, shouldTransition) {
  1323. if (shouldTransition === void 0) { shouldTransition = true; }
  1324. var singlePageWidth = window.innerWidth + horizontalOffset;
  1325. var translateX = -singlePageWidth * photoIndex;
  1326. _this.setState({
  1327. touched: false,
  1328. lastClientX: undefined,
  1329. lastClientY: undefined,
  1330. translateX: translateX,
  1331. photoIndex: photoIndex,
  1332. shouldTransition: shouldTransition,
  1333. });
  1334. var onIndexChange = _this.props.onIndexChange;
  1335. if (onIndexChange) {
  1336. onIndexChange(photoIndex);
  1337. }
  1338. };
  1339. _this.handlePrevious = function (shouldTransition) {
  1340. var photoIndex = _this.state.photoIndex;
  1341. if (photoIndex > 0) {
  1342. _this.handleIndexChange(photoIndex - 1, shouldTransition);
  1343. }
  1344. };
  1345. _this.handleNext = function (shouldTransition) {
  1346. var images = _this.props.images;
  1347. var photoIndex = _this.state.photoIndex;
  1348. if (photoIndex < images.length - 1) {
  1349. _this.handleIndexChange(photoIndex + 1, shouldTransition);
  1350. }
  1351. };
  1352. _this.handleReachMove = function (reachState, clientX, clientY, scale) {
  1353. if (reachState === ReachTypeEnum.XReach) {
  1354. _this.handleReachHorizontalMove(clientX);
  1355. }
  1356. else if (reachState === ReachTypeEnum.YReach) {
  1357. _this.handleReachVerticalMove(clientY, scale);
  1358. }
  1359. };
  1360. _this.handleReachUp = function (clientX, clientY) {
  1361. var images = _this.props.images;
  1362. var _a = _this.state, _b = _a.lastClientX, lastClientX = _b === void 0 ? clientX : _b, _c = _a.lastClientY, lastClientY = _c === void 0 ? clientY : _c, photoIndex = _a.photoIndex, overlayVisible = _a.overlayVisible, canPullClose = _a.canPullClose;
  1363. var offsetClientX = clientX - lastClientX;
  1364. var offsetClientY = clientY - lastClientY;
  1365. var willClose = false;
  1366. // 下一张
  1367. if (offsetClientX < -maxMoveOffset && photoIndex < images.length - 1) {
  1368. _this.handleIndexChange(photoIndex + 1);
  1369. return;
  1370. }
  1371. // 上一张
  1372. if (offsetClientX > maxMoveOffset && photoIndex > 0) {
  1373. _this.handleIndexChange(photoIndex - 1);
  1374. return;
  1375. }
  1376. var singlePageWidth = window.innerWidth + horizontalOffset;
  1377. // 当前偏移
  1378. var currentTranslateX = -singlePageWidth * photoIndex;
  1379. var currentPhotoIndex = photoIndex;
  1380. if (Math.abs(offsetClientY) > window.innerHeight * 0.14 && canPullClose) {
  1381. willClose = true;
  1382. _this.handleClose();
  1383. }
  1384. _this.setState({
  1385. touched: false,
  1386. translateX: currentTranslateX,
  1387. photoIndex: currentPhotoIndex,
  1388. lastClientX: undefined,
  1389. lastClientY: undefined,
  1390. backdropOpacity: defaultOpacity,
  1391. overlayVisible: willClose ? true : overlayVisible,
  1392. });
  1393. };
  1394. _this.state = {
  1395. translateX: 0,
  1396. photoIndex: 0,
  1397. touched: false,
  1398. shouldTransition: true,
  1399. lastClientX: undefined,
  1400. lastClientY: undefined,
  1401. backdropOpacity: defaultOpacity,
  1402. lastBackdropOpacity: defaultOpacity,
  1403. overlayVisible: true,
  1404. canPullClose: true,
  1405. rotatingMap: new Map(),
  1406. };
  1407. return _this;
  1408. }
  1409. PhotoSlider.getDerivedStateFromProps = function (nextProps, prevState) {
  1410. if (nextProps.index !== undefined && nextProps.index !== prevState.photoIndex) {
  1411. return {
  1412. photoIndex: nextProps.index,
  1413. translateX: -(window.innerWidth + horizontalOffset) * nextProps.index,
  1414. };
  1415. }
  1416. return null;
  1417. };
  1418. PhotoSlider.prototype.componentDidMount = function () {
  1419. var _a = this.props.index, index = _a === void 0 ? 0 : _a;
  1420. this.setState({
  1421. translateX: index * -(window.innerWidth + horizontalOffset),
  1422. photoIndex: index,
  1423. });
  1424. window.addEventListener('keydown', this.handleKeyDown);
  1425. window.addEventListener('popstate', this.handleBack);
  1426. };
  1427. PhotoSlider.prototype.componentWillUnmount = function () {
  1428. window.removeEventListener('keydown', this.handleKeyDown);
  1429. };
  1430. PhotoSlider.prototype.render = function () {
  1431. var _this = this;
  1432. var _a = this.props, images = _a.images, visible = _a.visible, className = _a.className, maskClassName = _a.maskClassName, viewClassName = _a.viewClassName, imageClassName = _a.imageClassName, bannerVisible = _a.bannerVisible, introVisible = _a.introVisible, overlayRender = _a.overlayRender, toolbarRender = _a.toolbarRender, loadingElement = _a.loadingElement, brokenElement = _a.brokenElement;
  1433. var _b = this.state, translateX = _b.translateX, touched = _b.touched, photoIndex = _b.photoIndex, backdropOpacity = _b.backdropOpacity, lastBackdropOpacity = _b.lastBackdropOpacity, overlayVisible = _b.overlayVisible, rotatingMap = _b.rotatingMap, shouldTransition = _b.shouldTransition;
  1434. var imageLength = images.length;
  1435. var currentImage = images.length ? images[photoIndex] : undefined;
  1436. var transform = "translate3d(" + translateX + "px, 0px, 0)";
  1437. // Overlay
  1438. var overlayIntro = currentImage && currentImage.intro;
  1439. return (React.createElement(VisibleAnimationHandle, { visible: visible, currentImage: currentImage }, function (_a) {
  1440. var photoVisible = _a.photoVisible, showAnimateType = _a.showAnimateType, originRect = _a.originRect, onShowAnimateEnd = _a.onShowAnimateEnd;
  1441. if (photoVisible) {
  1442. var innerWidth_1 = window.innerWidth;
  1443. var currentOverlayVisible = overlayVisible && showAnimateType === ShowAnimateEnum.None;
  1444. // 关闭过程中使用下拉保存的透明度
  1445. var currentOpacity = visible ? backdropOpacity : lastBackdropOpacity;
  1446. // 覆盖物参数
  1447. var overlayParams = {
  1448. images: images,
  1449. index: photoIndex,
  1450. visible: visible,
  1451. onClose: _this.handleClose,
  1452. onIndexChange: _this.handleIndexChange,
  1453. overlayVisible: currentOverlayVisible,
  1454. onRotate: _this.handleRotate,
  1455. rotate: rotatingMap.get(photoIndex) || 0,
  1456. };
  1457. return (React.createElement(SlideWrap, { className: classNames({
  1458. 'PhotoView-PhotoSlider__clean': !currentOverlayVisible,
  1459. 'PhotoView-PhotoSlider__willClose': !visible,
  1460. }, className), role: "dialog", id: "PhotoView_Slider", onClick: function (e) { return e.stopPropagation(); } },
  1461. React.createElement("div", { className: classNames('PhotoView-PhotoSlider__Backdrop', maskClassName, {
  1462. 'PhotoView-PhotoSlider__fadeIn': showAnimateType === ShowAnimateEnum.In,
  1463. 'PhotoView-PhotoSlider__fadeOut': showAnimateType === ShowAnimateEnum.Out,
  1464. }), style: {
  1465. background: "rgba(0, 0, 0, " + currentOpacity + ")",
  1466. }, onAnimationEnd: onShowAnimateEnd }),
  1467. bannerVisible && (React.createElement("div", { className: "PhotoView-PhotoSlider__BannerWrap" },
  1468. React.createElement("div", { className: "PhotoView-PhotoSlider__Counter" },
  1469. photoIndex + 1,
  1470. " / ",
  1471. imageLength),
  1472. React.createElement("div", { className: "PhotoView-PhotoSlider__BannerRight" },
  1473. toolbarRender && toolbarRender(overlayParams),
  1474. React.createElement(Close, { className: "PhotoView-PhotoSlider__toolbarIcon", onClick: _this.handleClose })))),
  1475. images
  1476. .slice(
  1477. // 加载相邻三张
  1478. Math.max(photoIndex - 1, 0), Math.min(photoIndex + 2, imageLength + 1))
  1479. .map(function (item, index) {
  1480. // 截取之前的索引位置
  1481. var realIndex = photoIndex === 0 ? photoIndex + index : photoIndex - 1 + index;
  1482. return (React.createElement(PhotoView, { key: item.key || realIndex, src: item.src, intro: item.intro, onReachMove: _this.handleReachMove, onReachUp: _this.handleReachUp, onPhotoTap: _this.handlePhotoTap, onMaskTap: _this.handlePhotoMaskTap, viewClassName: viewClassName, className: imageClassName, style: {
  1483. left: (innerWidth_1 + horizontalOffset) * realIndex + "px",
  1484. WebkitTransform: transform,
  1485. transform: transform,
  1486. transition: touched || !shouldTransition
  1487. ? undefined
  1488. : 'transform 0.6s cubic-bezier(0.25, 0.8, 0.25, 1)',
  1489. }, loadingElement: loadingElement, brokenElement: brokenElement, onPhotoResize: _this.handleResize, isActive: photoIndex === realIndex, showAnimateType: showAnimateType, originRect: originRect, rotate: rotatingMap.get(realIndex) || 0 }));
  1490. }),
  1491. !isTouchDevice && bannerVisible && (React.createElement(React.Fragment, null,
  1492. photoIndex !== 0 && (React.createElement("div", { className: "PhotoView-PhotoSlider__ArrowLeft", onClick: function () { return _this.handlePrevious(false); } },
  1493. React.createElement(ArrowLeft, null))),
  1494. photoIndex + 1 < imageLength && (React.createElement("div", { className: "PhotoView-PhotoSlider__ArrowRight", onClick: function () { return _this.handleNext(false); } },
  1495. React.createElement(ArrowRight, null))))),
  1496. Boolean(introVisible && overlayIntro) && (React.createElement("div", { className: "PhotoView-PhotoSlider__FooterWrap" }, overlayIntro)),
  1497. overlayRender && overlayRender(overlayParams)));
  1498. }
  1499. return null;
  1500. }));
  1501. };
  1502. PhotoSlider.displayName = 'PhotoSlider';
  1503. PhotoSlider.defaultProps = {
  1504. maskClosable: true,
  1505. photoClosable: false,
  1506. bannerVisible: true,
  1507. introVisible: true,
  1508. };
  1509. return PhotoSlider;
  1510. }(React.Component));
  1511. var PhotoProvider = /** @class */ (function (_super) {
  1512. __extends(PhotoProvider, _super);
  1513. function PhotoProvider(props) {
  1514. var _this = _super.call(this, props) || this;
  1515. _this.handleAddItem = function (imageItem) {
  1516. _this.setState(function (prev) { return ({
  1517. images: prev.images.concat(imageItem),
  1518. }); });
  1519. };
  1520. _this.handleRemoveItem = function (key) {
  1521. _this.setState(function (_a) {
  1522. var images = _a.images, index = _a.index;
  1523. var nextImages = images.filter(function (item) { return item.key !== key; });
  1524. var nextEndIndex = nextImages.length - 1;
  1525. return {
  1526. images: nextImages,
  1527. index: Math.min(nextEndIndex, index),
  1528. };
  1529. });
  1530. };
  1531. _this.handleShow = function (key) {
  1532. var images = _this.state.images;
  1533. _this.setState({
  1534. visible: true,
  1535. index: images.findIndex(function (item) { return item.key === key; }),
  1536. });
  1537. };
  1538. _this.handleClose = function () {
  1539. _this.setState({
  1540. visible: false,
  1541. });
  1542. };
  1543. _this.handleIndexChange = function (index) {
  1544. _this.setState({
  1545. index: index,
  1546. });
  1547. };
  1548. _this.state = {
  1549. images: [],
  1550. visible: false,
  1551. index: 0,
  1552. addItem: _this.handleAddItem,
  1553. removeItem: _this.handleRemoveItem,
  1554. onShow: _this.handleShow,
  1555. };
  1556. return _this;
  1557. }
  1558. PhotoProvider.prototype.render = function () {
  1559. var _a = this.props, children = _a.children, restProps = __rest(_a, ["children"]);
  1560. var _b = this.state, images = _b.images, visible = _b.visible, index = _b.index;
  1561. return (React.createElement(PhotoContext.Provider, { value: this.state },
  1562. children,
  1563. React.createElement(PhotoSlider, __assign({ images: images, visible: visible, index: index, onIndexChange: this.handleIndexChange, onClose: this.handleClose }, restProps))));
  1564. };
  1565. return PhotoProvider;
  1566. }(React.Component));
  1567. /**
  1568. * lodash (Custom Build) <https://lodash.com/>
  1569. * Build: `lodash modularize exports="npm" -o ./`
  1570. * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  1571. * Released under MIT license <https://lodash.com/license>
  1572. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  1573. * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  1574. */
  1575. /** Used as references for various `Number` constants. */
  1576. var INFINITY = 1 / 0;
  1577. /** `Object#toString` result references. */
  1578. var symbolTag$1 = '[object Symbol]';
  1579. /** Detect free variable `global` from Node.js. */
  1580. var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
  1581. /** Detect free variable `self`. */
  1582. var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self;
  1583. /** Used as a reference to the global object. */
  1584. var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')();
  1585. /** Used for built-in method references. */
  1586. var objectProto$1 = Object.prototype;
  1587. /** Used to generate unique IDs. */
  1588. var idCounter = 0;
  1589. /**
  1590. * Used to resolve the
  1591. * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
  1592. * of values.
  1593. */
  1594. var objectToString$1 = objectProto$1.toString;
  1595. /** Built-in value references. */
  1596. var Symbol = root$1.Symbol;
  1597. /** Used to convert symbols to primitives and strings. */
  1598. var symbolProto = Symbol ? Symbol.prototype : undefined,
  1599. symbolToString = symbolProto ? symbolProto.toString : undefined;
  1600. /**
  1601. * The base implementation of `_.toString` which doesn't convert nullish
  1602. * values to empty strings.
  1603. *
  1604. * @private
  1605. * @param {*} value The value to process.
  1606. * @returns {string} Returns the string.
  1607. */
  1608. function baseToString(value) {
  1609. // Exit early for strings to avoid a performance hit in some environments.
  1610. if (typeof value == 'string') {
  1611. return value;
  1612. }
  1613. if (isSymbol$1(value)) {
  1614. return symbolToString ? symbolToString.call(value) : '';
  1615. }
  1616. var result = (value + '');
  1617. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  1618. }
  1619. /**
  1620. * Checks if `value` is object-like. A value is object-like if it's not `null`
  1621. * and has a `typeof` result of "object".
  1622. *
  1623. * @static
  1624. * @memberOf _
  1625. * @since 4.0.0
  1626. * @category Lang
  1627. * @param {*} value The value to check.
  1628. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  1629. * @example
  1630. *
  1631. * _.isObjectLike({});
  1632. * // => true
  1633. *
  1634. * _.isObjectLike([1, 2, 3]);
  1635. * // => true
  1636. *
  1637. * _.isObjectLike(_.noop);
  1638. * // => false
  1639. *
  1640. * _.isObjectLike(null);
  1641. * // => false
  1642. */
  1643. function isObjectLike$1(value) {
  1644. return !!value && typeof value == 'object';
  1645. }
  1646. /**
  1647. * Checks if `value` is classified as a `Symbol` primitive or object.
  1648. *
  1649. * @static
  1650. * @memberOf _
  1651. * @since 4.0.0
  1652. * @category Lang
  1653. * @param {*} value The value to check.
  1654. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  1655. * @example
  1656. *
  1657. * _.isSymbol(Symbol.iterator);
  1658. * // => true
  1659. *
  1660. * _.isSymbol('abc');
  1661. * // => false
  1662. */
  1663. function isSymbol$1(value) {
  1664. return typeof value == 'symbol' ||
  1665. (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1);
  1666. }
  1667. /**
  1668. * Converts `value` to a string. An empty string is returned for `null`
  1669. * and `undefined` values. The sign of `-0` is preserved.
  1670. *
  1671. * @static
  1672. * @memberOf _
  1673. * @since 4.0.0
  1674. * @category Lang
  1675. * @param {*} value The value to process.
  1676. * @returns {string} Returns the string.
  1677. * @example
  1678. *
  1679. * _.toString(null);
  1680. * // => ''
  1681. *
  1682. * _.toString(-0);
  1683. * // => '-0'
  1684. *
  1685. * _.toString([1, 2, 3]);
  1686. * // => '1,2,3'
  1687. */
  1688. function toString(value) {
  1689. return value == null ? '' : baseToString(value);
  1690. }
  1691. /**
  1692. * Generates a unique ID. If `prefix` is given, the ID is appended to it.
  1693. *
  1694. * @static
  1695. * @since 0.1.0
  1696. * @memberOf _
  1697. * @category Util
  1698. * @param {string} [prefix=''] The value to prefix the ID with.
  1699. * @returns {string} Returns the unique ID.
  1700. * @example
  1701. *
  1702. * _.uniqueId('contact_');
  1703. * // => 'contact_104'
  1704. *
  1705. * _.uniqueId();
  1706. * // => '105'
  1707. */
  1708. function uniqueId(prefix) {
  1709. var id = ++idCounter;
  1710. return toString(prefix) + id;
  1711. }
  1712. var lodash_uniqueid = uniqueId;
  1713. var PhotoConsumer = function (_a) {
  1714. var src = _a.src, intro = _a.intro, children = _a.children;
  1715. var photoContext = React.useContext(PhotoContext);
  1716. var key = React.useMemo(function () { return lodash_uniqueid(); }, []);
  1717. var _b = React.useState({
  1718. clientX: undefined,
  1719. clientY: undefined,
  1720. }), position = _b[0], updatePosition = _b[1];
  1721. var photoTriggerRef = React.useRef(null);
  1722. React.useEffect(function () {
  1723. photoContext.addItem({
  1724. key: key,
  1725. src: src,
  1726. originRef: photoTriggerRef.current,
  1727. intro: intro,
  1728. });
  1729. return function () {
  1730. photoContext.removeItem(key);
  1731. };
  1732. }, []);
  1733. function handleTouchStart(e) {
  1734. var _a = e.touches[0], clientX = _a.clientX, clientY = _a.clientY;
  1735. updatePosition({
  1736. clientX: clientX,
  1737. clientY: clientY,
  1738. });
  1739. if (children) {
  1740. var onTouchStart = children.props.onTouchStart;
  1741. if (onTouchStart) {
  1742. onTouchStart(e);
  1743. }
  1744. }
  1745. }
  1746. function handleTouchEnd(e) {
  1747. var _a = e.changedTouches[0], clientX = _a.clientX, clientY = _a.clientY;
  1748. if (position.clientX === clientX && position.clientY === clientY) {
  1749. photoContext.onShow(key);
  1750. }
  1751. if (children) {
  1752. var onTouchEnd = children.props.onTouchEnd;
  1753. if (onTouchEnd) {
  1754. onTouchEnd(e);
  1755. }
  1756. }
  1757. }
  1758. function handleClick(e) {
  1759. photoContext.onShow(key);
  1760. if (children) {
  1761. var onClick = children.props.onClick;
  1762. if (onClick) {
  1763. onClick(e);
  1764. }
  1765. }
  1766. }
  1767. if (children) {
  1768. return React.Children.only(React.cloneElement(children, isTouchDevice
  1769. ? {
  1770. onTouchStart: handleTouchStart,
  1771. onTouchEnd: handleTouchEnd,
  1772. ref: photoTriggerRef,
  1773. }
  1774. : { onClick: handleClick, ref: photoTriggerRef }));
  1775. }
  1776. return null;
  1777. };
  1778. exports.PhotoConsumer = PhotoConsumer;
  1779. exports.PhotoProvider = PhotoProvider;
  1780. exports.PhotoSlider = PhotoSlider;
  1781. //# sourceMappingURL=index.js.map