upgrade image previewer

This commit is contained in:
seaheart
2023-08-12 12:42:00 +08:00
parent 46957d317e
commit 2787c95916
5 changed files with 54 additions and 147 deletions
+3 -4
View File
@@ -7,7 +7,6 @@
"@craco/craco": "6.4.3",
"@types/echarts": "4.6.1",
"@types/node": "16.7.13",
"@types/photoswipe": "^4.1.2",
"@types/qs": "^6.9.7",
"@types/react": "17.0.2",
"@types/react-dom": "17.0.2",
@@ -18,7 +17,7 @@
"craco-less": "2.0.0",
"echarts": "4.8.0",
"echarts-for-react": "2.0.16",
"photoswipe": "^4.1.3",
"photoswipe": "^5.3.8",
"qs": "^6.10.3",
"react": "17.0.2",
"react-dom": "17.0.2",
@@ -45,9 +44,9 @@
]
},
"devDependencies": {
"prettier": "^2.8.8",
"husky": "^8.0.3",
"lint-staged": "^13.2.2"
"lint-staged": "^13.2.2",
"prettier": "^2.8.8"
},
"husky": {
"hooks": {
@@ -1,3 +0,0 @@
.widget-image-previewer {
}
+47 -130
View File
@@ -1,90 +1,45 @@
import './ImagePreviewer.less';
import PhotoSwipe from 'photoswipe';
import PhotoSwipeUIDefault from 'photoswipe/dist/photoswipe-ui-default';
//PhotoSwipe的样式
import 'photoswipe/dist/photoswipe.css';
import 'photoswipe/dist/default-skin/default-skin.css';
import 'photoswipe/style.css';
import { UIElementData } from 'photoswipe/dist/types/ui/ui';
/**
* 图片预览器
* 支持预览一张图片或者多张图片
*/
export default class ImagePreviewer {
private static pswpDom(): HTMLElement {
let innerHTML = `
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
static downloadElement: UIElementData = {
name: 'download-button',
order: 8,
isButton: true,
tagName: 'a',
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
// SVG with outline
html: {
isCustomSVG: true,
inner:
'<path d="M20.5 14.3 17.1 18V10h-2.2v7.9l-3.4-3.6L10 16l6 6.1 6-6.1ZM23 23H9v2h14Z" id="pswp__icn-download"/>',
outlineID: 'pswp__icn-download',
},
onInit: (el, pswp) => {
el.setAttribute('download', '');
el.setAttribute('target', '_blank');
el.setAttribute('rel', 'noopener');
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
pswp.on('change', () => {
(el as HTMLAnchorElement).href = pswp.currSlide?.data.src!;
});
},
};
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
`;
let div: HTMLElement = document.createElement('div');
div.className = 'pswp';
div.setAttribute('tabIndex', '-1');
div.setAttribute('role', 'dialog');
div.setAttribute('aria-hidden', 'true');
div.innerHTML = innerHTML;
return div;
static getImageSize(
url: string
): Promise<{ width?: number; height?: number }> {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve({ width: img.width, height: img.height });
img.onerror = () => resolve({ width: undefined, height: undefined });
img.src = url;
});
}
//展示一张图片
@@ -92,61 +47,23 @@ export default class ImagePreviewer {
ImagePreviewer.showMultiPhoto([url], 0);
}
//展示一系列图片
static showMultiPhoto(urls: string[], index: number = 0) {
let that = this;
let items: PhotoSwipe.Item[] = [];
urls.forEach((url) => {
items.push({
src: url,
w: 0,
h: 0,
});
});
let options = {
closeEl: false,
//不需要历史纪录
history: false,
//不需要全屏按钮
fullscreenEl: false,
//不需要分享按钮
shareEl: false,
//当前从第0张展示。
index: index,
tapToClose: true,
};
//获取dom节点
let div = ImagePreviewer.pswpDom();
//添加到body
document.body.appendChild(div);
let photoSwipe = new PhotoSwipe(div, PhotoSwipeUIDefault, items, options);
photoSwipe.listen(
'gettingData',
function (index: number, item: PhotoSwipe.Item) {
if (!item.w || !item.h || item.w < 1 || item.h < 1) {
//这里为了获取图片真实大小
const img: HTMLImageElement = new Image();
img.onload = function () {
item.w = img.width;
item.h = img.height;
photoSwipe.updateSize(true); // reinit Items
};
img.src = item.src!;
}
}
static async showMultiPhoto(urls: string[], index: number = 0) {
const sizes = await Promise.all(
urls.map((url) => ImagePreviewer.getImageSize(url))
);
photoSwipe.init();
photoSwipe.listen('close', () => {
if (div.parentNode) {
//移除节点
div.parentNode.removeChild(div);
}
const pswp = new PhotoSwipe({
dataSource: urls.map((url, index) => ({
src: url,
width: sizes[index].width,
height: sizes[index].height,
})),
index,
});
photoSwipe.listen('afterChange', () => {});
pswp.on('uiRegister', () => {
pswp.ui?.registerElement(ImagePreviewer.downloadElement);
});
pswp.init();
}
}
@@ -1,4 +1,3 @@
import './ImagePreviewer.less';
import MimeUtil from '../../../common/util/MimeUtil';
import MessageBoxUtil from '../../../common/util/MessageBoxUtil';
import Moon from '../../../common/model/global/Moon';
+4 -9
View File
@@ -1859,11 +1859,6 @@
resolved "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/photoswipe@^4.1.2":
version "4.1.2"
resolved "https://registry.npmmirror.com/@types/photoswipe/-/photoswipe-4.1.2.tgz#3ddafb668bf6800f8dfab5bea2ba82dda879cd84"
integrity sha512-HA9TtCAQKToldgxRiyJ1DbsElg/cQV/SQ8COVjqIqghjy60Zxfh78E1WiFotthquqkS86nz13Za9wEbToe0svQ==
"@types/prettier@^2.1.5":
version "2.4.4"
resolved "https://registry.npmmirror.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17"
@@ -6766,10 +6761,10 @@ performance-now@^2.1.0:
resolved "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
photoswipe@^4.1.3:
version "4.1.3"
resolved "https://registry.npmmirror.com/photoswipe/-/photoswipe-4.1.3.tgz#59f49494eeb9ddab5888d03392926a19bc197550"
integrity sha512-89Z43IRUyw7ycTolo+AaiDn3W1EEIfox54hERmm9bI12IB9cvRfHSHez3XhAyU8XW2EAFrC+2sKMhh7SJwn0bA==
photoswipe@^5.3.8:
version "5.3.8"
resolved "https://registry.npmmirror.com/photoswipe/-/photoswipe-5.3.8.tgz#bea7db18e79383833f85c005b833da2029f0daee"
integrity sha512-4vTzOQt8GP4Chsm0s+8j2xDtVHAEN252PxrU12A1zXauNn0zD5HRHgjALKO2GKTyBnTnOrJUOxbV8LTrFIMrYw==
picocolors@^0.2.1:
version "0.2.1"