图片旋转功能(解决无法撑开父元素宽高的问题)

123 阅读2分钟

前言

图片上传有时候会有旋转功能,但是直接对图片进行旋转会无法撑开父元素导致宽高不能适应,图片显示不全,因为旋转属性是不会引起重排的,所以要用另外的方法进行旋转 目前我找到的方法是进行使用canvas进行base旋转(只支持90的倍数旋转),这两个我都试过,目前没什么问题,实际用到项目中根据自己需要更改就可以了

第一种(这个是URL是base64的形式)

 rotate(angle) {
            const img = new Image();
            img.src = JSON.parse(JSON.stringify(this.imgUrl));
            img.onload = () => {
                const canvas = document.createElement("canvas");
                // 交换宽高
                canvas.width = img.height;
                canvas.height = img.width;
                const ctx = canvas.getContext('2d');
                ctx.translate(img.height, 0);
                // 图片顺时针旋转90度后
                ctx.rotate(90 * Math.PI / 180);
                ctx.drawImage(img, 0, 0, img.width, img.height);
                // 转编译,一定要在图像绘制完毕以后
                const newBase64Str = canvas.toDataURL("image / jpeg", 1.0);
                //这个赋值是要在onload中进行,不然就是无法赋到值,因为onload这个函数不是同步进行的,如果一定要在外面赋值就使用promise去对图片加载进行监听,加载完就resolve(),然后在。then那里赋值也可以,我之前试过这个用法,不过有点麻烦
                this.imgUrl = newBase64Str
            }

        },

第二种(这个url是地址形式)

  rotateBase64Img(file, callback) {
            if (!file) {
                return
            }
            //旋转角度,建议就是不要整什么顺时针逆时针,都直接按照顺时针的处理,-90就是270这样子,处理的时候更好处理(只是个人建议,不习惯的也可以按照自己的方式来,怎么顺手怎么写)
            const angle = file.angle;

            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext("2d");
            let imgW;
            let imgH;
            let size;
            if (angle % 90 === 0) {
                const quadrant = (angle / 90) % 4;
                const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 };
                let image = new Image();
                image.crossOrigin = "anonymous";
                image.src = file.url;

                image.onload = function () {
                    imgW = image.width;
                    imgH = image.height;
                    size = imgW > imgH ? imgW : imgH;

                    canvas.width = size * 2;
                    canvas.height = size * 2;

                    switch (quadrant) {
                        case 0:
                            cutCoor.sx = size;
                            cutCoor.sy = size;
                            cutCoor.ex = size + imgW;
                            cutCoor.ey = size + imgH;
                            break;
                        case 1:
                            cutCoor.sx = size - imgH;
                            cutCoor.sy = size;
                            cutCoor.ex = size;
                            cutCoor.ey = size + imgW;
                            break;
                        case 2:
                            cutCoor.sx = size - imgW;
                            cutCoor.sy = size - imgH;
                            cutCoor.ex = size;
                            cutCoor.ey = size;
                            break;
                        case 3:
                            cutCoor.sx = size;
                            cutCoor.sy = size - imgW;
                            cutCoor.ex = size + imgH;
                            cutCoor.ey = size + imgW;
                            break;
                    }

                    ctx?.translate(size, size);
                    ctx?.rotate((angle * Math.PI) / 180);
                    ctx?.drawImage(image, 0, 0);
                    const imgData = ctx?.getImageData(
                        cutCoor.sx,
                        cutCoor.sy,
                        cutCoor.ex,
                        cutCoor.ey
                    );
                    if (quadrant % 2 == 0) {
                        canvas.width = imgW;
                        canvas.height = imgH;
                    } else {
                        canvas.width = imgH;
                        canvas.height = imgW;
                    }
                    ctx?.putImageData(imgData, 0, 0);
                    callback(canvas.toDataURL("image/png"));
                };

            }
        }
        
        
        使用方式
         this.rotateBase64Img(val, (url) => {
         //url是返回来的已经旋转好的图片
         }