Initial commit

This commit is contained in:
RainSun 2021-01-06 22:55:14 +08:00
parent 94c9abcab6
commit 1631b40672
64 changed files with 1364 additions and 108 deletions

1
.gitignore vendored
View File

@ -1,6 +1,5 @@
.DS_Store
node_modules
/dist
# local env files

38
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,38 @@
stages:
- build
- clear
- deploy
build:
stage: build
image: docker:latest
services:
- name: docker:dind
tags:
- dockerbase
script:
- ls -a
- docker build -t lacus/imgzip .
clear:
stage: clear
tags:
- dockerbase
only:
- master
script:
- docker stop lacus/imgzip
- docker rm lacus/imgzip
allow_failure: true
deploy:
stage: deploy
tags:
- dockerbase
only:
- master
script:
- ls -a
- docker run -d --name imgzip -p 127.0.0.1:5004:80 lacus/imgzip
cache:
policy: pull

1
dist/css/app.faddee12.css vendored Normal file
View File

@ -0,0 +1 @@
blockquote,body,button,dd,dl,dt,fieldset,form,h1,h2,h3,h4,h5,h6,hr,input,legend,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0}body,button,input,select,textarea{font:12px/1.5tahoma,arial,\5b8b\4f53}h1,h2,h3,h4,h5,h6{font-size:100%}address,cite,dfn,em,var{font-style:normal}code,kbd,pre,samp{font-family:couriernew,courier,monospace}small{font-size:12px}ol,ul{list-style:none}a{text-decoration:none}a:hover{text-decoration:underline}sup{vertical-align:text-top}sub{vertical-align:text-bottom}legend{color:#000}fieldset,img{border:0}button,input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}button{margin:0;padding:0;background:none;border:none;outline:none}#app{font-family:Roboto,Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;z-index:-99;top:0;left:0;width:100%;height:100%;min-height:100%;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.cropper-box[data-v-a7e6d032]{flex:1;width:100%;margin-top:2rem}.cropper-box .cropper[data-v-a7e6d032]{width:auto;height:300px}footer[data-v-a7e6d032]{padding:.5rem;box-sizing:border-box}footer .scope-btn[data-v-a7e6d032]{margin-top:.5rem;display:flex;justify-content:space-between}footer .scope-btn .btn[data-v-a7e6d032]{outline:none;display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;-webkit-appearance:none;text-align:center;box-sizing:border-box;outline:0;transition:.1s;padding:.2rem .4rem;font-size:.3rem;border-radius:3px;color:#fff;background-color:#409eff;border-color:#409eff}footer .btn-submit[data-v-a7e6d032]{margin-top:1rem;border-radius:1rem;height:1rem;font-size:.4rem;font-weight:400;text-align:center;line-height:1rem;color:#fff;background:linear-gradient(90deg,#3aa5fc,#20d6fa)}.home[data-v-77a1bcfd]{width:100%;max-width:1024px;margin:0 auto;min-height:100vh;position:relative;overflow:hidden;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)!important;background-color:#fff}.home header[data-v-77a1bcfd]{position:fixed;top:0;left:0;width:100%}.home header .warp[data-v-77a1bcfd]{background-color:#fff;width:100%;max-width:1024px;margin:0 auto;height:1.4rem;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)!important;border-bottom:1px solid #f3f3f3}.home header .warp .back[data-v-77a1bcfd]{float:left;margin:.35rem .3rem;height:.7rem;width:.7rem}.home header .warp p[data-v-77a1bcfd]{font-size:.45rem;color:#494e5e;line-height:1.4rem;width:7rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.home .logo-box[data-v-77a1bcfd]{height:3rem;margin-top:1.4rem;display:flex;align-items:center;justify-content:center}.home .logo-box .logo[data-v-77a1bcfd]{height:5rem;width:5rem}.home .logo-box img[data-v-77a1bcfd]{display:block;height:3rem;width:3rem;margin:0 auto}.home .title[data-v-77a1bcfd]{text-align:center;color:#303133;font-size:.6rem}.home .tip-box[data-v-77a1bcfd]{padding:.5rem 1rem;box-sizing:border-box;margin-top:1rem}.home .tip-box .tip-line[data-v-77a1bcfd]{display:flex;align-items:center;justify-content:space-between;font-size:.45rem;margin-bottom:.2rem}.home .tip-box .tip-line .tip-title[data-v-77a1bcfd]{flex:1;color:#c0c4cc}.home .tip-box .tip-line .tip-content[data-v-77a1bcfd]{flex:3;text-align:right;color:#606266}.home .btn-submit[data-v-77a1bcfd]{margin:1.5rem 1rem;margin-top:.5rem;border-radius:1rem;height:1rem;font-size:.4rem;font-weight:400;text-align:center;line-height:1rem;color:#fff;background:linear-gradient(90deg,#3aa5fc,#20d6fa)}.home footer[data-v-77a1bcfd]{position:absolute;bottom:0;left:0;width:100%;padding-bottom:.3rem}.home footer p[data-v-77a1bcfd]{text-align:center;font-size:.25rem;margin-bottom:.2rem;color:#989898}.snake-bar[data-v-6de0334b]{position:fixed;left:0;bottom:-1.2rem;width:100%}.snake-bar .warp[data-v-6de0334b]{width:100%;max-width:1024px;margin:0 auto;height:1.2rem;background:#ebf6ff}.snake-bar .warp .content[data-v-6de0334b]{margin-left:.3rem;padding-left:.3rem;font-size:.35rem;line-height:1.2rem;letter-spacing:2px;color:#249cff}.higher-snake-bar[data-v-6de0334b]{-webkit-animation:snakeToHigh-data-v-6de0334b .5s ease;animation:snakeToHigh-data-v-6de0334b .5s ease;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.lower-snake-bar[data-v-6de0334b]{-webkit-animation:snakeToLow-data-v-6de0334b .5s ease;animation:snakeToLow-data-v-6de0334b .5s ease;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes snakeToHigh-data-v-6de0334b{0%{bottom:-1.2rem}to{bottom:0}}@keyframes snakeToHigh-data-v-6de0334b{0%{bottom:-1.2rem}to{bottom:0}}@-webkit-keyframes snakeToLow-data-v-6de0334b{0%{bottom:0}to{bottom:-1.2rem}}@keyframes snakeToLow-data-v-6de0334b{0%{bottom:0}to{bottom:-1.2rem}}

1
dist/css/chunk-vendors.23c1f75a.css vendored Normal file
View File

@ -0,0 +1 @@
.svg-icon{display:inline-block;fill:currentColor}.svg-icon.flip-horizontal{transform:scaleX(-1)}.svg-icon.flip-vertical{transform:scaleY(-1)}.svg-icon.spin{-webkit-animation:fa-spin 1s linear 0s infinite;animation:fa-spin 1s linear 0s infinite}@-webkit-keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}

BIN
dist/favicon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
dist/img/icons/apple-touch-icon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
dist/img/icons/favicon-16x16.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

BIN
dist/img/icons/favicon-32x32.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
dist/img/icons/mstile-150x150.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

3
dist/img/icons/safari-pinned-tab.svg vendored Normal file
View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B

1
dist/index.html vendored Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><title>imgzip</title><link href="/css/app.faddee12.css" rel="preload" as="style"><link href="/css/chunk-vendors.23c1f75a.css" rel="preload" as="style"><link href="/js/app.6f7c4cba.js" rel="modulepreload" as="script"><link href="/js/chunk-vendors.6458e28e.js" rel="modulepreload" as="script"><link href="/css/chunk-vendors.23c1f75a.css" rel="stylesheet"><link href="/css/app.faddee12.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="imgzip"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but imgzip doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script type="module" src="/js/chunk-vendors.6458e28e.js"></script><script type="module" src="/js/app.6f7c4cba.js"></script><script>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script><script src="/js/chunk-vendors-legacy.2904f938.js" nomodule></script><script src="/js/app-legacy.662e8cf6.js" nomodule></script></body></html>

2
dist/js/app-legacy.662e8cf6.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/app-legacy.662e8cf6.js.map vendored Normal file

File diff suppressed because one or more lines are too long

2
dist/js/app.6f7c4cba.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/app.6f7c4cba.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

19
dist/js/chunk-vendors.6458e28e.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/chunk-vendors.6458e28e.js.map vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/manifest.json vendored Normal file
View File

@ -0,0 +1 @@
{"name":"imgzip","short_name":"imgzip","theme_color":"#4DBA87","icons":[{"src":"./img/icons/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"./img/icons/android-chrome-512x512.png","sizes":"512x512","type":"image/png"},{"src":"./img/icons/android-chrome-maskable-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"./img/icons/android-chrome-maskable-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}],"start_url":".","display":"standalone","background_color":"#000000"}

View File

@ -0,0 +1,26 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "bd5c9abd475c2220214b",
"url": "/css/app.faddee12.css"
},
{
"revision": "092e8f42717f524f5171",
"url": "/css/chunk-vendors.23c1f75a.css"
},
{
"revision": "df079c829049fae6541b25577477ec48",
"url": "/index.html"
},
{
"revision": "bd5c9abd475c2220214b",
"url": "/js/app-legacy.662e8cf6.js"
},
{
"revision": "092e8f42717f524f5171",
"url": "/js/chunk-vendors-legacy.2904f938.js"
},
{
"revision": "a440a1aeebdd46313eb718729537708c",
"url": "/manifest.json"
}
]);

View File

@ -0,0 +1,30 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "f98b7fb1acca69b97ec9",
"url": "/css/app.faddee12.css"
},
{
"revision": "dc7dfa177e02bb82fb74",
"url": "/css/chunk-vendors.23c1f75a.css"
},
{
"revision": "56643affe11940d4e2c126bb2149fa59",
"url": "/index.html"
},
{
"revision": "f98b7fb1acca69b97ec9",
"url": "/js/app.6f7c4cba.js"
},
{
"revision": "dc7dfa177e02bb82fb74",
"url": "/js/chunk-vendors.6458e28e.js"
},
{
"revision": "a440a1aeebdd46313eb718729537708c",
"url": "/manifest.json"
},
{
"revision": "b6216d61c03e6ce0c9aea6ca7808f7ca",
"url": "/robots.txt"
}
]);

2
dist/robots.txt vendored Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow:

34
dist/service-worker.js vendored Normal file
View File

@ -0,0 +1,34 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.d9b7f8b6d0aef6009f6a9553c0379055.js"
);
workbox.core.setCacheNameDetails({prefix: "imgzip"});
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

View File

@ -4,13 +4,17 @@
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
"build": "vue-cli-service build",
"buildsuper": "vue-cli-service build --modern"
},
"dependencies": {
"core-js": "^3.6.5",
"lrz": "^4.9.40",
"register-service-worker": "^1.7.1",
"vue": "^2.6.11",
"vue-cropper": "^0.5.6",
"vue-router": "^3.2.0",
"vue-svg-icon": "^1.2.9",
"vuex": "^3.4.0"
},
"devDependencies": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,3 +1,254 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="283px" height="283px" viewBox="0 0 283 283" enable-background="new 0 0 283 283" xml:space="preserve"> <image id="image0" width="283" height="283" x="0" y="0"
href="data:image/png;base64,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" />
</svg>

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<title>护资照片压缩</title>
</head>
<body>
<noscript>

View File

@ -1,32 +1,129 @@
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
<!-- 缓存 -->
<keep-alive>
<router-view v-if="this.$route.meta.keepAlive"></router-view>
</keep-alive>
<!-- 非缓存 -->
<router-view v-if="!this.$route.meta.keepAlive"></router-view>
</div>
</template>
<style lang="scss">
body,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
p,
blockquote,
dl,
dt,
dd,
ul,
ol,
li,
pre,
form,
fieldset,
legend,
button,
input,
textarea,
th,
td {
margin: 0;
padding: 0;
}
body,
button,
input,
select,
textarea {
font: 12px/1.5tahoma, arial, \5b8b\4f53;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 100%;
}
address,
cite,
dfn,
em,
var {
font-style: normal;
}
code,
kbd,
pre,
samp {
font-family: couriernew, courier, monospace;
}
small {
font-size: 12px;
}
ul,
ol {
list-style: none;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
sup {
vertical-align: text-top;
}
sub {
vertical-align: text-bottom;
}
legend {
color: #000;
}
fieldset,
img {
border: 0;
}
button,
input,
select,
textarea {
font-size: 100%;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
button {
margin: 0;
padding: 0;
background: none;
border: none;
outline: none;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
font-family: "Roboto", "Helvetica Neue", Helvetica, "PingFang SC",
"Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
position: absolute;
z-index: -99;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 100%;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
</style>

BIN
src/assets/cherry.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,206 @@
<template>
<div class="cropper-box">
<div class="cropper">
<vue-cropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
:outputType="option.outputType"
:info="option.info"
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:full="option.full"
:fixedBox="option.fixedBox"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:height="option.height"
:infoTrue="option.infoTrue"
:maxImgSize="option.maxImgSize"
:enlarge="option.enlarge"
:mode="option.mode"
@realTime="realTime"
@imgLoad="imgLoad"
>
</vue-cropper>
</div>
<!--底部操作工具按钮-->
<footer>
<div class="scope-btn">
<div class="btn" @click="changeScale(1)">放大</div>
<div class="btn" @click="changeScale(-1)">缩小</div>
<div class="btn" @click="rotateLeft"> 左旋转</div>
<div class="btn" @click="rotateRight"> 右旋转</div>
</div>
<div class="upload-btn">
<div class="btn-submit" @click="donwloadImg()">压缩图片并下载</div>
</div>
</footer>
</div>
</template>
<script>
import { VueCropper } from "vue-cropper";
import "lrz";
export default {
name: "CropperImage",
components: {
VueCropper,
},
props: ["img"],
data() {
return {
previews: {},
option: {
img: this.img, //
outputSize: 1, //(0.1 - 1)
outputType: "png", //jpeg || png || webp
info: false, //
canScale: true, //
autoCrop: true, //
autoCropWidth: 200, //
autoCropHeight: 280, //
fixed: true, //
fixedNumber: [5, 7], //
full: false, //false
fixedBox: false, //
canMove: false, //
canMoveBox: true, //
original: false, //
centerBox: true, //
height: true, //dpr
infoTrue: false, //truefalse
maxImgSize: 3000, //
enlarge: 1, //
mode: "200px 280px", //
},
};
},
methods: {
//
imgLoad(msg) {
console.log("工具初始化函数=====" + msg);
},
//
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
//
rotateRight() {
this.$refs.cropper.rotateRight();
},
//
realTime(data) {
this.previews = data;
},
//
zipImg(data, width, height) {
return new Promise((resolve) => {
//
const img = new Image();
// base64
img.src = data;
img.onload = () => {
const canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
// canvas
ctx.drawImage(img, 0, 0, width, height);
const res = canvas.toDataURL("image/png");
console.log(res.length / 1024 / 1024);
if (res.length / 1024 / 1024 > 0.1) {
console.log(1, width, height);
resolve(this.zipImg(data, width * 0.9, height * 0.9));
} else {
console.log(2, width, height);
resolve(res);
}
};
});
},
//
donwloadImg() {
//base64
this.$refs.cropper.getCropData(async (data) => {
this.zipImg(data, 295, 413).then((res) => {
console.log(res.length / 1024 / 1024);
const a = document.createElement("a");
a.href = res; //
a.download = "护士执业资格考试.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
});
},
selectImg() {
this.$refs.upload.click();
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.cropper-box {
flex: 1;
width: 100%;
margin-top: 2rem;
.cropper {
width: auto;
height: 300px;
}
}
footer {
padding: 0.5rem;
box-sizing: border-box;
.scope-btn {
margin-top: 0.5rem;
display: flex;
justify-content: space-between;
.btn {
outline: none;
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
-webkit-appearance: none;
text-align: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
-webkit-transition: 0.1s;
transition: 0.1s;
padding: 0.2rem 0.4rem;
font-size: 0.3rem;
border-radius: 3px;
color: #fff;
background-color: #409eff;
border-color: #409eff;
}
}
.btn-submit {
margin-top: 1rem;
border-radius: 1rem;
height: 1rem;
font-size: 0.4rem;
font-weight: 400;
text-align: center;
line-height: 1rem;
color: #fff;
background: linear-gradient(to right, #3aa5fc, #20d6fa);
}
}
</style>

View File

@ -1,60 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa" target="_blank" rel="noopener">pwa</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

136
src/components/Logo.vue Normal file
View File

@ -0,0 +1,136 @@
<template>
<!--Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)-->
<svg
version="1.1"
id="图层_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 200 200"
enable-background="new 0 0 200 200"
xml:space="preserve"
>
<!-- <image display="none" overflow="visible" width="389" height="292" xlink:href="E40720C9.png" transform="matrix(0.24 0 0 0.24 53 65)"/> -->
<path
:fill="stroke"
id="左耳"
d="M68.2,87.3h19.2l-6.7-13.8c0,0-0.3-1.5-2.8-1.5c-2.6,0-2.8,1.3-2.8,1.3L68.2,87.3z"
/>
<path
:fill="stroke"
id="右耳"
d="M111.2,87.6h19.2l-6.7-13.8c0,0-0.3-1.5-2.8-1.5c-2.6,0-2.8,1.3-2.8,1.3L111.2,87.6z"
/>
<path
id="身材"
fill="none"
:stroke="stroke"
stroke-width="5"
stroke-miterlimit="10"
d="M128.6,92.1c2.4,0,6.1,4.6,6.1,4.6
s0,21.1,0,23.8s-4.6,5.3-4.6,5.3s-56.3,0-59,0s-6.5-5-6.5-5s0-20.4,0-23.3s4.4-5.3,4.4-5.3S126.2,92.1,128.6,92.1z"
/>
<rect x="87.5" y="89" :fill="fill" width="3.1" height="43" />
<path
id="U"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
d="M72.7,102.3c0,0,0,10,0,11.5s1.4,1.5,1.4,1.5
h4.4c0,0,1.8,0,1.8-1.5s0-11.5,0-11.5"
/>
<line
id="T1"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
x1="95.3"
y1="104"
x2="104.5"
y2="104"
/>
<line
id="T2"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
x1="99.9"
y1="117"
x2="99.9"
y2="104"
/>
<path
id="E1"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
d="M116.1,104.1l-6.9-0.2c0,0-1.1,0.1-1.1,1.5
s0,6.8,0,8.3s0.8,1.5,0.8,1.5h7.2"
/>
<line
id="E2"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
x1="116.2"
y1="109.8"
x2="106.7"
y2="109.8"
/>
<rect
x="124.5"
y="85.3"
transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 232.7188 -19.0313)"
:fill="fill"
width="2.7"
height="43"
/>
<rect
x="124.1"
y="90.9"
transform="matrix(-1.836970e-16 1 -1 -1.836970e-16 237.7917 -12.9583)"
:fill="fill"
width="2.6"
height="43"
/>
<polygon
id="D"
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
points="120,104.1 124.7,104.1 127.5,106.8
127.5,112.3 125.4,115.2 120,115.2 "
/>
<path
fill="none"
:stroke="stroke"
stroke-width="3"
stroke-miterlimit="10"
d="M93.3,104h-6.1c0,0-1.4,0.1-1.4,1.6s0,2.5,0,2.5
s0,1.5,1.3,1.5s3.1,0,3.1,0s1.7,0.1,1.7,1.7s0,1.1,0,2.5c0,1.4-1.4,1.4-1.4,1.4h-6.1"
/>
<rect x="87.4" y="106.9" :fill="fill" width="3.1" height="5.8" />
</svg>
</template>
<script>
// @ is an alias to /src
export default {
name: "CustedLogo",
computed: {
stroke: function () {
return "#249cff";
},
fill: function () {
return "#fff";
},
},
};
</script>

View File

@ -0,0 +1,85 @@
<template>
<div class="snake-bar" :class="snack_bar_class">
<div class="warp">
<div class="content">{{msg}}</div>
</div>
</div>
</template>
<script>
export default {
name: "SnakeBar",
props: ["msg"],
data() {
return {
snack_bar_class: ""
};
},
computed: {},
methods: {
openSnackBar(content) {
this.snack_bar_class = "higher-snake-bar";
setTimeout(() => {
this.snack_bar_class = "lower-snake-bar";
}, 2500);
},
},
created() {
this.openSnackBar();
},
mounted() {},
watch: {},
beforeDestroy() {},
components: {},
activated() {}
};
</script>
<style scoped lang="scss" type="text/scss">
.snake-bar {
position: fixed;
left: 0;
bottom: -1.2rem;
width: 100%;
.warp {
width: 100%;
max-width: 1024px;
margin: 0 auto;
height: 1.2rem;
background: #ebf6ff;
.content {
margin-left: 0.3rem;
padding-left: 0.3rem;
font-size: 0.35rem;
line-height: 1.2rem;
letter-spacing: 2px;
color: #249cff;
}
}
}
.higher-snake-bar {
animation: snakeToHigh 0.5s ease;
animation-fill-mode: forwards;
}
.lower-snake-bar {
animation: snakeToLow 0.5s ease;
animation-fill-mode: forwards;
}
@keyframes snakeToHigh {
0% {
bottom: -1.2rem;
}
100% {
bottom: 0rem;
}
}
@keyframes snakeToLow {
0% {
bottom: 0rem;
}
100% {
bottom: -1.2rem;
}
}
</style>

View File

@ -0,0 +1,31 @@
import SnakeBar from './SnakeBar.vue'
import Vue from 'vue'
let SnakeBarConstructor = Vue.extend(SnakeBar)
let instance
let seed = 1
let index = 2000
let eleList = []
const install = () => {
Object.defineProperty(Vue.prototype, '$snakebar', {
get () {
let id = 'snakebar_' + seed++
const alertMsg = options => {
instance = new SnakeBarConstructor({
propsData: {msg:options}
})
index++
instance.id = id
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
eleList.push(instance.vm.$el)
setTimeout(()=> {
document.body.removeChild(eleList.shift())
},3000)
instance.vm.$el.style.zIndex = index
return instance.vm
}
return alertMsg
}
})
}
export default install

View File

@ -4,8 +4,32 @@ import './registerServiceWorker'
import router from './router'
import store from './store'
//px2rem
function setHtmlFontSize() {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
if (htmlWidth >= 500) htmlDom.style.fontSize = 500 / 10 + 'px'
else htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize();
onresize = setHtmlFontSize
Vue.config.productionTip = false
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
// icon-loader
import Icon from 'vue-svg-icon/Icon.vue'
Vue.component('icon', Icon);
import CustedLogo from './components/Logo.vue'
Vue.component('custedLogo', CustedLogo)
// 自己写的snakebar组件
import SnakeBar from '@/components/SnakeBar/index'
Vue.use(SnakeBar)
new Vue({
router,
store,

View File

@ -8,16 +8,14 @@ const routes = [
{
path: '/',
name: 'Home',
component: Home
component: () => import( /* webpackChunkName: "home" */ '../views/Home.vue')
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
path: '*', // 页面不存在的情况下会跳到home
redirect: '/',
name: 'notFound',
hidden: true
}
]
const router = new VueRouter({

1
src/svg/left_arrow.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1592540000470" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6373" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M783.872 542.122667l-0.042667-64.405334-477.610666-0.298666 225.28-225.322667-45.568-45.568L182.506667 509.952l303.829333 303.829333 45.525333-45.504-226.474666-226.453333 478.506666 0.298667z" p-id="6374" fill="#494e5e"></path></svg>

After

Width:  |  Height:  |  Size: 611 B

View File

@ -1,5 +0,0 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

87
src/views/Cache.vue Normal file
View File

@ -0,0 +1,87 @@
<template>
<div class="home">
<header>
<div class="warp">
<p>图片压缩护士证专用</p>
</div>
</header>
<div style="height: 1.4rem"></div>
<main>
</main>
</div>
</template>
<script>
// @ is an alias to /src
// import HelloWorld from '@/components/HelloWorld.vue'
import "lrz";
export default {
name: 'Home',
data() {
return {
//
upload_file: null,
//
lrz_file: null,
}
},
methods: {
//
processFile: async function(e) {
let file = e[0]
if (file) {
let name = file.name
console.log('文件压缩开始')
file = await lrz(file);
file = file.file;
file = new File([file], name);
this.lrz_file = file;
console.log('文件压缩完成', this.lrz_file)
}
}
},
components: {
}
}
</script>
<style scoped lang="scss" type="text/scss">
.home {
width: 100%;
max-width: 1024px;
margin: 0 auto;
min-height: 100%;
position: relative;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
background-color: #fff;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
.warp {
background-color: #fff;
width: 100%;
max-width: 1024px;
margin: 0 auto;
height: 1.4rem;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
border-bottom: 1px solid #f3f3f3;
padding: 0 .35rem;
box-sizing: border-box;
p {
font-size: 0.45rem;
color: #494e5e;
line-height: 1.4rem;
width: 7rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
</style>

View File

@ -1,18 +1,217 @@
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<template v-if="img">
<header>
<div class="warp">
<div @click="back">
<icon name="left_arrow" class="back"></icon>
</div>
<p>图片压缩</p>
</div>
</header>
<cropper-image ref="child" :img="img"></cropper-image>
</template>
<main v-else>
<div class="logo-box">
<!-- <img src="../assets/cherry.png" /> -->
<custedLogo class="logo"></custedLogo>
</div>
<div class="title">护资照片压缩</div>
<div class="tip-box">
<div class="tip-line">
<div class="tip-title">冲印尺寸</div>
<div class="tip-content">25mm x 35mm</div>
</div>
<div class="tip-line">
<div class="tip-title">像素尺寸</div>
<div class="tip-content">295 x 413 px</div>
</div>
<div class="tip-line">
<div class="tip-title">分辨率</div>
<div class="tip-content">300 DPI</div>
</div>
<div class="tip-line">
<div class="tip-title">背景色</div>
<div class="tip-content">白色</div>
</div>
<div class="tip-line">
<div class="tip-title">文件大小</div>
<div class="tip-content">小于100kb</div>
</div>
<div class="tip-line">
<div class="tip-title">其他</div>
<div class="tip-content">
无噪点不模糊服装突出肩膀等高中性表情双眼水平人像剧中人脸姿态自然
</div>
</div>
</div>
<div class="btn-submit" @click="selectImg">选择图片</div>
<input
type="file"
ref="uploads"
style="position: absolute; clip: rect(0 0 0 0)"
accept="image/png, image/jpeg, image/gif, image/jpg"
@change="manageImg($event)"
/>
</main>
<footer>
<a href="http://beian.miit.gov.cn/"> <p>吉ICP备18005655号</p> </a>
<p>Copyright &copy; 2020 小单同学</p>
<p>All Rights Reserved</p>
</footer>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
import CropperImage from "@/components/CropperImage.vue";
export default {
name: 'Home',
components: {
HelloWorld
name: "Home",
components: { CropperImage },
data() {
return {
img: null,
};
},
methods: {
back() {
this.img = null;
},
selectImg() {
this.$refs.uploads.click();
},
//
manageImg: async function (e) {
let file = e.target.files[0];
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
this.$snakebar("图片类型要求jpeg、jpg、png");
return false;
}
//blob
let reader = new FileReader();
reader.onload = (e) => {
let data;
if (typeof e.target.result === "object") {
data = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data = e.target.result;
}
this.img = data;
};
//base64
reader.readAsDataURL(file);
},
},
};
</script>
<style scoped lang="scss" type="text/scss">
.home {
width: 100%;
max-width: 1024px;
margin: 0 auto;
min-height: 100vh;
position: relative;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
background-color: #fff;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
.warp {
background-color: #fff;
width: 100%;
max-width: 1024px;
margin: 0 auto;
height: 1.4rem;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !important;
border-bottom: 1px solid #f3f3f3;
.back {
float: left;
margin: 0.35rem 0.3rem;
height: 0.7rem;
width: 0.7rem;
}
p {
font-size: 0.45rem;
color: #494e5e;
line-height: 1.4rem;
width: 7rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.logo-box {
height: 3rem;
margin-top: 1.4rem;
display: flex;
align-items: center;
justify-content: center;
.logo {
height: 5rem;
width: 5rem;
}
img {
display: block;
height: 3rem;
width: 3rem;
margin: 0 auto;
}
}
.title {
text-align: center;
color: #303133;
font-size: 0.6rem;
}
.tip-box {
padding: 0.5rem 1rem;
box-sizing: border-box;
margin-top: 1rem;
.tip-line {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 0.45rem;
margin-bottom: 0.2rem;
.tip-title {
flex: 1;
color: #c0c4cc;
}
.tip-content {
flex: 3;
text-align: right;
color: #606266;
}
}
}
.btn-submit {
margin: 1.5rem 1rem;
margin-top: 0.5rem;
border-radius: 1rem;
height: 1rem;
font-size: 0.4rem;
font-weight: 400;
text-align: center;
line-height: 1rem;
color: #fff;
background: linear-gradient(to right, #3aa5fc, #20d6fa);
}
footer {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding-bottom: 0.3rem;
p {
text-align: center;
font-size: 0.25rem;
margin-bottom: 0.2rem;
color: #989898;
}
}
}
</script>
</style>

20
vue.config.js Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
productionSourceMap: false,
pwa: {
name: 'ImgZip',
themeColor: '#2dbdfb',
workboxOptions: {
skipWaiting: true
},
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico'
},
manifestOptions: {
background_color: '#ffffff'
}
}
}