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

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>

 

posted @ 2018-11-21 15:44  suanmei  阅读(220)  评论(0编辑  收藏  举报