在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 相关文章推荐
JavaScript 创建对象和构造类实现代码
Jul 30 Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 Javascript
jQuery创建插件的代码分析
Apr 14 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
Feb 18 Javascript
浅析js封装和作用域
Jul 09 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
Feb 12 Javascript
javascript常用代码段搜集
Dec 04 Javascript
jQuery在ul中显示某个li索引号的方法
Mar 17 Javascript
jQuery移动端日期(datedropper)和时间(timedropper)选择器附源码下载
Apr 19 Javascript
jQuery实现底部浮动窗口效果
Sep 07 Javascript
jQuery实现弹窗下底部页面禁止滑动效果
Dec 19 jQuery
基于Vue实现可以拖拽的树形表格实例详解
Oct 18 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文件
2007/01/04 PHP
PHP伪静态写法附代码
2008/06/20 PHP
MySql 按时间段查询数据方法(实例说明)
2008/11/02 PHP
PHP 函数学习简单小结
2010/07/08 PHP
php中配置文件操作 如config.php文件的读取修改等操作
2012/07/07 PHP
php中addslashes函数与sql防注入
2014/11/17 PHP
php通过strpos查找字符串出现位置的方法
2015/03/17 PHP
PHP Opcache安装和配置方法介绍
2015/05/28 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
扩展jQuery 键盘事件的几个基本方法
2009/10/30 Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
2010/10/20 Javascript
js格式化货币数据实现代码
2013/09/04 Javascript
javascript模拟实现C# String.format函数功能代码
2013/11/25 Javascript
js实现鼠标悬浮给图片加边框的方法
2015/01/30 Javascript
Javascript中的方法和匿名方法实例详解
2015/06/13 Javascript
Javascript编写俄罗斯方块思路及实例
2015/07/07 Javascript
JavaScript数据存储 Cookie篇
2016/07/02 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
vue 之 .sync 修饰符示例详解
2018/04/21 Javascript
JavaScript单线程和任务队列原理解析
2020/02/04 Javascript
python复制与引用用法分析
2015/04/08 Python
Python输出各行命令详解
2018/02/01 Python
python 检查文件mime类型的方法
2018/12/08 Python
解决Python3 被PHP程序调用执行返回乱码的问题
2019/02/16 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
Python基于os.environ从windows获取环境变量
2020/06/09 Python
python实现canny边缘检测
2020/09/14 Python
详解使用postMessage解决iframe跨域通信问题
2019/11/01 HTML / CSS
美国最值得信赖的宠物药房:Allivet
2019/03/23 全球购物
亚马逊巴西站:Amazon.com.br
2019/09/22 全球购物
群胜软件Java笔试题
2012/09/29 面试题
父亲八十大寿答谢词
2014/01/23 职场文书
高中生班主任评语
2014/04/25 职场文书
党的群众路线教育实践活动总结报告
2014/04/28 职场文书
感恩母亲节演讲稿
2014/05/07 职场文书