在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 使用手册(二)
Sep 23 Javascript
中文字符串截取的js函数代码
Apr 17 Javascript
js实现点击链接后延迟3秒再跳转的方法
Jun 05 Javascript
js中flexible.js实现淘宝弹性布局方案
Jun 23 Javascript
jQuery通过写入cookie实现更换网页背景的方法
Apr 15 Javascript
AngularJS基础 ng-show 指令简单示例
Aug 03 Javascript
怎样判断jQuery当前元素是隐藏还是显示
Nov 23 Javascript
JS解析url查询参数的简单代码
Aug 06 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 Javascript
layui数据表格 table.render 报错的解决方法
Sep 29 Javascript
原生js实现点击轮播切换图片
Feb 11 Javascript
js实现点击按钮随机生成背景颜色
Sep 05 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 htmlentities和htmlspecialchars 的区别
2008/08/18 PHP
探讨:如何通过stats命令分析Memcached的内部状态
2013/06/14 PHP
一款简单实用的php操作mysql数据库类
2014/12/08 PHP
几个优化WordPress中JavaScript加载体验的插件介绍
2015/12/17 PHP
javascript来定义类的规范小结
2010/11/19 Javascript
JavaScript Accessor实现说明
2010/12/06 Javascript
JS操作Cookies包括(读取添加与删除)
2012/12/26 Javascript
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
js调试工具console.log()方法查看js代码的执行情况
2014/08/08 Javascript
12行javascript代码绘制一个八卦图
2015/04/02 Javascript
使用AngularJS创建自定义的过滤器的方法
2015/06/18 Javascript
微信小程序实现蒙版弹窗效果
2018/11/01 Javascript
node.js通过url读取文件
2020/10/16 Javascript
js闭包和垃圾回收机制示例详解
2021/03/01 Javascript
在Python中使用异步Socket编程性能测试
2014/06/25 Python
Python中Unittest框架的具体使用
2019/08/27 Python
基于Django框架的权限组件rbac实例讲解
2019/08/31 Python
关于numpy中eye和identity的区别详解
2019/11/29 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
python3 使用openpyxl将mysql数据写入xlsx的操作
2020/05/15 Python
python中复数的共轭复数知识点总结
2020/12/06 Python
巴西网上药房:onofre
2016/11/21 全球购物
英国性感内衣和睡衣品牌:Bluebella
2018/01/26 全球购物
Madewell澳大利亚官方网站:美国休闲服饰品牌
2019/07/18 全球购物
Ooni英国官网:披萨烤箱
2020/05/31 全球购物
信息管理专业学生自荐信格式
2013/09/22 职场文书
新闻网站实习自我鉴定
2013/09/25 职场文书
会计专业大学生求职信范文
2014/01/28 职场文书
房屋所有权证明
2014/10/20 职场文书
小学教师见习总结
2015/06/23 职场文书
护士工作心得体会
2016/01/25 职场文书
mysql知识点整理
2021/04/05 MySQL
Python数据分析之pandas函数详解
2021/04/21 Python
一行代码python实现文件共享服务器
2021/04/22 Python
python绘制简单直方图(质量分布图)的方法
2022/04/21 Python
Python中的 enumerate和zip详情
2022/05/30 Python