|
|
<!DOCTYPE html>
|
|
|
<html lang="">
|
|
|
|
|
|
<head>
|
|
|
<meta charset="utf-8">
|
|
|
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
|
|
|
<meta name=viewport content="width=device-width,initial-scale=1">
|
|
|
<link rel="icon" href="https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/favicon.png">
|
|
|
<title>无需上传文件的多功能图片批量处理程序v3.0 (webp2jpg)-Multi-function picture batch processing v3.0 No need to upload files --Traitement par
|
|
|
lots d'images multifonctions Pas besoin de télécharger des fichiers - Procesamiento por lotes de imágenes
|
|
|
multifunción No es necesario cargar archivos-多機能画像バッチ処理v3.0 ファイルをアップロードする必要はありません</title>
|
|
|
<meta name=description
|
|
|
content="在线多功能图片批量处理程序(webp2jpg),无需上传文件,可转换格式psd转jpg、webp转jpg、png无损压缩、svg压缩、heic转jpg、heif转jpg、tiff转jpg、hdr转jpg、png转jpg、psd转png、gif转webp,指出输入psd、psb、hdr、heic、heif、tiff、tif、bmp、tga、xcf、miff、dcm、xpm、pcx、fits、ppm、pgm、pfm、mng、dds、otb,可批量添加图片水印和文字水印、批量调整图片的宽度和高度、旋转图片、翻转图片、修剪图片、批量图片重命名">
|
|
|
<meta name=author content=renzhezhilu,https://github.com/renzhezhilu/webp2jpg-online>
|
|
|
<meta name=keywords
|
|
|
content="webp2jpg,psd转jpg,webp转jpg,png无损压缩,svg压缩,heic转jpg,heif转jpg,tiff转jpg,hdr转jpg,png转jpg,psd转png,批量添加图片水印,批量添加文字水印,批量调整图片尺寸,批量旋转图片,批量翻转图片,批量,修剪图片,批量图片重命名">
|
|
|
<meta name=apple-mobile-web-app-capable content=yes>
|
|
|
<meta name=apple-mobile-web-app-status-bar-style content=black-translucent>
|
|
|
<meta name=format-detection content="telephone=no, email=no">
|
|
|
<meta name=HandheldFriendly content=true>
|
|
|
<meta name=MobileOptimized content=320>
|
|
|
<meta property=og:site_name content="无需上传文件的多功能图片批量处理程序">
|
|
|
<meta property=og:title
|
|
|
content="无需上传文件的多功能图片批量处理程序,-Multi-function picture batch processing v3.0 No need to upload files">
|
|
|
<meta property=og:description
|
|
|
content="可转换格式psd转jpg、webp转jpg、png无损压缩、svg压缩、heic转jpg、heif转jpg、tiff转jpg、hdr转jpg、png转jpg、psd转png、gif转webp,指出输入psd、psb、hdr、heic、heif、tiff、tif、bmp、tga、xcf、miff、dcm、xpm、pcx、fits、ppm、pgm、pfm、mng、dds、otb,可批量添加图片水印和文字水印、批量调整图片的宽度和高度、旋转图片、翻转图片、修剪图片、批量图片重命名">
|
|
|
<meta property=og:image content=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/webp2jpg_v3_ui.jpg>
|
|
|
<meta property=og:url content=https://renzhezhilu.github.io/webp2jpg-online />
|
|
|
<meta property=og:type content=article>
|
|
|
<link rel=apple-touch-icon href=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/favicon.png>
|
|
|
<link rel="shortcut icon" href=https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/favicon.png>
|
|
|
<script>
|
|
|
|
|
|
|
|
|
var idbKeyval = function (t) {
|
|
|
"use strict";
|
|
|
|
|
|
function e(t) {
|
|
|
return new Promise(((e, n) => {
|
|
|
t.oncomplete = t.onsuccess = () => e(t.result), t.onabort = t.onerror = () => n(t.error)
|
|
|
}))
|
|
|
}
|
|
|
|
|
|
function n(t, n) {
|
|
|
const r = indexedDB.open(t);
|
|
|
r.onupgradeneeded = () => r.result.createObjectStore(n);
|
|
|
const o = e(r);
|
|
|
return (t, e) => o.then((r => e(r.transaction(n, t).objectStore(n))))
|
|
|
}
|
|
|
let r;
|
|
|
|
|
|
function o() {
|
|
|
return r || (r = n("keyval-store", "keyval")), r
|
|
|
}
|
|
|
|
|
|
function u(t, n) {
|
|
|
return t("readonly", (t => (t.openCursor().onsuccess = function () {
|
|
|
this.result && (n(this.result), this.result.continue())
|
|
|
}, e(t.transaction))))
|
|
|
}
|
|
|
return t.clear = function (t = o()) {
|
|
|
return t("readwrite", (t => (t.clear(), e(t.transaction))))
|
|
|
}, t.createStore = n, t.del = function (t, n = o()) {
|
|
|
return n("readwrite", (n => (n.delete(t), e(n.transaction))))
|
|
|
}, t.entries = function (t = o()) {
|
|
|
const e = [];
|
|
|
return u(t, (t => e.push([t.key, t.value]))).then((() => e))
|
|
|
}, t.get = function (t, n = o()) {
|
|
|
return n("readonly", (n => e(n.get(t))))
|
|
|
}, t.getMany = function (t, n = o()) {
|
|
|
return n("readonly", (n => Promise.all(t.map((t => e(n.get(t)))))))
|
|
|
}, t.keys = function (t = o()) {
|
|
|
const e = [];
|
|
|
return u(t, (t => e.push(t.key))).then((() => e))
|
|
|
}, t.promisifyRequest = e, t.set = function (t, n, r = o()) {
|
|
|
return r("readwrite", (r => (r.put(n, t), e(r.transaction))))
|
|
|
}, t.setMany = function (t, n = o()) {
|
|
|
return n("readwrite", (n => (t.forEach((t => n.put(t[1], t[0]))), e(n.transaction))))
|
|
|
}, t.update = function (t, n, r = o()) {
|
|
|
return r("readwrite", (r => new Promise(((o, u) => {
|
|
|
r.get(t).onsuccess = function () {
|
|
|
try {
|
|
|
r.put(n(this.result), t), o(e(r.transaction))
|
|
|
} catch (t) {
|
|
|
u(t)
|
|
|
}
|
|
|
}
|
|
|
}))))
|
|
|
}, t.values = function (t = o()) {
|
|
|
const e = [];
|
|
|
return u(t, (t => e.push(t.value))).then((() => e))
|
|
|
}, t
|
|
|
}({});
|
|
|
</script>
|
|
|
<style>
|
|
|
* {
|
|
|
padding: 0;
|
|
|
margin: 0;
|
|
|
}
|
|
|
|
|
|
body {
|
|
|
background-color: #202223;
|
|
|
}
|
|
|
|
|
|
.loadPage {
|
|
|
position: fixed;
|
|
|
z-index: 9999;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
left: 0;
|
|
|
top: 0;
|
|
|
background-color: #202223;
|
|
|
display: none;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
flex-direction: column;
|
|
|
color: #2eb5de
|
|
|
}
|
|
|
|
|
|
.loadPage .p {
|
|
|
width: 100%;
|
|
|
max-width: 500px;
|
|
|
height: 10px;
|
|
|
background-color: #2d2f31;
|
|
|
overflow: hidden;
|
|
|
border-radius: 6px;
|
|
|
margin: 30px 0 10px 0
|
|
|
}
|
|
|
|
|
|
.loadPage .p div {
|
|
|
height: 100%;
|
|
|
width: 30%;
|
|
|
background-color: #37d1c8;
|
|
|
background-image: linear-gradient(-34deg, #2eb5de 0%, #37d1c8 100%);
|
|
|
}
|
|
|
|
|
|
.loadPage h2 {
|
|
|
font-size: 70px;
|
|
|
line-height: 90px;
|
|
|
}
|
|
|
|
|
|
.loadPage h3 {
|
|
|
color: #7b7e80;
|
|
|
font-size: 20px;
|
|
|
}
|
|
|
.app_html{
|
|
|
display: none;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
<div class="loadPage">
|
|
|
<h2>1%</h2>
|
|
|
<div class="p">
|
|
|
<div></div>
|
|
|
</div>
|
|
|
<h3>LOADING...</h3><a target="_blank" href="https://imagestool.com/">v4.0 -></a>
|
|
|
|
|
|
</div>
|
|
|
<noscript><strong>We're sorry but vue_2 doesn't work properly without JavaScript enabled. Please enable it
|
|
|
to continue.</strong></noscript>
|
|
|
<div id="app"></div>
|
|
|
|
|
|
<div class="app_html" >
|
|
|
<div class="dark"><div class="batchTool"><header><div class="l1"><div class="layout_max_width"><div class="logo"><img src="favicon.png" width="24" alt="" style="margin-right: 7px;"><h1>多功能图片批处理 v3.0</h1><p>无需上传文件</p><iframe src="https://img.shields.io/github/stars/renzhezhilu/webp2jpg-online.svg?style=social&label=Star" frameborder="0" width="86px" height="22px"></iframe><a target="_blank" href="/v2.html"> v2.2</a></div><nav class="other"><div title="" class="item red_text"><i class="iconfont icon-coffee"></i><span style="font-size: 14px;"> 打赏 </span></div><div class="hr_y"></div><div title="" class="item"><i class="iconfont icon-share-variant"></i></div><div class="hr_y"></div><div title="" class="moreTool item"><i class="iconfont icon-qrcode-scan" style="padding-right: 4px;"></i><div class="allTool language"><div class="con" style="width: 270px;"><img src="" alt=""> url: <br> 用手机二维码扫描打开 </div></div></div><div class="hr_y"></div><div title="" class="item"><i class="iconfont icon-white-balance-sunny"></i></div><div class="hr_y"></div><div title="" class="moreTool item"><i class="iconfont icon-web" style="padding-right: 4px;"></i><div class="allTool language"><div class="con"><ul><li class=""><div class="text"> English </div></li><li class=""><div class="text"> français </div></li><li class=""><div class="text"> Español </div></li><li class=""><div class="text"> português </div></li><li class=""><div class="text"> Deutsche </div></li><li class=""><div class="text"> italiano </div></li><li class=""><div class="text"> русский </div></li><li class="on"><div class="text"> 中文-简体 </div></li><li class=""><div class="text"> 中文-繁體 </div></li><li class=""><div class="text"> 日本語 </div></li><li class=""><div class="text"> 한국어 </div></li><li class=""><div class="text"> Tiếng Việt </div></li><li class=""><div class="text"> ไทย </div></li><li class=""><div class="text"> Bahasa Melayu </div></li><li class=""><div class="text"> हिंदी </div></li><li class=""><div class="text"> عربى </div></li><li class=""><div class="text"> bahasa Indonesia </div></li><li class=""><div class="text"> বাংলা </div></li><li class=""><div class="text"> اردو </div></li><li class=""><div class="text"> Kiswahili </div></li><li class=""><div class="text"> Esperanto </div></li></ul></div></div></div><!----></nav><!----></div></div></header><!----><div class="layout_max_width layout_max_width_batch"><div class="configSwitch "><i class="iconfont icon-reorder-horizontal hideConfig"></i><div><h5 class="configSwitch_tit"><span> 配置 </span><i class="iconfont icon-reorder-horizontal hideConfig"></i></h5><ul><li><span class="open"><i class="iconfont icon-repeat"></i><b>格式</b></span><button class="switchBut isOpen disabled strong"><div class="after"></div></button></li><li><span class=""><i class="iconfont icon-move-resize-variant"></i><b>尺寸</b></span><button class="switchBut strong"><div class="after"></div></button></li><li><span class=""><i class="iconfont icon-rotate-right-variant"></i><b>变换</b></span><button class="switchBut strong"><div class="after"></div></button></li><li><span class=""><i class="iconfont icon-format-wrap-inline"></i><b>水印</b></span><button class="switchBut strong"><div class="after"></div></button></li><li><span class=""><i class="iconfont icon-crop"></i><b>修剪</b></span><button class="switchBut strong"><div class="after"></div></button></li><li><span class="open"><i class="iconfont icon-rename-box"></i><b> 重命名</b></span><button class="switchBut isOpen strong"><div class="after"></div></button></li><li><span class="open"><i class="iconfont icon-download"></i><b>下载</b></span><button class="switchBut isOpen strong"><div class="after"></div></button></li></ul><div class="hr"></div><!----><!----><ul><li><span class="open"><i class="iconfont icon-settings"></i><b>设置</b></span><i class="iconfont icon-chevron-right"></i></li></ul></div></div><div class="midMain "><div class="configMore "><div class="cBox" style="z-index: 20;"><p> 格式 </p><div class="conBox"><div class="formBox"><h5> 格式 </h5><div class="con"><div class="selectGroup selectGroupFormat" style="width: 190px; z-index: 20; margin-right: 22px;"><div class="mini"><button class="button current"><b> jpg-tiny </b><div class="more" style="right: 6px;"><i class="iconfont icon-chevron-down"></i></div></button><div class="moreBox"><ul><li><b class="var_color ">jpg</b><p> 普通jpg </p></li><li><b class="var_color ">webp</b><p> 静态webp </p></li><li><b class="var_color ">gif</b><p> 静态gif </p></li><li><b class="var_color ">png</b><p> 无损png </p></li><li><b class="var_color ">jpg-tiny</b><p> 压缩率更好的 Jpg </p></li><li><b class="var_color ">png-tiny</b><p> 压缩png,减少40%以上 </p></li><li><b class="var_color ">svg-tiny</b><p> svg 压缩,只支持输入svg </p></li><li><b class="var_color ">webp-animation <span>beta</span></b><p> 支持webp、gif、apng动画 </p></li><li><b class="var_color ">gif-animation <span>beta</span></b><p> 支持webp、gif、apng动画 </p></li><li><b class="var_color ">ico</b><p> 网站图标 </p></li><li><b class="var_color ">avif</b><p> 极限压缩率,支持alpha </p></li></ul></div></div></div></div></div><!----><div class="formBox" style="margin-left: 0px;"><h5> 品质 </h5><div class="con"><div class="vue-slider vue-slider-ltr" style="padding: 7px 0px; width: 150px; height: 3px; margin-right: 16px; flex-shrink: 0;"><div class="vue-slider-rail"><div class="vue-slider-process" style="height: 100%; top: 0px; left: 0%; width: 79.798%; transition-property: width, left; transition-duration: 0.5s;"></div><div aria-valuetext="80" class="vue-slider-dot" role="slider" aria-valuenow="80" aria-valuemin="1" aria-valuemax="100" aria-orientation="horizontal" tabindex="0" style="width: 14px; height: 14px; transform: translate(-50%, -50%); top: 50%; left: 79.798%; transition: left 0.5s ease 0s;"><div class="vue-slider-dot-handle"></div></div></div></div> 80% </div></div><!----><!----><!----><div style="width: 100%;"></div><!----><!----><div style="width: 100%;"></div><!----><!----></div></div><!----><!----><!----><!----><div class="cBox" style="z-index: 15;"><p> 重命名 </p><div class="conBox" style="z-index: 19;"><div class="formBox" style="margin-left: 0px;"><h5> 分隔符 </h5><div class="con"><button class="switchBut isOpen strong"><div class="after"></div></button></div></div><div style="width: 100%;"></div><p> 未加入 </p><div style="width: 100%;"></div><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> Original name <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> Number++ <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> date <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> time <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> width&height <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> File size <!----><!----></button><button class="vue-button normal" style="margin: 0px 6px 6px 0px; min-width: 140px; justify-content: start;"><i class="iconfont icon-plus-circle"></i> Any <!----><!----></button><div style="width: 100%;"></div><p> 加入 </p><div style="width: 100%;"></div><button class="vue-button strong" style="margin: 0px 6px 6px 0px;"> date <i class="iconfont icon-close" style="opacity: 0.3; padding-right: 0px;"></i><!----><!----></button><button class="vue-button strong" style="margin: 0px 6px 6px 0px;"> Number++ <i class="iconfont icon-close" style="opacity: 0.3; padding-right: 0px;"></i><!----><!----></button><button class="vue-button strong" style="margin: 0px 6px 6px 0px;"> File size <i class="iconfont icon-close" style="opacity: 0.3; padding-right: 0px;"></i><!----><!----></button><div style="width: 100%;"></div><p> 预览 </p><div style="width: 100%;"></div><h4>2021-08-08_1_300Kb.jpg</h4><div style="width: 100%;"></div></div></div><div class="cBox" style="z-index: 14;"><p> 下载 </p><div class="conBox" style="z-index: 19;"><div class="formBox" style="margin-right: 22px;"><h5> 自动下载 </h5><div class="con"><button class="switchBut isOpen strong"><div class="after"></div></button></div></div><div class="formBox" style="margin-right: 0px;"><h5> 下载 模式 </h5><div class="con"><button class="vue-button strong" style="margin-right: 12px;"> zip </button><button class="vue-button"> 逐个下载 </button></div></div><div style="width: 100%;"></div></div></div><div class="endHeight"></div></div><div class="imageView "><input accept=".jpeg,.jpg,.png,.gif,.webp,.svg,.ico,.bmp,.avif,.psd,.hdr,.tiff,.tif,.psb,.bmp,.tga,.xcf,.miff,.dcm,.xpm,.pcx,.fits,.ppm,.pgm,.pfm,.mng,.dds,.otb,.heic,.heif" id="photoHub_file" type="file" value="" multiple="multiple" style="display: none;"><!----><div class="ready"><label for="photoHub_file"><i class="iconfont icon-image-filter-hdr"><small>+</small></i><p><strong class="var_color"> 拖入或选择图像 or Ctrl+V </strong></p><p class="p2"><span style="display: block;"> 支持输入格式 </span><ul><li><i class="iconfont icon-check"></i> jpg </li><li><i class="iconfont icon-check"></i> png </li><li><i class="iconfont icon-check"></i> webp </li><li><i class="iconfont icon-check"></i> gif </li><li><i class="iconfont icon-check"></i> psd/psb </li><li><i class="iconfont icon-check"></i> heic/heif </li><li><i class="iconfont icon-check"></i> avif </li><li><i class="iconfont icon-check"></i> svg </li><li><i class="iconfont icon-check"></i> ico </li><li><i class="iconfont icon-check"></i> bmp </li><li><i class="iconfont icon-check"></i> hdr </li><li><i class="iconfont icon-check"></i> tif/tiff </li><div data-v-7ad4a9ed="" class="tip"><li data-v-7ad4a9ed=""><i data-v-7ad4a9ed="" class="iconfont icon-more"></i> 更多 </li><div data-v-7ad4a9ed="" class="arrow top">tga , xcf , miff , dcm , xpm , pcx , fits , ppm , pgm ,pfm , mng , dds , otb</div></div></ul></p><p class="p2"><span>推荐文件总数:</span><b> < 1000</b><br><span>推荐文件大小:</span><b> < 20Mb</b></p></label></div></div></div><!----></div><!----><!----><!----><!----><div style="display: none;"><canvas id="fabricjsDocCn"></canvas></div><!----></div></div>
|
|
|
</div>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|
|
|
<script>
|
|
|
window.CACHE_VERSION = '3.2.2'
|
|
|
window.CACHE_LIST = {}
|
|
|
window.CACHE_FN = _ => {
|
|
|
let cdnList = [{
|
|
|
name: 'app.js',
|
|
|
url: ['js/app_v3.2.1.js']
|
|
|
}, {
|
|
|
name: 'avif_enc_worker_all_in.js',
|
|
|
url: ['js/avif_enc_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'imagequant_worker_all_in.js',
|
|
|
url: ['js/imagequant_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'squoosh_oxipng_worker_all_in.js',
|
|
|
url: ['js/squoosh_oxipng_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'mozjpeg_enc_worker_all_in.js',
|
|
|
url: ['js/mozjpeg_enc_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'svgo_worker_all_in.js',
|
|
|
url: ['js/svgo_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'wasm-im_worker_all_in.js',
|
|
|
url: ['js/wasm-im_worker_all_in.js']
|
|
|
}, {
|
|
|
name: 'logo.png',
|
|
|
url: ['images/logo.png']
|
|
|
}, {
|
|
|
name: '1920x1080.jpg',
|
|
|
url: ['images/1920x1080.jpg']
|
|
|
}, {
|
|
|
name: '750x1350.jpg',
|
|
|
url: ['images/750x1350.jpg']
|
|
|
}, {
|
|
|
name: '500x500.jpg',
|
|
|
url: ['images/500x500.jpg']
|
|
|
},
|
|
|
//
|
|
|
{
|
|
|
name: 'magickApi.js',
|
|
|
url: ['js/magick/magickApi.js']
|
|
|
},
|
|
|
{
|
|
|
name: 'magick.js',
|
|
|
url: ['js/magick/magick.js']
|
|
|
}
|
|
|
]
|
|
|
// let cdnList = [{
|
|
|
// name: 'avif_enc_worker_all_in.js',
|
|
|
// url: ['./cache/js/avif_enc_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'imagequant_worker_all_in.js',
|
|
|
// url: ['./cache/js/imagequant_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'squoosh_oxipng_worker_all_in.js',
|
|
|
// url: ['./cache/js/squoosh_oxipng_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'mozjpeg_enc_worker_all_in.js',
|
|
|
// url: ['./cache/js/mozjpeg_enc_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'svgo_worker_all_in.js',
|
|
|
// url: ['./cache/js/svgo_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'wasm-im_worker_all_in.js',
|
|
|
// url: ['./cache/js/wasm-im_worker_all_in.js']
|
|
|
// }, {
|
|
|
// name: 'logo.png',
|
|
|
// url: ['./cache/images/logo.png']
|
|
|
// }, {
|
|
|
// name: '1920x1080.jpg',
|
|
|
// url: ['./cache/images/1920x1080.jpg']
|
|
|
// }, {
|
|
|
// name: '750x1350.jpg',
|
|
|
// url: ['./cache/images/750x1350.jpg']
|
|
|
// }, {
|
|
|
// name: '500x500.jpg',
|
|
|
// url: ['./cache/images/500x500.jpg']
|
|
|
// },
|
|
|
// //
|
|
|
// {
|
|
|
// name: 'magickApi.js',
|
|
|
// url: ['./cache/js/magick/magickApi.js']
|
|
|
// },
|
|
|
// {
|
|
|
// name: 'magick.js',
|
|
|
// url: ['./cache/js/magick/magick.js']
|
|
|
// }
|
|
|
// ]
|
|
|
|
|
|
cdnList = cdnList.map(m => {
|
|
|
// m.url = ['./cdn/v3.0/' + m.url[0]]
|
|
|
m.url = ['https://cdn.jsdelivr.net/gh/renzhezhilu/webp2jpg-online/cdn/v3.0/' + m.url[0]]
|
|
|
|
|
|
// m.url = ['https://cdn-6lo.pages.dev/v3.0/' + m.url[0]]
|
|
|
return m
|
|
|
})
|
|
|
|
|
|
|
|
|
function creatScript(src, name) {
|
|
|
let body = document.querySelector('body')
|
|
|
let script = document.createElement('script')
|
|
|
script.src = src
|
|
|
script.className = name
|
|
|
body.appendChild(script)
|
|
|
}
|
|
|
|
|
|
|
|
|
start(0)
|
|
|
async function start(num) {
|
|
|
if (num > 2) return
|
|
|
let ver = await idbKeyval.get('CACHE_VERSION')
|
|
|
let blobList = await idbKeyval.get('CACHE_LIST')
|
|
|
// 重新请求
|
|
|
if (!ver || ver !== window.CACHE_VERSION || !blobList) {
|
|
|
// await idbKeyval.clear()
|
|
|
let retList = await getCdnList(cdnList)
|
|
|
await idbKeyval.set('CACHE_LIST', retList)
|
|
|
}
|
|
|
blobList = await idbKeyval.get('CACHE_LIST')
|
|
|
let errorList = blobList.some(f => !f.blob || !f.name)
|
|
|
if (errorList) {
|
|
|
alert('错误')
|
|
|
await idbKeyval.del('CACHE_VERSION')
|
|
|
start(num + 1)
|
|
|
return
|
|
|
}
|
|
|
blobList.map(m => {
|
|
|
window.CACHE_LIST[m.name] = URL.createObjectURL(m.blob)
|
|
|
})
|
|
|
await idbKeyval.set('CACHE_VERSION', window.CACHE_VERSION)
|
|
|
creatScript(window.CACHE_LIST['app.js'], 'appJs')
|
|
|
// console.log('window.CACHE_LIST', window.CACHE_LIST);
|
|
|
// console.log('blobList', blobList);
|
|
|
// console.log(window.CACHE_LIST['magickApi.js']);
|
|
|
import(window.CACHE_LIST['magickApi.js'])
|
|
|
.then(module => {
|
|
|
Window.Magick = module
|
|
|
console.log(Window.Magick);
|
|
|
})
|
|
|
.catch(err => {
|
|
|
console.log(err);
|
|
|
});
|
|
|
console.log('加载完成✅', );
|
|
|
|
|
|
|
|
|
}
|
|
|
async function getCdnList(cdnList) {
|
|
|
let time = new Date().getTime()
|
|
|
let retList = []
|
|
|
document.querySelector('.loadPage').style.display = 'flex'
|
|
|
for (let index = 0; index < cdnList.length; index++) {
|
|
|
const cdn = cdnList[index];
|
|
|
// end
|
|
|
// await new Promise(_ => setTimeout(() => _(), 300))
|
|
|
let file = await fetchFile(cdn.url)
|
|
|
if (!file) {
|
|
|
file = {
|
|
|
name: null,
|
|
|
blob: null
|
|
|
}
|
|
|
console.error('GET ERRPR!', file);
|
|
|
}
|
|
|
retList.push({
|
|
|
name: cdn.name,
|
|
|
blob: file.blob
|
|
|
})
|
|
|
// console.log(cdn.name);
|
|
|
// if(cdn.name==='app.js'){
|
|
|
// creatScript(window.CACHE_LIST['app.js'],'appJs')
|
|
|
// }
|
|
|
console.log('+', index + 1)
|
|
|
let pNum = ((index + 1) / cdnList.length * 100).toFixed(0) + '%'
|
|
|
document.querySelector('.loadPage h2').textContent = pNum
|
|
|
document.querySelector('.loadPage .p div').style.width = pNum
|
|
|
}
|
|
|
// await idbKeyval.set('cdnList', retList)
|
|
|
time = new Date().getTime() - time
|
|
|
time = (time / 1000).toFixed(2)
|
|
|
console.log('缓存完成!', time);
|
|
|
document.querySelector('.loadPage').style.display = 'none'
|
|
|
|
|
|
return retList
|
|
|
|
|
|
}
|
|
|
async function fetchFile(url = []) {
|
|
|
return new Promise(async (res, rej) => {
|
|
|
let blob;
|
|
|
for (let index = 0; index < url.length; index++) {
|
|
|
const element = url[index];
|
|
|
blob = await fetch(element)
|
|
|
.then(d => {
|
|
|
if (d.status === 200) return d.blob()
|
|
|
else return null
|
|
|
})
|
|
|
.catch(e => {
|
|
|
console.log(e);
|
|
|
return null
|
|
|
})
|
|
|
if (blob) {
|
|
|
res({
|
|
|
blob,
|
|
|
index,
|
|
|
element
|
|
|
})
|
|
|
break
|
|
|
} else {
|
|
|
console.error('ERROR URL:', element);
|
|
|
}
|
|
|
}
|
|
|
if (!blob) res(null)
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
window.CACHE_FN()
|
|
|
</script> |