在Vue中用canvas实现二维码和图片合成海报的方法


Posted in Javascript onJune 10, 2019

在项目中经常会遇到需要将不同的二维码放到一张通用图片上,提供用户下载

简单来说,就是利用canvas将同等比例的二维码在图片上叠加,生成海报

1. 设置相应比例

一般来说海报背景都是固定的,可以直接放在public文件夹,二维码可根据后台返回数据,也可用canvas生成,在此不多赘述

import posterBgImg from '../public/images/poster_bg.png';// 海报底图
import qrcodeImg from '../public/images/qrcode.png';// 二维码
export default{
  name: 'qrcode-in-poster',
  data(){
    return {
      posterBgImg,
      qrcodeImg,
      posterSize: 930/650,// 海报高宽比例
      qrCodeSize: {// 二维码与海报对应比例 =》 用于设置二维码在海报中的位置
        width: 270/650,
        height: 270/930,
        left: 190/650,
        top: 448/650
      },
      poster: '',// 合成图片
    }
  }
};

2. 获取屏幕宽度

限定移动端最大宽度为 480px

computed: {
  screenWidth(){
    let w = document.body.clientWidt || document.documentElement.clientWidth || 375;
    return w > 480 ? 480 : w ;
  }
};

3. 组合图片

methods: {
  combinedPoster(_url){
    let that = this,
      qrcode = this.qrcodeImg; // 二维码地址
  
    console.log("open draw: ", _url, qrcode)
    let base64 = '',
      canvas = document.createElement('canvas'),
      ctx = canvas.getContext("2d"),
      _w = this.screenWidth * 2, // 图片宽度: 由于手机屏幕时retina屏,都会多倍渲染,在此只设置2倍,如果直接设置等于手机屏幕,会导致生成的图片分辨率不够而模糊
      _h = this.posterSize * _w, // 图片高度
      _qr_w = this.qrCodeSize.width * _w, // 二维码宽 = 比例 * 宽度
      _qr_h = this.qrCodeSize.height * _h, // 二维码高 = 比例 * 高度
      _qr_t = this.qrCodeSize.top * _w, // 二维码顶部距离 = 比例 * 宽度
      _qr_l = this.qrCodeSize.left * _w; // 二维码左侧距离 = 比例 * 宽度
    // 设置canvas宽高  
    canvas.width = _w; 
    canvas.height = _h;
    ctx.rect(0, 0, _w, _h);
    ctx.fillStyle = '#fff'; // 填充颜色
    ctx.fill();
    // 迭代生成: 第一层(底图)+ 第二层(二维码)
    // file:文件,size:[顶部距离,左侧距离,宽度,高度]
    let _list = [ 
      {
        file: _url,
        size: [0, 0, _w, _h]
      }, {
        file: qrcode,
        size: [_qr_l, _qr_t, _qr_w, _qr_h]
      }
    ];
    // 开始绘画
    let drawing = (_index) => {
      // 判断当前索引 =》 是否已绘制完毕
      if (_index < _list.length) {
        // 等图片预加载后画图
        let img = new Image(),
          timeStamp = new Date().getTime();
        // 防止跨域
        img.setAttribute('crossOrigin', 'anonymous')
        // 链接加上时间戳
        img.src = _list[_index].file + '?' + timeStamp
        img.onload = function() {
          // 画图
          ctx.drawImage(img, ..._list[_index].size)
          // 递归_list
          drawing(_index + 1)
        }
      } else {
        // 生成图片
        base64 = canvas.toDataURL("image/png")
        if (base64) {
          // 赋值相应海报上
          this.$set(that, 'poster', base64)
        }
      }
    }
    drawing(0)
  }
};
mounted(){
  // 需要合成海报的图片
  this.draw(this.posterBgImg)
}

4. 下载

点击下载合成图片

methods: {
  handleDownload(){
    if(this.poster){
      let a = document.createElement("a");
      a.setAttribute("download", "海报下载-"+(new Date().getTime()));
      a.href = this.poster
      a.click()
    }else{
      console.log("海报不存在,请重新生成!")
    }
  }
}

tips:不适用于微信浏览器,只能提示用户长按保存。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
28个JS验证函数收集
Mar 02 Javascript
Jquery显示、隐藏元素以及添加删除样式
Aug 09 Javascript
jquery实现在光标位置插入内容的方法
Feb 05 Javascript
在JavaScript中使用对数Math.log()方法的教程
Jun 15 Javascript
Node.js的Web模板引擎ejs的入门使用教程
Jun 06 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
Aug 02 Javascript
C#微信小程序服务端获取用户解密信息实例代码
Mar 10 Javascript
vue一步步实现alert功能
Jul 05 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
Nov 22 Javascript
基于axios 解决跨域cookie丢失的问题
Sep 26 Javascript
JS实现基本的网页计算器功能示例
Jan 16 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
Mar 20 jQuery
vue中使用 pako.js 解密 gzip加密字符串的方法
Jun 10 #Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
Jun 10 #Javascript
利用百度echarts实现图表功能简单入门示例【附源码下载】
Jun 10 #Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
Jun 10 #jQuery
利用Electron简单撸一个Markdown编辑器的方法
Jun 10 #Javascript
js实现类似iphone的网页滑屏解锁功能示例【附源码下载】
Jun 10 #Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
Jun 10 #jQuery
You might like
收音机史话 - 1960年代前后的DIY
2021/03/02 无线电
php下使用SimpleXML 处理XML 文件
2010/02/27 PHP
利用PHP实现短域名互转
2013/07/05 PHP
PHP动态页生成静态页的3种常用方法
2014/11/13 PHP
Javascript实现的分页函数
2007/02/07 Javascript
深入理解JavaScript系列(14) 作用域链介绍(Scope Chain)
2012/04/12 Javascript
利用js实现选项卡的特别效果的实例
2013/03/03 Javascript
JSP跨iframe如何传递参数实现代码
2013/09/21 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
jQuery获得document和window对象宽度和高度的方法
2015/03/25 Javascript
JS基于面向对象实现的拖拽功能示例
2016/12/20 Javascript
jQuery倒计时代码(超简单)
2017/02/27 Javascript
Angular中$state.go页面跳转并传递参数的方法
2017/05/09 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
Popup弹出框添加数据实现方法
2017/10/27 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
Node.js 实现远程桌面监控的方法步骤
2019/07/02 Javascript
IE11下处理Promise及Vue的单项数据流问题
2019/07/24 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
Ant Design Pro 下实现文件下载的实现代码
2019/12/03 Javascript
简单的连接MySQL与Python的Bottle框架的方法
2015/04/30 Python
Python实现将目录中TXT合并成一个大TXT文件的方法
2015/07/15 Python
对json字符串与python字符串的不同之处详解
2018/12/19 Python
Python函数的参数常见分类与用法实例详解
2019/03/30 Python
Python3 读取Word文件方式
2020/02/13 Python
Python实现队列的方法示例小结【数组,链表】
2020/02/22 Python
Windows和Linux动态库应用异同
2016/07/28 面试题
英语专业职业生涯规划范文
2014/03/05 职场文书
成语的广告词
2014/03/19 职场文书
社区食品安全实施方案
2014/03/28 职场文书
如何写好自荐信
2014/04/07 职场文书
团拜会策划方案
2014/06/07 职场文书
党的群众路线教育实践活动自我剖析材料
2014/10/08 职场文书
人事任命通知书
2015/04/21 职场文书
解决numpy数组互换两行及赋值的问题
2021/04/17 Python