在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 相关文章推荐
Convert Seconds To Hours
Jun 16 Javascript
基于jquery的当鼠标滚轮到最底端继续加载新数据思路分享(多用于微博、空间、论坛 )
Oct 10 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
May 30 Javascript
jquery获取table中的某行全部td的内容方法
Mar 08 Javascript
用js正确判断用户名cookie是否存在的方法
Jan 28 Javascript
javascript中基本类型和引用类型的区别分析
May 12 Javascript
Javascript打印局部页面实例
Jun 21 Javascript
浅谈JS之iframe中的窗口
Sep 13 Javascript
Javascript Event(事件)的传播与冒泡
Jan 23 Javascript
webpack热模块替换(HMR)/热更新的方法
Apr 05 Javascript
详解Vue结合后台的列表增删改案例
Aug 21 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
Apr 30 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/06 PHP
php简单实现发送带附件的邮件
2015/06/10 PHP
帝国cms目录结构分享
2015/07/06 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
2019/03/30 PHP
php设计模式之职责链模式定义与用法经典示例
2019/09/19 PHP
window.parent与window.openner区别介绍
2012/04/12 Javascript
jQuery学习笔记之总体架构
2014/06/03 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
2014/10/10 Javascript
javascript跨域原因以及解决方案分享
2015/04/08 Javascript
js插件设置innerHTML时在IE8下提示“未知运行时错误”解决方法
2015/04/25 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
bootstrap 下拉多选框进行多选传值问题代码分析
2017/02/14 Javascript
ES6中的rest参数与扩展运算符详解
2017/07/18 Javascript
使用百度地图实现地图网格的示例
2018/02/06 Javascript
jQuery实现遍历XML节点和属性的方法示例
2018/04/29 jQuery
python进阶教程之文本文件的读取和写入
2014/08/29 Python
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
2017/03/16 Python
分享6个隐藏的python功能
2017/12/07 Python
pycharm 解除默认unittest模式的方法
2018/11/30 Python
Python实现定时执行任务的三种方式简单示例
2019/03/30 Python
pytorch 共享参数的示例
2019/08/17 Python
使用tensorflow实现矩阵分解方式
2020/02/07 Python
python绘制动态曲线教程
2020/02/24 Python
python切割图片的示例
2020/11/12 Python
详解使用HTML5的classList属性操作CSS类
2017/10/13 HTML / CSS
英国在线自行车商店:Evans Cycles
2016/09/26 全球购物
美国在线健康和美容市场:Pharmapacks
2018/12/05 全球购物
行政总经理岗位职责
2013/12/05 职场文书
夏季药店促销方案
2014/08/22 职场文书
环保项目建议书
2014/08/26 职场文书
领导班子群众路线与四风问题对照检查材料思想汇报
2014/10/11 职场文书
2014年法务工作总结
2014/12/11 职场文书
就业推荐表导师评语
2014/12/31 职场文书
选购到合适的激光打印机
2022/04/21 数码科技