在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 相关文章推荐
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
onclick与listeners的执行先后问题详细解剖
Jan 07 Javascript
Express作者TJ告别Node.js奔向Go
Jul 14 Javascript
浅谈javascript 迭代方法
Jan 21 Javascript
原生js实现addClass,removeClass,hasClass方法
Apr 27 Javascript
jQuery使用ajax跨域获取数据的简单实例
May 18 Javascript
使用jquery如何获取时间
Oct 13 Javascript
WebStorm ES6 语法支持设置&amp;babel使用及自动编译(详解)
Sep 08 Javascript
react中使用swiper的具体方法
May 15 Javascript
Layui数据表格 前后端json数据接收的方法
Sep 19 Javascript
jQuery实现动态向上滚动
Dec 21 jQuery
使用Cargo工具高效创建Rust项目
Aug 14 Javascript
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
缓存技术详谈―php
2006/12/14 PHP
AJAX的跨域访问-两种有效的解决方法介绍
2013/06/22 PHP
php提示Warning:mysql_fetch_array() expects的解决方法
2014/12/16 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
PHP页面输出搜索后跳转下一页的处理方法
2016/09/30 PHP
PHP实现图片压缩
2020/09/09 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
2019/04/17 PHP
jQuery Ajax之load()方法
2009/10/12 Javascript
定义JavaScript二维数组采用定义数组的数组来实现
2012/12/09 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
2013/10/17 Javascript
js获取url中指定参数值的示例代码
2013/12/14 Javascript
详谈nodejs异步编程
2014/12/04 NodeJs
JavaScript针对网页节点的增删改查用法实例
2015/02/02 Javascript
javascript实现无缝上下滚动特效
2015/12/16 Javascript
使用jquery如何获取时间
2016/10/13 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
JS实现简单省市二级联动
2019/11/27 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
2020/09/21 Javascript
[39:08]完美世界DOTA2联赛PWL S3 LBZS vs CPG 第一场 12.12
2020/12/16 DOTA
python批量提交沙箱问题实例
2014/10/08 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
python3操作微信itchat实现发送图片
2018/02/24 Python
处理Selenium3+python3定位鼠标悬停才显示的元素
2019/07/31 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
Pycharm plot独立窗口显示的操作
2020/12/11 Python
英超联赛的首选足球:Mitre足球
2019/05/06 全球购物
高中生毕业学习总结的自我评价
2013/11/14 职场文书
安全责任协议书
2014/04/21 职场文书
小学网上祭英烈活动总结
2014/07/05 职场文书
小平小道观后感
2015/06/09 职场文书
KTV员工管理制度
2015/08/06 职场文书
MySQL 如何限制一张表的记录数
2021/09/14 MySQL
教你修复 Win11应用商店加载空白问题
2021/12/06 数码科技
德劲DE1102数字调谐收音机机评
2022/04/07 无线电
MongoDB数据库之添删改查
2022/04/26 MongoDB