• js 的canvas使用 -- canvas转图片、图片转canvas、base64图片下载到本地、复制剪贴板、生成二维码的canvas


    将canvas 转图片 以及 将 图片转成 canvas的方法

    1. 图片转到画布上

    // Converts image to canvas; returns new canvas element
    function convertImageToCanvas(image) {
        var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        canvas.getContext("2d").drawImage(image, 0, 0);
    
        return canvas;
    }
    // (image, 0, 0); 其中0,0表示canvas的坐标点

    2. 画布转成图片

    // Converts canvas to an image
    function convertCanvasToImage(canvas) {
        var image = new Image();
        image.src = canvas.toDataURL("image/png");
        return image;
    }
    // "image/png"表示canvas转成的图片类型,默认是png,可以改成"image/jpeg"

    3. base64图片下载到本地(android另说)

    /**
     * 下载Base64到本地
     1. trident内核都不可以(IE,猎豹)
     2. chrome, opera 等使用blink内核 可以(但是chrome好像还是webkit内核)
     3. firefox(Gecko) 可以
     4. 三星可以(多余后缀)
     5. 小米自带的手机浏览器可以(但filename乱码)
     6. qq, uc(PC都可以)
     * */
    function downloadFile(content, fileName) { //下载base64图片
        const base64ToBlob = function(code) {
            let parts = code.split(';base64,');
            let contentType = parts[0].split(':')[1];
            let raw = window.atob(parts[1]);
            let rawLength = raw.length;
            let uInt8Array = new Uint8Array(rawLength);
            for(let i = 0; i < rawLength; ++i) {
                uInt8Array[i] = raw.charCodeAt(i);
            }
            return new Blob([uInt8Array], {
                type: contentType
            });
        };
        let aLink = document.createElement('a');
        let blob = base64ToBlob(content); //new Blob([content]);
        let evt = document.createEvent("HTMLEvents");
        evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
        aLink.download = fileName;
        aLink.href = URL.createObjectURL(blob);
        // aLink.click();
        aLink.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true, view: window}));  //
    }

    4. 复制剪贴板

    /**
     * 复制进剪贴板
     * @param str
     */
    export function copyText(message) {
        // copy(str){
        //     let save = function (e){
        //         e.clipboardData.setData('text/plain',str);//clipboardData对象
        //         e.preventDefault();//阻止默认行为
        //     };
        //     document.addEventListener('copy',save);
        //     return document.execCommand("copy");//使文档处于可编辑状态,否则无效
        // }
    
        let input = document.createElement("textarea");
        input.value = message;
        document.body.appendChild(input);
        input.select();
        input.setSelectionRange(0, input.value.length);
        document.execCommand('Copy');
        document.body.removeChild(input);
        console.log("复制成功")     //"复制成功"
    }

    5. 生成二维码的canvas(使用jquery 和 jquery.qrcode.js )

    // 生成二维码canvas - 使用jquery 和 jquery.qrcode.js 
    function() {  
         var imgBuffer = $("<div></div>");
            imgBuffer.qrcode({
                render: 'canvas',
                 0.24 * deviceWidth * ratio,
                height: 0.24 * deviceWidth * ratio,
                text: url,
                foreground: "#000000",
                correctLevel: 3,
                minVersion: 1,
                //src: require("../image/logo-qrcode.png"),
            });
            // var ctx = imgBuffer.children("canvas")[0].getContext("2d");
            // this.qrcodeImageObj = imgBuffer.children("canvas")[0];
            // this.qrcodeImageSrc = imgBuffer.children("canvas")[0].toDataURL();
            // this.qrCodeData = ctx.getImageData(0,0,imgBuffer.children("canvas")[0].width, imgBuffer.children("canvas")[0].height);
    }
    // 123

    方法二: 使用 npm i qrcode

    // 使用 npm i qrcode 的二维码生成功能   
    function getQrcodeCanvas = { 
        const _this = this;
            await QRCode.toCanvas(url, {
                 0.24 * deviceWidth * ratio,
                height: 0.24 * deviceWidth * ratio,
                text: url,
                foreground: "#000000",
                correctLevel: 3,
                minVersion: 1,
            }, function (err, canvas) {
                var ctx = canvas.getContext("2d");
                _this.qrcodeImageObj = canvas;
                _this.qrcodeImageSrc = canvas.toDataURL();
                _this.qrCodeData = ctx.getImageData(0,0, canvas.width, canvas.height);
            });
    }

    最后: 实例

      1 /**
      2  * 使用
      3  */
      4 const data = {
      5      document.body.clientWidth,
      6     height: document.body.clientHeight
      7 }
      8 new DrawInvitation(data, (src, canvas, imageObj, imageSrc) => {
      9     // success callback
     10     // 显示 canvas
     11     // 显示 image
     12     // 保存 image
     13 }, () => {
     14     // fail callback
     15 })
     16 
     17 
     18 
     19 
     20 /**
     21  * 画图
     22  */
     23 class DrawCanvas {
     24     constructor(data, successCallback, errorCallback) {
     25         this.url = "https://123.com";
     26 
     27         var deviceWidth = data.width ? data.width : window.screen.width;
     28         var deviceHeight = data.height ? data.height : window.screen.width * 16/9;
     29         var dpr = window.devicePixelRatio || 1;
     30         var canvas = $("<canvas id='qrcode-canvas'></canvas>");
     31         canvas.attr("width",deviceWidth);
     32         canvas.attr("height",deviceHeight);
     33         canvas.css("position", "absolute");
     34         canvas.css("left", "0");
     35         canvas.css("top", "0");
     36         canvas.css("z-index", "1");
     37         // canvas.css("display", "none");
     38         canvas.css("background-color", "#000000");
     39         var ctx = canvas[0].getContext("2d");
     40         var bspr = ctx.webkitBackingStorePixelRatio ||
     41             ctx.mozBackingStorePixelRatio ||
     42             ctx.msBackingStorePixelRatio ||
     43             ctx.oBackingStorePixelRatio ||
     44             ctx.BackingStorePixelRatio || 1;
     45         var ratio = dpr / bspr;
     46         canvas.css("width", canvas.attr("width"));
     47         canvas.css("height", canvas.attr("height"));
     48         canvas.attr("width", canvas.attr("width") * ratio);
     49         canvas.attr("height", canvas.attr("height") * ratio);
     50 
     51         this.qrCodeData = null;
     52         this.deviceWidth = deviceWidth;
     53         this.deviceHeight = deviceHeight;
     54         this.ctx = ctx;
     55         this.ratio = ratio;
     56         this.canvas = canvas;
     57         this.successCallback = successCallback;
     58         this.errorCallback = errorCallback;
     59     }
     60 
     61     /**
     62      * 生成二维码
     63      */
     64     async qrCodeCreater(){
     65         // 二维码的生成路径
     66         let {deviceWidth, ratio} = this;
     67         var imgBuffer = $("<div></div>");
     68         let url = this.url;
     69         // imgBuffer.qrcode({
     70         //     render: 'canvas',
     71         //      0.24 * deviceWidth * ratio,
     72         //     height: 0.24 * deviceWidth * ratio,
     73         //     text: url,
     74         //     foreground: "#000000",
     75         //     correctLevel: 3,
     76         //     minVersion: 1,
     77         //     //src: require("../image/logo-qrcode.png"),
     78         // });
     79         // var ctx = imgBuffer.children("canvas")[0].getContext("2d");
     80         // this.qrcodeImageObj = imgBuffer.children("canvas")[0];
     81         // this.qrcodeImageSrc = imgBuffer.children("canvas")[0].toDataURL();
     82         // this.qrCodeData = ctx.getImageData(0,0,imgBuffer.children("canvas")[0].width, imgBuffer.children("canvas")[0].height);
     83 
     84         const _this = this;
     85         await QRCode.toCanvas(url, {
     86              0.24 * deviceWidth * ratio,
     87             height: 0.24 * deviceWidth * ratio,
     88             text: url,
     89             foreground: "#000000",
     90             correctLevel: 3,
     91             minVersion: 1,
     92         }, function (err, canvas) {
     93             var ctx = canvas.getContext("2d");
     94             _this.qrcodeImageObj = canvas;
     95             _this.qrcodeImageSrc = canvas.toDataURL();
     96             _this.qrCodeData = ctx.getImageData(0,0, canvas.width, canvas.height);
     97         });
     98     };
     99 
    100     /**
    101      * 生成图片
    102      */
    103     draw() {
    104         // 生成二维码的图片
    105         this.qrCodeCreater();
    106         const _this = this;
    107         // var imgBuffer = $("<img></img>");
    108         // imgBuffer.on("load", function() {})  //jquery的监听从1.8版本开始,不可使用load直接进行
    109         var imgBuffer = new Image();
    110         imgBuffer.crossOrigin = "Anonymous";
    111         imgBuffer.src = "图片1.png";
    112         imgBuffer.onload = function(){
    113             var imgBuffer_2 = new Image();
    114             imgBuffer_2.crossOrigin = "Anonymous";
    115             imgBuffer_2.src = "图片2.png";
    116             imgBuffer_2.onload = function(){
    117                 var imgBuffer_3 = new Image();
    118                 imgBuffer_3.crossOrigin = "Anonymous";
    119                 imgBuffer_3.src = "图片3.png";
    120                 imgBuffer_3.onload = function(){
    121                     _this.drawCanvas(imgBuffer, imgBuffer_2, imgBuffer_3);
    122                 };
    123                 imgBuffer_3.onerror = function () {
    124                     showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback);    //'生成邀请函失败!'
    125                 };
    126             };
    127             imgBuffer_2.onerror = function () {
    128                 showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback);    //'生成邀请函失败!'
    129             }
    130         };
    131         imgBuffer.onerror = function () {
    132             showErrorMessage(i18n.home.generate_card_fail, _this.errorCallback);    //'生成邀请函失败!'
    133         }
    134     }
    135 
    136     /**
    137      * onload 图片后合成canvas
    138      * @param imgBuffer
    139      * @param imgBuffer_2
    140      */
    141     drawCanvas(imgBuffer, imgBuffer_2, imgBuffer_3) {
    142         let {qrCodeData, ctx, canvas, deviceWidth, deviceHeight, ratio, successCallback} = this;
    143         ctx.clearRect(0,0,canvas.attr("width"), canvas.attr("height"));
    144         //背景颜色
    145         ctx.fillStyle = "#ffffff";
    146         ctx.fillRect(0, 0, canvas.attr("width"), canvas.attr("height"));
    147         ctx.textAlign="center";
    148         // ctx.drawImage(imgBuffer, 0, 0, canvas.attr("width"), canvas.attr("height"));
    149 
    150         let canvasWidth= canvas.attr("width"), canvasHeight = canvas.attr("height");
    151         // 顶部橙色圆弧背景
    152         ctx.beginPath();
    153         // ctx.arc(300, -540, 750, 0, 2*Math.PI);
    154         ctx.arc(canvasWidth/6*5, -canvasWidth/9*13.5, canvasWidth/12*25, 0, 2*Math.PI);
    155         ctx.stroke();
    156         ctx.fillStyle="#03bcd5";
    157         ctx.fill();
    158         // logo图片
    159         ctx.drawImage(imgBuffer, canvasWidth * 0.2, canvasWidth * 0.14, canvasWidth*0.6, canvasWidth*0.6*0.31466);//0.31466470154753131908621960206338
    160         // 底部图片
    161         ctx.drawImage(imgBuffer_2, canvasWidth * 0.382/2, canvasHeight-canvasWidth * 0.618, canvasWidth * 0.618, canvasWidth * 0.618);
    162         // 二维码背景
    163         ctx.beginPath();
    164         ctx.rect(canvasWidth*0.38-canvasWidth*0.01, canvasHeight*0.59-canvasWidth*0.008, qrCodeData.width+canvasWidth*0.02, qrCodeData.height+canvasWidth*0.02);
    165         ctx.stroke();
    166         ctx.fillStyle="#ffffff";
    167         ctx.fill();
    168         // 二维码
    169         ctx.putImageData(qrCodeData, canvas.attr("width") * 0.38, canvas.attr("height") * 0.59);
    170 
    171         ctx.drawImage(imgBuffer_3,
    172             canvas.attr("width") * 0.38 + this.qrcodeImageObj.width/2 - this.qrcodeImageObj.width/4.7/2,
    173             canvas.attr("height") * 0.59 + this.qrcodeImageObj.height/2 - this.qrcodeImageObj.height/4.7/2,
    174             this.qrcodeImageObj.width/4.7,
    175             this.qrcodeImageObj.height/4.7);
    176 
    177         //文字颜色
    178         ctx.fillStyle = "#000000";
    179         var in_text3 = "123456789";
    180         var in_text4 = "123456789";
    181         var in_text5 = "123456789";
    182         var in_text6 = "123456789";
    183 
    184         // 1
    185         ctx.font= "900 " + deviceWidth * ratio / (getCurrentInputLength(in_text3) * 1 > 12 ? getCurrentInputLength(in_text3) * 1 : 12) +"px 微软雅黑";
    186         ctx.fillText(in_text3, 0.5 * deviceWidth * ratio , 0.42 * deviceHeight * ratio);
    187         // 2
    188         this.fillTextAndAutoChangeLine(ctx, deviceWidth, ratio, deviceHeight, in_text4);
    189         // 3
    190         ctx.font= "bold " + deviceWidth * ratio / 22 + "px exo, JiaLiDaYuan, 微软雅黑";
    191         ctx.fillText(in_text5, 0.5 * deviceWidth * ratio , 0.815 * deviceHeight * ratio);
    192         ctx.fillText(in_text6, 0.5 * deviceWidth * ratio, 0.855 * deviceHeight * ratio);
    193 
    194         // $("#imgBox").children("img").attr("src", canvas[0].toDataURL());
    195         successCallback(canvas[0].toDataURL(), canvas, this.qrcodeImageObj, this.qrcodeImageSrc);
    196     }
    197 
    198 
    199     /** 绘制文字时自动换行 */
    200     fillTextAndAutoChangeLine(ctx, deviceWidth, ratio, deviceHeight, text) {
    201         ctx.font= deviceWidth * ratio / 22 +"px 微软雅黑";
    202         // 一个字符的宽度
    203         const oneCharWidth = ctx.measureText("M").width;
    204         // canvas的宽度, 这里特意少个字符
    205         const canvasWidth = deviceWidth * ratio - 3 * oneCharWidth;
    206         const len = text.length;
    207         // 初始Y的距离
    208         let initY = 0.45 * deviceHeight * ratio;
    209         const lineHeight = 0.03 * deviceHeight * ratio;
    210         // 预存字符串
    211         let preWriteText = "";
    212         let preWriteTextWidth = 0;
    213         // 整个单词, 遇到不完整的就换行
    214         let totalWord = "";
    215         for (let i = 0; i < len; i ++) {
    216             const char = text.charAt(i);
    217             // 判断是否遇到空格
    218             if (char === " ") {
    219                 totalWord = "";
    220             } else {
    221                 totalWord += char;
    222             }
    223             // 计算字体的宽度
    224             const charWidth = ctx.measureText(char).width;
    225             preWriteTextWidth += charWidth;
    226             // 如果大于cavas宽度并且不是最后一个字符并且是一个完整的单次, 则将这行写下来, 并换行
    227             if (i != len - 1 && preWriteTextWidth >= canvasWidth) {
    228                 // 通过下一个是不是空格判断是不是一个完整的单次
    229                 if (char != " "&& preWriteText.indexOf(" ") !== -1) {
    230                     // 不是完整的单次, 则退回到单次开头
    231                     const wordFirstCharPos = preWriteText.length - totalWord.length + 1;
    232                     preWriteText = preWriteText.substring(0, wordFirstCharPos);
    233                     initY += lineHeight;
    234                     ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY);
    235                     i -= totalWord.length;
    236                     // 单次的第一个字母
    237                     const wordFirstChar = text.charAt(wordFirstCharPos);
    238                     preWriteText = "";
    239                     preWriteTextWidth = 0;
    240                 }
    241                 // 下一个不是空格, 并且这一行中没有空格, 则把这行写下来 ||
    242                 else {
    243                     initY += lineHeight;
    244                     // 当前单次切掉, 确保不爆框
    245                     preWriteText = preWriteText.substring(0, preWriteText.length);
    246                     ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY);
    247                     // 换行
    248                     preWriteText = char;
    249                     preWriteTextWidth = charWidth;
    250                 }
    251             } else {
    252                 preWriteText += char;
    253             }
    254             // 直到最后一个字
    255             if (i == len - 1) {
    256                 initY += lineHeight;
    257                 ctx.fillText(preWriteText, 0.5 * deviceWidth * ratio , initY);
    258             }
    259         }
    260     }
    261 }
    View Code
  • 相关阅读:
    什么是Web Service?
    按钮上显示值的轮流切换
    跟偶一起做:击退眼睛疲劳的五大运动
    Windows下权限设置详解
    实现数据分类汇总的SQL语句
    毕业不吼不快十首经典歌曲
    使用命令查看自己的外网IP地址
    如何面对30岁?
    JavaScript中this关键字使用方法详解
    发掘WinRAR的“自解压安装”功能
  • 原文地址:https://www.cnblogs.com/nangezi/p/13807307.html
Copyright © 2020-2023  润新知