image.stories.jsx 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. import React, { useState, useCallback, useMemo, useEffect } from "react";
  2. import {
  3. Image,
  4. Button,
  5. ImagePreview,
  6. Row,
  7. Col,
  8. Icon,
  9. Switch,
  10. Input,
  11. Divider,
  12. Tooltip
  13. } from "../../index";
  14. import {
  15. IconChevronLeft,
  16. IconChevronRight,
  17. IconMinus,
  18. IconPlus,
  19. IconRotate,
  20. IconDownload,
  21. IconWindowAdaptionStroked,
  22. IconRealSizeStroked,
  23. IconUploadError,
  24. IconInfoCircle
  25. } from "@douyinfe/semi-icons";
  26. export default {
  27. title: "Image",
  28. parameters: {
  29. chromatic: { disableSnapshot: true },
  30. }
  31. }
  32. const srcList1 = [
  33. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/lion.jpeg",
  34. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/seaside.jpeg",
  35. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/beach.jpeg",
  36. ];
  37. const srcList2 = [
  38. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag1.png",
  39. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag2.png",
  40. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag3.png",
  41. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag4.png",
  42. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag5.png",
  43. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag6.png",
  44. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag7.png",
  45. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/imag8.png",
  46. ];
  47. export const basicImage = () => {
  48. const [escOut, setEscOut] = useState(true);
  49. const [disableDownload, setDisableDownload] = useState(false);
  50. const [maskClosable, setMaskClosable] = useState(true);
  51. const [preview, setPreview] = useState(true);
  52. const itemStyle = { display: 'flex', alignItems: 'center', flexShrink: 0, width: 'fit-content', margin: '10px 20px 0 0' };
  53. const menuStyle = { marginBottom: 20, display: 'flex', flexWrap: 'wrap' };
  54. return (
  55. <>
  56. <div style={menuStyle}>
  57. <div style={itemStyle} id='preview'>
  58. <span >是否可预览:</span>
  59. <Switch checked={preview} checkedText="是" uncheckedText="否" onChange={setPreview}/>
  60. </div>
  61. <div style={itemStyle} id='escOut'>
  62. <span>点击 esc 是否关闭预览:</span>
  63. <Switch checked={escOut} checkedText="是" uncheckedText="否" onChange={setEscOut}/>
  64. </div>
  65. <div style={itemStyle} id='disableDownload'>
  66. <span >是否禁用下载:</span>
  67. <Switch checked={disableDownload} checkedText="是" uncheckedText="否" onChange={setDisableDownload}/>
  68. </div>
  69. <div style={itemStyle} id='maskClosable'>
  70. <span >点击遮罩层是否关闭预览:</span>
  71. <Switch checked={maskClosable} checkedText="是" uncheckedText="否" onChange={setMaskClosable}/>
  72. </div>
  73. </div>
  74. <Image
  75. width={360}
  76. height={200}
  77. src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-lite.jpeg"
  78. preview={preview ? {
  79. closeOnEsc: escOut,
  80. disableDownload,
  81. maskClosable
  82. } : false}
  83. />
  84. </>
  85. )}
  86. export const LoadErrorImage = () => (
  87. <>
  88. <p>加载失败默认样式</p>
  89. <Image
  90. width={200}
  91. height={200}
  92. src="https://load-error.jpeg"
  93. />
  94. <br />
  95. <p>自定义加载失败占位图</p>
  96. <Image
  97. width={200}
  98. height={200}
  99. src="https://load-error.jpeg"
  100. fallback={<IconUploadError style={{ fontSize: 50 }} />}
  101. />
  102. </>
  103. )
  104. export const ProgressiveLoading = () => {
  105. const [timestamp, setTimestamp] = React.useState('');
  106. return (
  107. <>
  108. <Image
  109. width={300}
  110. height={200}
  111. src={`https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-big.png?${timestamp}`}
  112. placeholder={<Image
  113. src='https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-small.jpeg'
  114. width={300}
  115. height={200}
  116. preview={false}
  117. />}
  118. />
  119. <br />
  120. <Button
  121. theme={'solid'}
  122. onClick={() => {
  123. setTimestamp(Date.now());
  124. }}
  125. style={{ marginTop: 10 }}
  126. >Reload</Button>
  127. </>
  128. );
  129. }
  130. export const CustomPreviewImage = () => (
  131. <Image
  132. width={300}
  133. height={200}
  134. src={'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-small.jpeg'}
  135. preview={{
  136. src: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-big.png'
  137. }}
  138. />
  139. )
  140. export const ControlledPreviewSingle = () => {
  141. const [visible, setVisible] = useState(false);
  142. const handlePreviewVisibleChange = useCallback((v) => {
  143. setVisible(v);
  144. }, []);
  145. const handleClick = useCallback(() => {
  146. setVisible(!visible);
  147. }, [visible])
  148. return (
  149. <>
  150. <Button onClick={handleClick}>{visible ? "hide" : "show single"}</Button>
  151. <ImagePreview
  152. src={"https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-lite.jpeg"}
  153. visible={visible}
  154. onVisibleChange={handlePreviewVisibleChange}
  155. />
  156. </>
  157. )
  158. }
  159. export const ImageShowControlled = () => {
  160. const [visible, setVisible] = useState(false);
  161. const handlePreviewVisibleChange = useCallback((v) => {
  162. setVisible(v);
  163. }, []);
  164. return (
  165. <Image
  166. width={360}
  167. height={200}
  168. src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract-lite.jpeg"
  169. preview={{
  170. visible: visible,
  171. onVisibleChange: handlePreviewVisibleChange
  172. }}
  173. />
  174. );
  175. }
  176. export const ControlledPreviewMultiple = () => {
  177. const [visible, setVisible] = useState(false);
  178. const handlePreviewVisibleChange = useCallback((v) => {
  179. setVisible(v);
  180. }, []);
  181. const handleClick = useCallback(() => {
  182. setVisible(!visible);
  183. }, [visible])
  184. return (
  185. <>
  186. <Button onClick={handleClick}>{visible ? "hide" : "show multiple"}</Button>
  187. <ImagePreview
  188. src={srcList1}
  189. visible={visible}
  190. onVisibleChange={handlePreviewVisibleChange}
  191. />
  192. </>
  193. )
  194. }
  195. export const DefaultCurrentIndex = () => {
  196. const [visible, setVisible] = useState(false);
  197. const [index, setIndex] = useState(1);
  198. const handlePreviewVisibleChange = useCallback((v) => {
  199. setVisible(v);
  200. }, []);
  201. const handleClick = useCallback(() => {
  202. setVisible(!visible);
  203. }, [visible])
  204. const onInputChange = useCallback((value) => {
  205. setIndex(Number(value) ?? 0);
  206. }
  207. ,[])
  208. const imageData = srcList1;
  209. return (
  210. <>
  211. <span>{`输入默认打开图片index(0-${imageData.length - 1})`}</span>
  212. <Input style={{ width: 100 }} defaultValue={index} onChange={onInputChange}/>
  213. <br /><br />
  214. <Button onClick={handleClick}>{visible ? "hide" : "show multiple"}</Button>
  215. <ImagePreview
  216. key={index}
  217. src={imageData}
  218. visible={visible}
  219. defaultCurrentIndex={index}
  220. onVisibleChange={handlePreviewVisibleChange}
  221. />
  222. </>
  223. );
  224. }
  225. export const BasicPreview = () => {
  226. const [showTooltip, setShowTooltip] = useState(false);
  227. const [customTooltip, setCustomTooltip] = useState(false);
  228. const [infinite, setInfinite] = useState(false);
  229. const customTooltipProps = {
  230. prevTip: "Prev",
  231. nextTip: "Next",
  232. zoomInTip: "ZoomIn",
  233. zoomOutTip: "ZoomOut",
  234. rotateTip: "Rotate",
  235. downloadTip: "Download",
  236. adaptiveTip: "Adaption",
  237. originTip: "Original size"
  238. };
  239. const props = useMemo(() => {
  240. let props = {};
  241. if (showTooltip) {
  242. props = { showTooltip: true };
  243. if (customTooltip) {
  244. props = {...props, ...customTooltipProps}
  245. }
  246. }
  247. if (infinite) {
  248. props.infinite = true;
  249. }
  250. return props;
  251. }, [showTooltip, customTooltip, infinite])
  252. const itemStyle = { display: 'flex', alignItems: 'center', flexShrink: 0, width: 'fit-content', margin: '10px 20px 0 0' };
  253. const menuStyle = { marginBottom: 20, display: 'flex', flexWrap: 'wrap' };
  254. return (
  255. <>
  256. <div style={menuStyle}>
  257. <div style={itemStyle} id='showTooltip'>
  258. <span>是否show tooltip:</span>
  259. <Switch checked={showTooltip} checkedText="是" uncheckedText="否" onChange={setShowTooltip}/>
  260. </div>
  261. <div style={itemStyle} id='customTooltip'>
  262. <span>是否custom tooltip:</span>
  263. <Switch checked={customTooltip} checkedText="是" uncheckedText="否" onChange={setCustomTooltip}/>
  264. </div>
  265. <div style={itemStyle} id='infinite'>
  266. <span >是否无限循环:</span>
  267. <Switch checked={infinite} checkedText="是" uncheckedText="否" onChange={setInfinite}/>
  268. </div>
  269. </div>
  270. <ImagePreview {...props}>
  271. {srcList1.map((src, index) => {
  272. return (
  273. <Image
  274. key={index}
  275. src={src}
  276. width={200}
  277. alt={`lamp${index + 1}`}
  278. />
  279. )})}
  280. </ImagePreview>
  281. </>
  282. )};
  283. // test all call back function
  284. export const TestCallBackFunc = () => {
  285. const visibleChange = useCallback((v) => {
  286. console.log("visible change", v);
  287. }, []);
  288. const change = useCallback((index) => {
  289. console.log("change", index);
  290. } , []);
  291. const zoomIn = useCallback((zoom) => {
  292. console.log("zoom in", zoom);
  293. }, []);
  294. const zoomOut = useCallback((zoom) => {
  295. console.log("zoom out", zoom);
  296. }, []);
  297. const prev = useCallback((index) => {
  298. console.log("prev", index);
  299. }, []);
  300. const next = useCallback((index) => {
  301. console.log("next", index);
  302. }, []);
  303. const ratioChange = useCallback((type) => {
  304. console.log("ratio change", type);
  305. }, []);
  306. const rotateChange = useCallback((angle) => {
  307. console.log("rotate change", angle);
  308. }, []);
  309. const download = useCallback((src, index) =>{
  310. console.log("download", src, index);
  311. }, []);
  312. return (
  313. <>
  314. <ImagePreview
  315. onVisibleChange={visibleChange}
  316. // onChange={change}
  317. onClose={close}
  318. onZoomIn={zoomIn}
  319. onZoomOut={zoomOut}
  320. onPrev={prev}
  321. onNext={next}
  322. onRotateLeft={rotateChange}
  323. onDownload={download}
  324. >
  325. <div >
  326. {srcList1.map((src, index) => {
  327. return (
  328. <Image key={index} src={src} width={200} alt={`lamp${index + 1}`} />
  329. )})}
  330. </div>
  331. </ImagePreview>
  332. </>
  333. )
  334. };
  335. export const GridImage= () => {
  336. const [gap, setGap] = useState(3);
  337. const [infinite, setInfinite] = useState(true);
  338. const switchChange = useCallback((value) => {
  339. setInfinite(value);
  340. }, []);
  341. const onInputChange = useCallback((value) => {
  342. setGap(value)
  343. }, []);
  344. return (
  345. <>
  346. <span>是否开启 infinite:</span>
  347. <Switch checked={infinite} checkedText="是" uncheckedText="否" onChange={switchChange}/>
  348. <span style={{ marginLeft: 50 }}>输入 preLoadGap: </span>
  349. <Input style={{ width: 150 }} value={gap} onChange={onInputChange} />
  350. <ImagePreview
  351. key={gap}
  352. preLoad={true}
  353. preLoadGap={Number(gap)}
  354. infinite={infinite}
  355. >
  356. <Row style={{ width: 800 }}>
  357. {srcList2.map((src, index) => {
  358. return (
  359. <Col span={6} style={{ height: 200 }} key={`col${index}`}>
  360. <Image key={index} src={src} style={{ width: 200, height: 200 }} width={200} alt={`lamp${index + 1}`} />
  361. </Col>
  362. )})}
  363. </Row>
  364. </ImagePreview>
  365. </>
  366. )};
  367. export const LazyLoadImage = () => {
  368. return (
  369. <>
  370. <ImagePreview
  371. style={{ width: 848, height: 200, overflow: 'auto' }}
  372. lazyLoadMargin={"0px"}
  373. >
  374. <Row style={{ width: 800 }}>
  375. {srcList2.map((src, index) => {
  376. return (
  377. <Col span={6} style={{ height: 200 }} key={`col${index}`}>
  378. <Image key={index} src={src} style={{ width: 200, height: 200 }} width={200} alt={`lamp${index + 1}`} />
  379. </Col>
  380. )})}
  381. </Row>
  382. </ImagePreview>
  383. </>
  384. )};
  385. export const CustomContainer = () => {
  386. const srcList = useMemo(() => ([
  387. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/flower.jpeg",
  388. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/duck.jpeg",
  389. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/swan.jpeg",
  390. ]), []);
  391. return (
  392. <>
  393. <div
  394. id="container"
  395. style={{
  396. height: 400,
  397. position: "relative",
  398. }}
  399. >
  400. <ImagePreview
  401. getPopupContainer={() => {
  402. const node = document.getElementById("container");
  403. return node;
  404. }}
  405. style={{
  406. height: "100%",
  407. display: "flex",
  408. alignItems: "center",
  409. justifyContent: "center",
  410. flexWrap: "wrap",
  411. }}
  412. >
  413. {srcList.map((src, index) => {
  414. return (
  415. <Image
  416. key={index}
  417. src={src}
  418. width={200}
  419. alt={`lamp${index + 1}`}
  420. />
  421. );
  422. })}
  423. </ImagePreview>
  424. </div>
  425. </>
  426. );
  427. }
  428. export const customRenderFooterMenu = () => {
  429. const download = useCallback((src, index) =>{
  430. console.log("download", src, index);
  431. }, []);
  432. const renderPreviewMenu = useCallback((props) => {
  433. const {
  434. ratio,
  435. disabledPrev,
  436. disabledNext,
  437. disableZoomIn,
  438. disableZoomOut,
  439. disableDownload,
  440. onDownload,
  441. onNext,
  442. onPrev,
  443. onRotateLeft,
  444. onRotateRight,
  445. onRatioClick,
  446. onZoomIn,
  447. onZoomOut,
  448. } = props;
  449. return (
  450. <div
  451. style={{
  452. background: "grey",
  453. height: 40,
  454. display: "flex",
  455. alignItems: "center",
  456. justifyContent: "space-around",
  457. borderRadius: 3,
  458. }}
  459. >
  460. <Button
  461. icon={<IconChevronLeft size="large" />}
  462. type="tertiary"
  463. onClick={!disabledPrev ? onPrev : undefined}
  464. disabled={disabledPrev}
  465. />
  466. <Button
  467. icon={<IconChevronRight size="large" />}
  468. type="tertiary"
  469. onClick={!disabledNext ? onNext : undefined}
  470. disabled={disabledNext}
  471. />
  472. <Button
  473. icon={<IconMinus size="large" />}
  474. type="tertiary"
  475. onClick={!disableZoomOut ? onZoomOut : undefined}
  476. disabled={disableZoomOut}
  477. />
  478. <Button
  479. icon={<IconPlus size="large" />}
  480. type="tertiary"
  481. onClick={!disableZoomIn ? onZoomIn : undefined}
  482. disabled={disableZoomIn}
  483. />
  484. <Button
  485. icon={ratio === "adaptation" ? <IconRealSizeStroked size="large" /> : <IconWindowAdaptionStroked size="large" />}
  486. type="tertiary"
  487. onClick={onRatioClick}
  488. />
  489. <Button
  490. icon={<IconRotate size="large" style={{ transform: 'scale(-1,1)'}}/>}
  491. type="tertiary"
  492. onClick={onRotateRight}
  493. />
  494. <Button
  495. icon={<IconRotate size="large" />}
  496. type="tertiary"
  497. onClick={onRotateLeft}
  498. />
  499. <Button
  500. icon={<IconDownload size="large" />}
  501. type="tertiary"
  502. onClick={!disableDownload ? onDownload : undefined}
  503. disabled={disableDownload}
  504. />
  505. </div>);
  506. }, []);
  507. return (
  508. <>
  509. <ImagePreview
  510. renderPreviewMenu={renderPreviewMenu}
  511. onDownload={download}
  512. >
  513. {srcList1.map((src, index) => {
  514. return <Image key={index} src={src} width={200} alt={`lamp${index + 1}`} />
  515. })}
  516. </ImagePreview>
  517. </>
  518. );
  519. }
  520. export const customRenderFooterMenuByNode = () => {
  521. const renderPreviewMenu = useCallback((props) => {
  522. const { menuItems } = props;
  523. const customNode = <Tooltip content='我是一个自定义操作'><IconInfoCircle size="large" /></Tooltip>;
  524. return (
  525. <div style={{ display: 'flex', backgroundColor: 'rgba(0, 0, 0, 0.75)', alignItems: 'center', padding: '5px 16px', borderRadius: 4 }}>
  526. {menuItems.slice(0, 3)}
  527. <Divider layout="vertical" />
  528. {menuItems.slice(3, 7)}
  529. <Divider layout="vertical" />
  530. {menuItems.slice(7)}
  531. <Divider layout="vertical" />
  532. {customNode}
  533. </div>
  534. );
  535. }, []);
  536. return (
  537. <>
  538. <ImagePreview
  539. renderPreviewMenu={renderPreviewMenu}
  540. >
  541. {srcList1.map((src, index) => (<Image key={index} src={src} width={200} alt={`lamp${index + 1}`} />))}
  542. </ImagePreview>
  543. </>
  544. );
  545. }
  546. export const CustomRenderTitle = () => (
  547. <>
  548. <ImagePreview
  549. renderHeader={(title) => (
  550. <div
  551. style={{
  552. background: "green",
  553. width: "100%",
  554. height: "100%",
  555. display: "flex",
  556. alignItems: "center",
  557. justifyContent: "center"
  558. }}
  559. >
  560. {title}
  561. </div>
  562. )}
  563. >
  564. <div >
  565. {srcList1.map((src, index) => {
  566. return (
  567. <Image
  568. key={index}
  569. src={src}
  570. width={200}
  571. alt={`lamp${index + 1}`}
  572. preview={{
  573. previewTitle: `lamp${index + 1}`,
  574. }}
  575. />
  576. )})}
  577. </div>
  578. </ImagePreview>
  579. </>
  580. );
  581. export const issue1526 = () => {
  582. // 测试懒加载状态下,image src 改变时候加载是否符合预期
  583. const [src, setSrc] = useState([]);
  584. const srcList1 = [
  585. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/lion.jpeg",
  586. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/seaside.jpeg",
  587. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/beach.jpeg",
  588. ];
  589. // 模拟远程加载
  590. useEffect(() => {
  591. setTimeout(() => {
  592. setSrc(srcList1);
  593. }, 1000);
  594. }, []);
  595. return (
  596. <ImagePreview zIndex={1000} >
  597. {src.map((file, index) => (
  598. <div
  599. style={{
  600. position: 'relative',
  601. cursor: 'pointer',
  602. display: 'inline-block',
  603. }}
  604. key={file}
  605. >
  606. <Image key={file} src={file} width={96} height={96} />
  607. </div>
  608. ))}
  609. </ImagePreview>
  610. )
  611. }
  612. export const SetDownloadName = () => {
  613. const srcList = useMemo(() => ([
  614. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract.jpg?timestap=1",
  615. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/sky.jpg?timestap=1",
  616. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/greenleaf.jpg?timestap=1",
  617. "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/colorful.jpg?timestap=1",
  618. ]), []);
  619. const setDownloadName = (src) => {
  620. let newSrc = src.slice(src.lastIndexOf("/") + 1);
  621. newSrc = newSrc.slice(0, newSrc.indexOf('?'));
  622. return newSrc;
  623. }
  624. return (
  625. <>
  626. <Image
  627. width={360}
  628. height={200}
  629. src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/abstract.jpg?test"
  630. setDownloadName={setDownloadName}
  631. />
  632. <br/>
  633. <br />
  634. <ImagePreview
  635. setDownloadName={setDownloadName}
  636. >
  637. {srcList.map((src, index) => {
  638. return (
  639. <Image
  640. key={index}
  641. src={src}
  642. width={200}
  643. alt={`lamp${index + 1}`}
  644. style={{ marginRight: 5 }}
  645. />
  646. );
  647. })}
  648. </ImagePreview>
  649. </>);
  650. }