https://blog.csdn.net/wk767113154/article/details/77989544  参考资料

<template>
<div id="profile" class="has-top">
<!-- <v-header title="我的资料"></v-header> -->
<!-- <div class="section" @click="changeAvatar()">
<mt-cell class="no-line" title="头像" is-link>
<v-image :src="userInfo.avatar" avatar class="circle60 mt_mb_10" />
</mt-cell>
</div> -->
<div class="box">
<div ref="cvs">
<canvas id="canvas" width="0" height="0"></canvas>
</div>
<div class="btn" @click="confirmBtn()">
确认
</div>
<div style="display:none">
<canvas id="preview" :width="cvw" :height="cvw"></canvas>
</div>
</div>
<div class="section">
<div class="head-pic">
<span class="left">头像</span>
<input type="file" class="tx-file" @change="handleFileChange" accept="image/*">
<div v-if="txStatus">
<div v-if="!defaultPic">
<img src="../../assets/images/account/default_avatar.png" alt="">
</div>
<div v-else>
<img :src="defaultPic" alt="">
</div>
</div>
<div v-else>
<img :src="successPic" alt="">
</div> <!-- <v-image :src="userInfo.avatar" avatar class="mt_mb_10" /> -->
</div>
<mt-cell title="昵称" :value="nickName" is-link :to="{path:'/user/edit-nickname'}" />
<mt-cell title="管理收货地址" is-link :to="{path:'/address/list?form=profile'}" />
<!-- <div class="mint-cell" @click="bindPhone()">
<span class="mint-cell-mask"></span>
<div class="mint-cell-wrapper">
<div class="mint-cell-title"><span class="mint-cell-text">{{userInfo.phone ? '当前' : ''}}绑定手机</span></div>
<div class="mint-cell-value is-link"><span>{{phone}}</span></div>
</div>
<i class="mint-cell-allow-right"></i>
</div>
<mt-cell :title="state.password + '密码'" :value="state.text" is-link :to="{path: state.url}" /> --> <!-- <mt-cell title="管理收货地址" is-link :to="{path:'/address/list'}" /> -->
<!--
<div class="mint-cell" @click="bindBank()">
<span class="mint-cell-mask"></span>
<div class="mint-cell-wrapper">
<div class="mint-cell-title"><span class="mint-cell-text">绑定银行卡</span></div>
<div class="mint-cell-value is-link"><span>{{bank.accountStatus||'未绑定'}}</span></div>
</div>
<i class="mint-cell-allow-right"></i>
</div> -->
</div>
<div class="section mt10">
<template v-if="invitor">
<mt-cell title="我的分享人" :to="{path:'/user/invitor'}" :value="invitor.nickName" is-link/>
</template>
<template>
<mt-cell title="账户与安全" :to="{path:'/account'}" is-link/>
</template>
</div>
<div class="section mt10">
<!-- <div class="mint-cell" @click="onContact()">
<span class="mint-cell-mask"></span>
<div class="mint-cell-wrapper">
<div class="mint-cell-title"><span class="mint-cell-text">联系客服</span></div>
</div>
<i class="mint-cell-allow-right"></i>
</div> -->
<mt-cell title="版本号" value="1.0.1"/>
</div>
<div class="logout" @click="logout()">
退出登录
</div>
</div>
</template>
<script type="text/javascript">
import Config from '../../config.js';
import UserService from '../../services/UserService.js';
import BankService from '../../services/BankService.js';
import WeChatService from '../../services/WeChatService.js';
import CsService from '../../services/CsService.js';
import { MessageBox } from 'mint-ui';
import axios from 'axios';
import EXIF from 'exif-js'
export default {
initWechat: true,
data() {
return {
defaultPic: '',
successPic: '',
txStatus: true,
phone: '',
nickName: '',
userInfo: {},
invitor: undefined,
bank: {},
config: null,
hasPassword: false,
state: {
password: '',
text: '',
url: '/user/edit-password'
},
canvas: null,
ctx: null,
preview: null,
ctxpreview: null,
img: null,
btn: null,
imgdata: null, //选中区域内容
point: null,
flag: false,
cvw:0,
orientation: null,
isIos: false,
lastX: null,
lastY: null,
disX: null,
disY: null
}
},
methods: {
logout() {
UserService.logout(this);
},
handleFileChange(ev) {
// WeChatService.uploadImage(this, (image) => {
// UserService.updateAvatar(this, image, () => {
// this.showMessage('更新头像成功');
// this.userInfo.avatar = image;
// });
// });
var _this = this
// let params = new FormData()
// let imgFile = ev.target.files[0]
// params.append('file', imgFile);
// params.append('version', '1.0');
/* 图片裁剪 */
_this.img = new Image() var reader = new FileReader()
var file = ev.target.files[0]
if(!file) {
return false
}
document.querySelector('.box').style.display = 'block'
reader.readAsDataURL(file);
reader.onload = function(e) {
console.log(_this.img)
_this.img.src = e.target.result
_this.img.onload = function() {
_this.orientation = null EXIF.getData(_this.img, function () {
EXIF.getAllTags(this);
_this.orientation = EXIF.getTag(this, "Orientation");// 获取方向角
var degree = 0, drawWidth = _this.img.width, drawHeight = _this.img.height, width, height;
//以下改变一下图片大小
var cliWidth = Math.floor(document.documentElement.clientWidth)
var cliHeight = Math.floor(document.documentElement.clientHeight)
var maxSide = Math.max(drawWidth, drawHeight);
var tarSize = cliHeight
// if(drawWidth > drawHeight) {
// tarSize = cliWidth
// }else {
// tarSize = cliHeight
// }
if (maxSide > tarSize) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * tarSize;
maxSide = tarSize;
if (drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
if(minSide > cliWidth) {
drawHeight = cliWidth * drawHeight / drawWidth
drawWidth = cliWidth
}else{
drawWidth = minSide;
drawHeight = maxSide;
}
}
}
else{
drawHeight = cliWidth * drawHeight / drawWidth
drawWidth = cliWidth
} _this.canvas.width = width = drawWidth;
_this.canvas.height = height = drawHeight;
switch (_this.orientation) {//横屏竖屏转化
//横屏拍摄,此时home键在左侧
case 3:
degree = 180;
drawWidth = -width;
drawHeight = -height;
break;
//竖屏拍摄,此时home键在下方(正常拿手机的方向)
case 6: _this.canvas.width = height;
_this.canvas.height = width;
console.log(_this.canvas.width,_this.canvas.height)
degree = 90;
drawWidth = width;
drawHeight = -height;
break;
//竖屏拍摄,此时home键在上方
case 8:
_this.canvas.width = height;
_this.canvas.height = width;
degree = 270;
drawWidth = -width;
drawHeight = height;
break;
} _this.ctx.rotate(degree* Math.PI/180); _this.ctx.clearRect(0,0,_this.canvas.width,_this.canvas.height);
_this.ctx.drawImage(_this.img, 0, 0, drawWidth, drawHeight);
_this.ctx.save()
_this.ctx.fillStyle = 'rgba(0,0,0,0.5)'
_this.ctx.fillRect(0,0,_this.canvas.width,_this.canvas.height)
_this.ctx.restore()
// if(cliHeight > drawHeight) {
// _this.$refs.cvs.style.marginTop = (cliHeight-drawHeight)/2 + 'px'
// } // _this.drawcenter()
_this.ctx.save()
_this.ctx.fillStyle = 'rgba(0,0,0,0.5)'
_this.ctx.fillRect(0,0,_this.canvas.width,_this.canvas.height)
_this.ctx.restore()
_this.lastX = _this.canvas.width / 2
_this.lastY = _this.canvas.height / 2
_this.drawtop((_this.canvas.width - _this.cvw)/2,(_this.canvas.height - _this.cvw)/2,drawWidth,drawHeight)
// 移动canvas
_this.canvas.ontouchstart = function(e) {
e.preventDefault();
if(e.touches.length == 1) {
_this.flag = true
_this.point = _this.windowToCanvas(_this.canvas,e.touches[0].clientX,e.touches[0].clientY)
_this.disX = _this.point.x - _this.lastX
_this.disY = _this.point.y - _this.lastY
_this.point.x = _this.point.x - _this.disX
_this.point.y = _this.point.y - _this.disY _this.ctx.clearRect(0,0,_this.canvas.width,_this.canvas.height);
_this.ctx.drawImage(_this.img, 0, 0, drawWidth, drawHeight);
_this.ctx.save()
_this.ctx.fillStyle = 'rgba(0,0,0,0.5)'
_this.ctx.fillRect(0,0,_this.canvas.width,_this.canvas.height)
_this.ctx.restore()
_this.drawtop(_this.point.x-(_this.cvw/2),_this.point.y-(_this.cvw/2),drawWidth,drawHeight)
} }
_this.canvas.ontouchmove = function(e) {
e.preventDefault();
if(_this.flag) {
_this.point = _this.windowToCanvas(canvas,e.changedTouches[0].clientX,e.changedTouches[0].clientY)
// console.log(point.x + ' - ' + point.y)
_this.lastX = _this.point.x - _this.disX
_this.lastY = _this.point.y - _this.disY
_this.point.x = _this.point.x - _this.disX
_this.point.y = _this.point.y - _this.disY
_this.ctx.clearRect(0,0,_this.canvas.width,_this.canvas.height);
_this.ctx.drawImage(_this.img, 0, 0, drawWidth, drawHeight);
_this.ctx.save()
_this.ctx.fillStyle = 'rgba(0,0,0,0.5)'
_this.ctx.fillRect(0,0,_this.canvas.width,_this.canvas.height)
_this.ctx.restore()
_this.drawtop(_this.point.x-(_this.cvw/2),_this.point.y-(_this.cvw/2),drawWidth,drawHeight)
}
}
_this.canvas.ontouchend = function(e) {
//将鼠标状态释放
_this.flag = false
_this.point.x = _this.point.x
_this.point.y = _this.point.y
_this.imgdata = _this.ctx.getImageData(_this.point.x-(_this.cvw/2),_this.point.y-(_this.cvw/2),_this.cvw,_this.cvw)
_this.ctxpreview.putImageData(_this.imgdata,0,0)
}
// if(drawWidth < cliWidth) {
// if(drawWidth < drawHeight) {
// //_this.drawtop(drawWidth/2-_this.cvw/2,drawHeight/2-_this.cvw/2,drawWidth,drawHeight)
// _this.ctx.save()
// _this.ctx.beginPath()
// console.log(0,drawHeight/2-drawWidth/2,drawWidth,drawWidth)
// _this.ctx.rect(0,drawHeight/2-drawWidth/2,drawWidth,drawWidth)
// _this.ctx.closePath()
// _this.ctx.clip()
// //在该图层绘制原图
// _this.ctx.drawImage(_this.img,0, 0,drawWidth,drawHeight)
// console.log(0,drawHeight/2-drawWidth/2,drawWidth,drawWidth)
// _this.imgdata = _this.ctx.getImageData(0,drawHeight/2-drawWidth/2,drawWidth,drawWidth)
// console.log(0,drawHeight/2-drawWidth/2,drawWidth,drawWidth)
// _this.ctxpreview.putImageData(_this.imgdata,0,0)
// _this.ctx.restore()
// }else{
// _this.ctx.save()
// _this.ctx.beginPath()
// _this.ctx.rect(drawWidth/2-drawHeight/2,0,drawHeight,drawHeight)
// _this.ctx.closePath()
// _this.ctx.clip()
// //在该图层绘制原图
// _this.ctx.drawImage(_this.img,0, 0,drawWidth,drawHeight)
// _this.imgdata = _this.ctx.getImageData(drawWidth/2-drawHeight/2,0,drawHeight,drawHeight)
// _this.ctxpreview.putImageData(_this.imgdata,0,0)
// _this.ctx.restore()
// } // }else{
// _this.drawtop(cliWidth/2-(_this.cvw/2),cliHeight/2-(_this.cvw/2),drawWidth,drawHeight)
// } //_this.drawtop((drawWidth/2-_this.cvw/2),(drawHeight/2-_this.cvw/2),drawWidth,drawHeight) }) // _this.canvas.width = Math.floor(document.documentElement.clientWidth)
// _this.canvas.height = Math.floor(document.documentElement.clientHeight) // _this.ctx.clearRect(0,0,_this.canvas.width,_this.canvas.height);
// //第一层将图像绘制到canvas
// _this.ctx.drawImage(_this.img,(_this.canvas.width-_this.img.width)/2,(_this.canvas.height-_this.img.height)/2,_this.img.width,_this.img.height) }
// console.dir(e.target.result)
}
},
confirmBtn() {
var _this = this
document.querySelector('.box').style.display = 'none'
//console.log(preview.toDataURL("image/png")) let params = new FormData()
let dataURL = this.preview.toDataURL("image/png")
let blob = this.dataURItoBlob(dataURL);
params.append('file', blob);
params.append('version', '1.0'); axios.post(process.env.BASE_API + 'ddmallapi/upload/uploadImage', params, {
headers:{'Content-Type':'multipart/form-data'}
}).then(function(res) {
console.log(res)
if(res.data.data.imgUrl) {
_this.txStatus = false
_this.successPic = res.data.data.imgUrl;
let paramSave = new FormData()
paramSave.append('headImage',res.data.data.imgUrl)
axios.post(process.env.BASE_API + 'ddmallapi/user/changeHead?version=1.0', paramSave, {
headers:{'Content-Type':'application/x-www-form-urlencoded'}
}).then(function(res) {
// if(res.data.code === 0) {
// UserService.getInfo(_this,(res) => {
// console.log(res.data.data.headImage)
// });
// } }).catch(function(err) {
console.log(err)
})
}else{
_this.showError(res.data.message);
}
}).catch(function(err) {
console.log(err)
})
},
onContact() {
CsService.showCsView();
},
bindPhone() {
if (!this.hasPassword) {
let toast = Config.toast.filter(item => item.id == 'noLogin')[0];
this.showConfirms(toast.title, toast.message, () => {
this.$router.push({
path: '/find-password',
query: {
redirect: location.pathname,
set: true
}
})
}, null, '去设置', '取消');
return;
} if (!this.userInfo.phone) {
this.$router.push({ path: '/bind/phone' });
return;
}
this.$router.push({ path: '/user/edit-phone' });
},
checkPassword() {
UserService.checkPassword(this, (res) => {
if (res.code == 1) {
this.hasPassword = true;
this.state.password = '修改';
} else {
this.state.password = '设置';
this.state.text = '去设置';
this.state.url = '/find-password'
this.state.url += '?set=true&redirect='+location.pathname
}
})
},
drawcenter() {
//第二层 在图片上绘制半透明遮罩
this.ctx.save()
this.ctx.fillStyle = 'rgba(0,0,0,0.5)'
this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)
this.ctx.restore()
},
drawtop(x,y,drawWidth,drawHeight){
//第三层 局部高亮
this.ctx.save()
this.ctx.beginPath()
this.ctx.rect(x,y,this.cvw,this.cvw)
this.ctx.closePath()
this.ctx.clip()
//在该图层绘制原图
this.ctx.drawImage(this.img,0, 0,drawWidth,drawHeight)
this.imgdata = this.ctx.getImageData(x,y,this.cvw,this.cvw)
this.ctxpreview.putImageData(this.imgdata,0,0)
this.ctx.restore()
},
windowToCanvas(element,x,y) {
var box = element.getBoundingClientRect();
var cx = x - box.left
var cy = y - box.top
return {x:cx,y:cy}
},
dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {type: mimeString});
}
},
created() {
this.checkPassword();
},
mounted() { this.canvas = document.getElementById('canvas')
this.preview = document.getElementById('preview')
this.ctx = this.canvas.getContext('2d')
this.ctxpreview = this.preview.getContext('2d')
this.btn = document.querySelector('.btn')
this.cvw = 300
this.$root.$on('user.info.update', (userInfo) => {
console.log(userInfo)
this.userInfo = userInfo.data; if (this.userInfo.phone) {
this.phone = this.userInfo.phone.substr(0, 3) + '****' + this.userInfo.phone.substr(7);
}
if (this.userInfo.nickName && this.userInfo.nickName.length > 7) {
this.nickName = this.userInfo.nickName.substr(0, 7) + '...';
} else {
this.nickName = this.userInfo.nickName
}
}); UserService.getInfo(this, (res) => {
if(res.headImage) {
this.defaultPic = res.headImage
}
});
UserService.getInvitor(this, (data) => {
this.invitor = data;
}, () => {});
}
}
</script>
<style>
.logout {
margin-top: 20px;
height: 45px;
text-align: center;
background: #fff;
line-height: 45px;
font-size: 16px;
color: #ff4646;
}
.mint-cell {
min-height: 44px;
}
.mint-cell-text {
font-size: 16px !important
}
.mint-cell-value > span {
font-size: 16px !important
}
.head-pic {
padding: 0 15px;
position: relative;
height: 50px;
border-bottom: 1px solid #f0f0f0;
}
.head-pic .tx-file{
position:absolute;
left: 0;
top: 0;
width: 100%;
height: 50px;
opacity: 0;
}
.head-pic img {
margin-top: 5px;
float:right;
width: 40px;
height: 40px;
border-radius: 50%;
}
.head-pic .left{
float: left;
font-size: 16px !important;
line-height: 50px;
}
.user-center-header .header-left{
margin-left: 0.7rem;
}
</style> <style scoped>
.box{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 111;
background: #333;
display: none;
overflow: hidden;
text-align:center;
}
.box .btn {
position: absolute;
width: 60px;
height: 30px;
right: 5px;
top: 5px;
z-index: 111;
background: #fff;
line-height: 30px;
text-align: center;
border-radius: 5px;
}
.box canvas{ }
</style>

头像修改功能 包含ios旋转图片 但是旋转后没遮罩, 正常图片可以显示遮罩 宽高不规则图片没做控制 遮罩框可以拖动的更多相关文章

  1. Matrix: 利用Matrix来设置ImageView的宽高,使图片能正常显示

    在Android中加载ImageView一般都不会给ImageView的宽高设置一个确切的值,一般都是直接写成: <ImageView android:id="@+id/iv_test ...

  2. js 获取图片宽高 和 图片大小

    获取要查看大小的img var img_url = 'http://img5.imgtn.bdimg.com/it/u=4267222417,1017407570&fm=200&gp= ...

  3. excel表格添加固定宽高的图片

    import xlsxwriter,xlrd import glob #打开excel文件 data=xlrd.open_workbook('优秀创意库-20180725.xlsx') #获取第一张工 ...

  4. Android之ListView异步加载图片且仅显示可见子项中的图片

    折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整 ...

  5. JS实现图片宽高的等比缩放

    关于图片宽高的等比缩放,其实需求就是让图片自适应父容器的宽高,并且是等比缩放图片,使图片不变形. 例如,需要实现如下的效果: 要实现上面的效果,需要知道图片的宽高,父容器的宽高,然后计算缩放后的宽高. ...

  6. table-cell实现未知宽高图片,文本水平垂直居中在div

    <BODY> <h1>未知宽高的图片水平垂直居中在div</h1> <!--box-outer--> <div class="box-o ...

  7. 一行css解决图片统一大小后的拉伸问题(被冷漠的object-fit)

    一.先来个实战 1. 测试案例 需求: 要求表情库里所有表情包大小都固定 实际效果: 由于图片原始大小都不一样,强行设定大小值会导致拉伸,如果不设定大小则参差不齐.例如: //html <bod ...

  8. jquery mobile上传图片完整例子(包含ios图片横向问题处理和C#后台图片压缩)

    上传图片本身是个基本的小功能,但是到了移动端就不那么简单了,相信找到这篇文章的你一定有深深的同感. 本文实例是:在(移动端)页面中点击图片,然后选择文件,然后保存.使用Asp.net 难点一:后台获取 ...

  9. iOS图片上传后被旋转的问题

    最近用PHP做了一个图片合成程序,前端是通过HTML的file input选取自定图片,POST到php后台调整尺寸后与事先准备好的背景图进行合成. 通过测试发现,上传后的自定图片有的被旋转了,有的是 ...

随机推荐

  1. log4js 2.X版本配置详解

    const log4js = require('log4js'); log4js.configure({ appenders: { cheese: { type: 'file', filename: ...

  2. IntelliJ Idea设置Could not autowire. No beans of 'xxx' type found

    1.问题描述 在Idea的spring工程里,经常会遇到Could not autowire. No beans of ‘xxxx’ type found的错误提示.但程序的编译和运行都是没有问题的, ...

  3. uva-10026-贪心

    题意:有N项工作,每项工作完成需要n天,如果不开始做每天罚fee,开始做即不罚钱,求任务的执行顺序,使得罚钱最少.如果有多组答案,取下标排列最小的那组 解题思路: 考虑工作tn(dn,fn) , 假如 ...

  4. scala函数和方法的差别

    想知道什么差别,把代码复制下来运行看结果 // 1 1 2 3 5 8 13 def f(x:Int) :Int= { ) ) else f(x-)+f(x-) } println(f()) // v ...

  5. thinkphp3.2.2有预览的多图上传

    thinkphp3.2.2有预览的多图上传 整体思路 1 封装文件上传和图片上传的类文件 2 视图中添加相关JS和表单提交 3 控制器中添加上传文件的相关代码 一 2个class 文件 请上传到/Th ...

  6. 4.高级js--(面向对象js)_2

    1.创建对象的三种方式: l第一种构造法:new  Object var a = new Object(); a.x = 1, a.y = 2; l第二种构造法:对象直接量 var b = { x : ...

  7. <面试> PHP 常见算法

    排序算法 1. 冒泡排序(数组排序) 基本思想:对需要排序的数组从后往前(逆序)进行多遍的扫描,当发现相邻的两个数值的次序与排序要求的规则不一致时,就将这两个数值进行交换.这样每遍历一次,最小的数值就 ...

  8. Redis 密码

  9. js/jquery this 坑

    重要:js onclick() 函数中,取不到this !!! 错误的写法: function test(){ $(this).parent().addClass('active') } 正确的写法是 ...

  10. delphi面向对象 继承窗体

    delphi继承form TFrmBase = class(TForm) procedure FormShow(Sender: TObject); end; procedure TFrmBase.Fo ...