兼容电脑版微信小程序canvas图片裁剪
发布于 1 年前 作者 min64 4576 次浏览 来自 分享

image-cropper.wxml:

<view class="imageCropper">

    <canvas class="canvascanvas-id="myCanvasstyle="width:{{canvasWidth}}px;height:{{canvasHeight}}px">

        <movable-area class="movableAreastyle="width:{{canvasWidth}}px;height:{{canvasHeight}}px;">

            <movable-view wx:if="{{src}}" style="width:{{cut1Width}}px;height:{{cut1Height}}pxclass="movableBoxx="{{x}}" y="{{y}}" direction="allbindchange="movableChange"></movable-view>

            <image src="{{src}}" id="photostyle="width:{{canvasWidth}}px;height:{{canvasHeight}}px"></image>

        </movable-area>

    </canvas>

    <view class="footBox flex_around f30style="background: none;"><view class="cf p30 box_bbindtap="hide">取消</view><view class="cf p30 box_bbindtap="cut">确定</view></view>

</view>

image-cropper.js

let common = getApp().globalData.commonFun

let util = getApp().globalData.utilFun

Component({

    options: {},

    properties: {},

    options: {styleIsolation: "apply-shared"},

    data: {

        canvasHeight: 0,

        canvasWidth: 0,

        x: 0,

        y: 0,

        src: '',

        cutWidth: 0,

        cut1Width: 0,

        cutHeight: 0,

        cut1Height: 0,

        aspectRatio: 0,

    },

    attached: function () {},

    methods: {

        async setPageData(res) {

            //console.log(res)

            let imgWidth = res.imgWidth,imgHeight = res.imgHeight,w = Number(imgWidth/ 2 * 0.7,h = Number(imgHeight/ 2 * 0.7,imgInfo = await this.singleImgInfo(res.imgSrc),ch = 0,cw = 0,x = this.data.x,y = this.data.y;

            if (imgWidth == imgHeight{

                if (imgInfo.width >= imgWidth && imgInfo.height >= imgHeight{

                    if (imgInfo.width > imgInfo.height{

                        ch = Number(h+ 4;cw = Number(h/ Number(imgInfo.height* Number(imgInfo.width);x = (cw - w/ 2 - 2;

                    } else {

                        cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height);y = (ch - h/ 2 - 2;

                    }

                } else {

                    if (imgInfo.width < imgWidth && imgInfo.height >= imgHeight{

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(res.imgHeight+ 4;cw = Number(res.imgHeight/ Number(imgInfo.height* Number(imgInfo.width);x = (cw - w/ 2 / 2 - 42;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height);y = (ch - h/ 2 - 2;

                        }

                    } else if (imgInfo.width >= imgWidth && imgInfo.height < imgHeight{

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(h+ 4;cw = Number(h/ Number(imgInfo.height* Number(imgInfo.width);x = (cw - w/ 2 - 2;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height);y = (ch - h/ 2 - 2;

                        }

                    } else {

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(h+ 4;cw = Number(h/ Number(imgInfo.height* Number(imgInfo.width);x = (cw - w/ 2 - 2;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height);y = (ch - h/ 2 - 2;

                        }

                    }

                }

            } else {

                if (imgInfo.width >= imgWidth && imgInfo.height >= imgHeight{

                    if (imgInfo.width > imgInfo.height{

                        ch = Number(h+ 4;cw = Number(imgHeight / 2/ Number(imgInfo.height* Number(imgInfo.width+ 8x = (cw - w/ 2 - 2;

                    } else {

                        cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height+ 8y = (ch - h/ 2 - 2;

                    }

                } else {

                    if (imgInfo.width < imgWidth && imgInfo.height >= imgHeight{

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(h+ 4;cw = Number(imgHeight / 2/ Number(imgInfo.height* Number(imgInfo.width+ 8x = (cw - w/ 2 - 2;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height+ 8y = (ch - h/ 2 - 2;

                        }

                    } else if (imgInfo.width >= imgWidth && imgInfo.height < imgHeight{

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(h+ 4;cw = Number(imgHeight / 2/ Number(imgInfo.height* Number(imgInfo.width+ 8x = (cw - w/ 2 - 2;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height+ 8y = (ch - h/ 2 - 2;

                        }

                    } else {

                        if (imgInfo.width > imgInfo.height{

                            ch = Number(h+ 4;cw = Number(imgHeight / 2/ Number(imgInfo.height* Number(imgInfo.width+ 8x = (cw - w/ 2 - 2;

                        } else {

                            cw = Number(w+ 4;ch = Number(w/ Number(imgInfo.width* Number(imgInfo.height+ 8y = (ch - h/ 2 - 2;

                        }

                    }

                }

            }

            this.setData({

                x,

                y,

                canvasHeight: ch,

                canvasWidth: cw,

                cutWidth: res.imgWidth,

                cutHeight: res.imgHeight,

                cut1Width: w,

                cut1Height: h,

                src: res.imgSrc,

                aspectRatio: res.imgWidth / res.imgHeight

            });

            let that = this;

            const ctx = wx.createCanvasContext('myCanvas', this)

            setTimeout(function () {

                wx.createSelectorQuery().in(that).select('#photo').boundingClientRect(function (rect) {

                    ctx.drawImage(res.imgSrc, 0, 0, cw, ch)

                    ctx.draw();

                    //确保不同大小的图片,切图不会变形

                    that.setData({

                        x: x,

                        y: y

                    });

                }).exec()

            }, 100)

        },

singleImgInfo(res) {

    return new Promise((resolve, reject)=>{

        getImageInfo({

            src: res,

            complete(rs) {

                resolve(rs)

            }

        });

    })

},

        hide() {

            this.triggerEvent('myevent', {

                type: "hide"

            })

        },

        //裁剪框移动事件

        movableChange: function (e) {

            console.log(e.detail);

            this.setData({

                x: e.detail.x,

                y: e.detail.y

            })

        },

        //截图

        cut: function () {

            const that = this;

            wx.canvasToTempFilePath({

                x: that.data.x,

                y: that.data.y,

                width: that.data.cut1Width,

                height: that.data.cut1Height,

                destWidth: that.data.cutWidth,

                destHeight: that.data.cutHeight,

                canvasId: 'myCanvas',

                success(res) {

                    that.triggerEvent('myevent', { cut_src: res.tempFilePath,cutWidth: that.data.cutWidth, cutHeight: that.data.cutHeight,type: "confirm" })

                }

            }, this)

        },

    }

})

image-cropper.wxss

.movableArea {width: 100%;height: auto;position: relative;background: rgba(0, 0, 0, 0.3)}

.movableBox {border: 2px dashed #fff}

.imageCropper {background: rgba(14, 13, 13, .8);position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;z-index: 1;}

.canvas {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -60%);}

 .footBox {position: fixed;left: 50%;transform: translateX(-50%);z-index: 10;width: 750rpx;bottom: 0;padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);background: #ffffff;}

 .p30 {padding: 30rpx}

 .flex_around {display: -webkit-flex;display: flex;justify-content: space-around;}

 .cf {color: #fff;}

 .box_b {box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;}

page.json

{

    "navigationBarTitleText": "选择照片",

    "usingComponents": {"image-cropper": "/pages/image-cropper/image-cropper"}

}

page.wxml

  <image-cropper id="cutImgbindgetTempFilePath="getCutsrc"></image-cropper>

  <view wx:if="{{cut_src}}" class="fyj_cutDiv text-center"><image style="width:{{cutWidth}}px;height:{{cutHeight}}pxsrc="{{cut_src}}" mode="widthFix"></image></view>

</view>

page.js

Page({

  data: {cut_src:'',cutWidth:0,cutHeight:0,},

  onLoad: function (options) {

let that = this;

wx.chooseImage({

    count: 1,

    sizeType: ['original', 'compressed'],

    sourceType: ['album', 'camera'],

    success(res) {

        let val = {cropScale: "1:1",imgHeight: "750",imgSrc: res.tempFilePaths[0],imgWidth: "750",}

        if (that.selectComponent("#cutImg")) {that.selectComponent("#cutImg").setPageData(val)}

    }

})

  },

  getCutsrc:function(e){

        console.log(e);

        this.setData({cut_src: e.detail.cut_src,cutWidth: e.detail.cutWidth,cutHeight: e.detail.cutHeight})}

})

回到顶部