Vue + ccropper.js裁切图片(vue-cropper)
按原比例裁剪图片并且不失真。
安装:
cnpm install vue-cropper --save-dev
使用:
<template>
<div style="display:flex;">
<div class="info-item" style="flex:1;">
<div style="width:120px;height:120px;border-radius:50%;overflow:hidden;margin-left:123px;border:1px solid #ddd">
<img style="width:120px;height:120px;" :src="headImg" alt="头像">
</div>
</div>
<div class="info-item" style="flex:1;margin-left:-160px;margin-top:30px;">
<label class="btn btn-orange" for="uploads" style="display:inline-block;width: 70px;padding: 0;text-align: center;line-height: 28px;">选择图片</label>
<input type="file" id="uploads" :value="imgFile" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="+" title="放大" @click="changeScale(1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="-" title="缩小" @click="changeScale(-1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↺" title="左旋转" @click="rotateLeft">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↻" title="右旋转" @click="rotateRight">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↓" title="下载" @click="down('blob')">
<input type="button" class="btn btn-blue" value="上传头像" @click="finish('blob')">
<div class="line" style="margin-left: -280px;margin-top: 85px;">
<div class="cropper-content" style="margin-top:-60px;margin-left:260px;">
<div class="cropper">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
@realTime="realTime"
@imgLoad="imgLoad"
></vueCropper>
</div>
<div style="margin-left:20px;">
<div class="show-preview" :style="{'width': '150px', 'height':'155px', 'overflow': 'hidden', 'margin': '5px'}">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template> <script>
import VueCropper from 'vue-cropper'
import Api from '@/js/api.js' //接口url配置文件 export default {
data() {
return {
headImg:'',
//剪切图片上传
crap: false,
previews: {},
option: {
img: '',
outputSize:1, //剪切后的图片质量(0.1-1)
full: false,//输出原图比例截图 props名full
outputType: 'png',
canMove: true,
original: false,
canMoveBox: true,
autoCrop: true,
autoCropWidth: 150,
autoCropHeight: 150,
fixedBox: true
},
fileName:'', //本机文件地址
downImg: '#',
imgFile:'',
uploadImgRelaPath:'', //上传后的图片的地址(不带服务器域名)
}
},
components: {
VueCropper
},
methods: {
//放大/缩小
changeScale(num) {
console.log('changeScale')
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//坐旋转
rotateLeft() {
console.log('rotateLeft')
this.$refs.cropper.rotateLeft();
},
//右旋转
rotateRight() {
console.log('rotateRight')
this.$refs.cropper.rotateRight();
},
//上传图片(点击上传按钮)
finish(type) {
console.log('finish')
let _this = this;
let formData = new FormData();
// 输出
if (type === 'blob') {
this.$refs.cropper.getCropBlob((data) => {
let img = window.URL.createObjectURL(data)
this.model = true;
this.modelSrc = img;
formData.append("file", data, this.fileName);
this.$http.post(Api.uploadSysHeadImg.url, formData, {contentType: false, processData: false, headers:{'Content-Type': 'application/x-www-form-urlencoded'}})
.then((response)=>{
var res = response.data;
if(res.success == 1){
$('#btn1').val('');
_this.imgFile = '';
_this.headImg = res.realPathList[0]; //完整路径
_this.uploadImgRelaPath = res.relaPathList[0]; //非完整路径
_this.$message({ //element-ui的消息Message消息提示组件
type: 'success',
message: '上传成功'
});
}
})
})
} else {
this.$refs.cropper.getCropData((data) => {
this.model = true;
this.modelSrc = data;
})
}
},
// 实时预览函数
realTime(data) {
console.log('realTime')
this.previews = data
},
//下载图片
down(type) {
console.log('down')
var aLink = document.createElement('a')
aLink.download = 'author-img'
if (type === 'blob') {
this.$refs.cropper.getCropBlob((data) => {
this.downImg = window.URL.createObjectURL(data)
aLink.href = window.URL.createObjectURL(data)
aLink.click()
})
} else {
this.$refs.cropper.getCropData((data) => {
this.downImg = data;
aLink.href = data;
aLink.click()
})
}
},
//选择本地图片
uploadImg(e, num) {
console.log('uploadImg');
var _this = this;
//上传图片
var file = e.target.files[0]
_this.fileName = file.name;
if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
alert('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
return false
}
var reader = new FileReader();
reader.onload =(e) => {
let data;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data = window.URL.createObjectURL(new Blob([e.target.result]))
}
else {
data = e.target.result
}
if (num === 1) {
_this.option.img = data
} else if (num === 2) {
_this.example2.img = data
}
}
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file); },
imgLoad (msg) {
console.log('imgLoad')
console.log(msg)
}
}, }
</script> <style lang="less">
.info {
width: 720px;
margin: 0 auto;
.oper-dv {
height:20px;
text-align:right;
margin-right:100px;
a {
font-weight: 500;
&:last-child {
margin-left: 30px;
}
}
}
.info-item {
margin-top: 15px;
label {
display: inline-block;
width: 100px;
text-align: right;
}
.sel-img-dv {
position: relative;
.sel-file {
position: absolute;
width: 90px;
height: 30px;
opacity: 0;
cursor: pointer;
z-index: 2;
}
.sel-btn {
position: absolute;
cursor: pointer;
z-index: 1;
}
}
}
} .cropper-content{
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
.cropper{
width: 260px;
height: 260px;
}
.show-preview{
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
.preview{
overflow: hidden;
border-radius: 50%;
border:1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
}
}
.cropper-content .show-preview .preview {margin-left: 0;} </style>
js/api.js文件是配置的{接口地址}。
粘贴好用。
Vue + ccropper.js裁切图片(vue-cropper)的更多相关文章
- vue.esm.js?efeb:628 [Vue warn]: Invalid prop: type check failed for prop "defaultActive". Expected String with value "0", got Number with value 0.
vue.esm.js?efeb:628 [Vue warn]: Invalid prop: type check failed for prop "defaultActive". ...
- vue项目js实现图片放大镜功能
效果图: 我写的是vue的组件形式,方便复用,图片的宽高,缩放的比例可以自己定义 magnifier.vue <template> <div class="magnif ...
- vue中 js获取图片尺寸 设置不同样式
1.JS: 请求到后端数据后 判断图片尺寸 2.HTML代码 根据设置的类型,给图片添加不同的样式 3.CSS代码 添加不同尺寸的样式
- 解决vue、js 下载图片浏览器默认预览而不是下载
在网页上,如果我们下载的地址对应的是一个jpg文件,txt文件等,点击链接时,浏览器默认的是打开这些文件而不是下载,那么如何才能实现默认下载呢? 后端解决 这就是Content-Disposition ...
- ant design for vue 解决 vue.esm.js?c5de:628 [Vue warn]: Invalid prop: custom validator check failed for prop "defaultValue". 的错误
错误重现: 在使用ant design for vue 的选择器插件的时候, 设置默认为为id(为数字) 报错: 解决办法: id为数字, 而defaultValue 的key 值必须为字符串, 将i ...
- vue cli3.3 以上版本配置vue.config.js
// vue.config.js 配置说明//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions// 这里只 ...
- 【vue-cli 3.0】 vue.config.js配置 - 路径别名
如何配置vue-cli 3中vue.config.js的路径别名? 前段时间更新电脑重装了一下vue-cli,发现了vue-cli已经更新到3.0版.用来搭建项目后发现简化了很多,而且配置文件现在可以 ...
- vue.config.js配置前端代理
// vue.config.js 配置说明 //官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions // 这 ...
- day67:Vue:es6基本语法&vue.js基本使用&vue指令系统
目录 Vue前戏:es6的基本语法 1.es6中的let特点 1.1.局部作用域 1.2.不存在变量提升 1.3.不能重复声明 1.4.let声明的全局变量不从属于window对象,var声明的全局变 ...
随机推荐
- tensorboard学习笔记
TensorBoard 默认是不会记录每个节点的用时.耗费的内存大小等这些信息的,那么如何才能在图上显示这些信息呢?关键就是如下这些代码,主要就是在 sess.run() 中加入 options 和 ...
- 【React学习笔记】React生命周期梳理(16.X前后两种)
React生命周期 「16版本以前的:」 生命周期流程图 组件从生成到被挂在到页面上的一系列过程 根据流程图打印的执行顺序图: 流程讲解: 初始化流程 start 开始创建组件 在这个周期中做的事情 ...
- iis 0x80070032 Cannot read configuration file because it exceeds the maximum file size
问题:iis部署了网站,由于webconfig文件过大(251kb,默认250kb)导致网站报错 0x80070032 Cannot read configuration file because i ...
- Redis作为缓存可能会出现的问题及解决方案
Redis是个大话题,只要是去面试Java开发,几乎必问.基础一点的问Redis是什么东西?用来做什么?Redis支持哪些数据类型?Redis的性能为什么那么好?复杂一点的就会问到缓存穿透.缓存击穿. ...
- node name配置错误,导致grid日志在报警
[root@aipdb ContentsXML]# cat inventory.xml <?xml version="1.0" standalone="yes&qu ...
- 016.Nginx HTTPS
一 HTTPS概述 1.1 HTTPS介绍 超文本传输安全协议HTTPS(Hypertext Transfer Protocol Secure)是超文本传输协议和SSL/TLS的组合,用以提供加密通讯 ...
- python 批量重命名文件名字
import os print(os.path) img_name = os.listdir('./img') for index, temp_name in enumerate(img_name): ...
- eclipse IDE usage of my own and tutorials link list
设置 字符集 Eclipse 修改字符集 默认情况下 Eclipse 字符集为 GBK,但现在很多项目采用的是 UTF-8,这是我们就需要设置我们的 Eclipse 开发环境字符集为 UTF-8, 设 ...
- JS 原生ajax写法
<script> //step1.创建XMLHTTPRequest对象,对于低版本的IE,需要换一个ActiveXObject对象 var xhr; if (window.XMLHttpR ...
- Python之生成器、迭代器
生成器 生成器类似返回值为数组的一个函数,这个函数可以接受参数,可被调用,但只能产生一个值,所以大大节省内存. 生成器表达式的语法非常简单,只需要将列表推导式的中括号改成小括号就可以了 [x+x fo ...