加入图片裁剪

master
chuguofei 2021-12-19 22:50:33 +08:00
parent 78e3c50bbb
commit c773f815a9
2 changed files with 305 additions and 50 deletions

View File

@ -1,14 +1,28 @@
<template>
<div class="navbar">
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
<breadcrumb
id="breadcrumb-container"
class="breadcrumb-container"
v-if="!topNav"
/>
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav" />
<div class="right-menu">
<template v-if="device!=='mobile'">
<template v-if="device !== 'mobile'">
<i
class="el-icon-scissors icon-tailoring"
@click="tailoringVisible = !tailoringVisible"
></i>
<search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip>
@ -22,12 +36,14 @@
<el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
</template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<el-dropdown
class="avatar-container right-menu-item hover-effect"
trigger="click"
>
<div class="avatar-wrapper">
<img :src="avatar" class="user-avatar">
<img :src="avatar" class="user-avatar" />
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
@ -43,19 +59,22 @@
</el-dropdown-menu>
</el-dropdown>
</div>
<tailoring-dig :visible.sync="tailoringVisible" />
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import TopNav from '@/components/TopNav'
import Hamburger from '@/components/Hamburger'
import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch'
import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc'
import { mapGetters } from "vuex";
import Breadcrumb from "@/components/Breadcrumb";
import TopNav from "@/components/TopNav";
import Hamburger from "@/components/Hamburger";
import Screenfull from "@/components/Screenfull";
import SizeSelect from "@/components/SizeSelect";
import Search from "@/components/HeaderSearch";
import RuoYiGit from "@/components/RuoYi/Git";
import RuoYiDoc from "@/components/RuoYi/Doc";
import tailoringDig from "./tailoring.vue";
export default {
components: {
@ -66,48 +85,52 @@ export default {
SizeSelect,
Search,
RuoYiGit,
RuoYiDoc
RuoYiDoc,
tailoringDig,
},
data() {
return {
tailoringVisible: false,
};
},
computed: {
...mapGetters([
'sidebar',
'avatar',
'device'
]),
...mapGetters(["sidebar", "avatar", "device"]),
setting: {
get() {
return this.$store.state.settings.showSettings
return this.$store.state.settings.showSettings;
},
set(val) {
this.$store.dispatch('settings/changeSetting', {
key: 'showSettings',
value: val
})
}
this.$store.dispatch("settings/changeSetting", {
key: "showSettings",
value: val,
});
},
},
topNav: {
get() {
return this.$store.state.settings.topNav
}
}
return this.$store.state.settings.topNav;
},
},
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
this.$store.dispatch("app/toggleSideBar");
},
async logout() {
this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('LogOut').then(() => {
location.href = '/index';
this.$confirm("确定注销并退出系统吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$store.dispatch("LogOut").then(() => {
location.href = "/index";
});
})
}).catch(() => {});
}
}
}
.catch(() => {});
},
},
};
</script>
<style lang="scss" scoped>
@ -116,18 +139,18 @@ export default {
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background .3s;
-webkit-tap-highlight-color:transparent;
transition: background 0.3s;
-webkit-tap-highlight-color: transparent;
&:hover {
background: rgba(0, 0, 0, .025)
background: rgba(0, 0, 0, 0.025);
}
}
@ -164,10 +187,10 @@ export default {
&.hover-effect {
cursor: pointer;
transition: background .3s;
transition: background 0.3s;
&:hover {
background: rgba(0, 0, 0, .025)
background: rgba(0, 0, 0, 0.025);
}
}
}
@ -196,5 +219,14 @@ export default {
}
}
}
.icon-tailoring {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: middle;
font-weight: bold;
}
}
</style>

View File

@ -0,0 +1,223 @@
<template>
<div>
<el-dialog
:title="title"
:visible.sync="visible"
width="1200px"
append-to-body
@close="close"
>
<el-alert
v-if="!options.img"
title="请选择要裁剪的图片"
type="warning"
:closable="false"
style="margin-bottom: 10px"
/>
<div style="min-height: 300px; height: 300px">
<vue-cropper
ref="cropper"
:img="options.img"
:info="true"
output-type="png"
:autoCrop="options.autoCrop"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
@realTime="realTime"
v-if="visible"
/>
</div>
<div
v-if="previews.url"
class="preview-image"
:style="{
width: options.autoCropWidth + 'px',
height: options.autoCropHeight + 'px',
}"
>
<img :src="previews.url" :style="previews.img" />
</div>
<br />
<el-row>
<el-col>
<el-upload
action="#"
:http-request="requestUpload"
:show-file-list="false"
:before-upload="beforeUpload"
style="display: inline-block; margin-right: 15px"
>
<el-button size="small">
选择
<i class="el-icon-upload el-icon--right"></i>
</el-button>
</el-upload>
<el-button
icon="el-icon-plus"
size="small"
@click="changeScale(1)"
></el-button>
<el-button
icon="el-icon-minus"
size="small"
@click="changeScale(-1)"
></el-button>
<el-button
icon="el-icon-refresh-left"
size="small"
@click="rotateLeft()"
></el-button>
<el-button
icon="el-icon-refresh-right"
size="small"
@click="rotateRight()"
></el-button>
<div style="display: inline-block; margin: 0 15px">
<el-input
v-model="options.autoCropWidth"
placeholder="裁剪像素"
type="number"
style="width: 80px; display: inline-block"
/>
<span>x</span>
<el-input
v-model="options.autoCropHeight"
placeholder="裁剪像素"
style="width: 80px; display: inline-block"
/>
</div>
<el-button type="primary" size="small" @click="downLoadImgMeth()"
> </el-button
>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import { VueCropper } from "vue-cropper";
export default {
components: { VueCropper },
props: {
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "裁剪图片",
},
},
data() {
return {
options: {
img: "", //
autoCrop: true, //
autoCropWidth: 0,
autoCropHeight: 0,
},
previews: {},
timer: null,
};
},
methods: {
//
requestUpload() {},
//
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
//
rotateRight() {
this.$refs.cropper.rotateRight();
},
//
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//
beforeUpload(file) {
if (file.type.indexOf("image/") == -1) {
this.msgError("文件格式错误,请上传图片类型,如JPGPNG后缀的文件。");
} else {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
this.options.autoCropWidth = 200;
this.options.autoCropHeight = 200;
this.options.img = reader.result;
};
}
},
//
realTime(data) {
this.previews = data;
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
let { w, h } = data;
this.options.autoCropWidth = w;
this.options.autoCropHeight = h;
}, 500);
},
downLoadImgMeth() {
this.$refs.cropper.getCropBlob((data) => {
var aLink = document.createElement("a");
aLink.download = new Date().getTime();
this.downImg = window.URL.createObjectURL(data);
aLink.href = window.URL.createObjectURL(data);
aLink.click();
this.$message.success("下载成功");
});
},
close() {
this.$emit("update:visible", false);
},
},
};
</script>
<style scoped lang="scss">
.user-info-head {
position: relative;
display: inline-block;
height: 120px;
}
.user-info-head:hover:after {
content: "+";
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
color: #eee;
background: rgba(0, 0, 0, 0.5);
font-size: 24px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
cursor: pointer;
line-height: 110px;
border-radius: 50%;
}
.preview-image {
box-shadow: 0 0 4px #ccc;
margin-top: 20px;
overflow: hidden;
}
</style>
<style>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type="number"] {
-moz-appearance: textfield;
}
</style>