在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中处理XML数据的大致方法
Aug 14 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
Nov 30 Javascript
深入php面向对象、模式与实践
Feb 16 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
Apr 19 Javascript
Javascript实现基本运算器
Jul 15 Javascript
vue如何使用 Slot 分发内容实例详解
Sep 05 Javascript
JavaScript动态绑定详解
Sep 14 Javascript
VUE element-ui 写个复用Table组件的示例代码
Nov 18 Javascript
Vue.js搭建移动端购物车界面
Jun 28 Javascript
快速对接payjq的个人微信支付接口过程解析
Aug 15 Javascript
jQuery实现每日秒杀商品倒计时功能
Sep 06 jQuery
vue点击自增和求和的实例代码
Nov 06 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 UTF8中文字符截断函数代码
2012/09/11 PHP
PHP使用DOM和simplexml读取xml文档的方法示例
2017/02/08 PHP
用js实现手把手教你月入万刀(转贴)
2007/11/07 Javascript
javaScript 判断字符串是否为数字的简单方法
2009/07/25 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
禁止选中文字兼容IE、Chrome、FF等
2013/09/04 Javascript
利用jQuery简单实现产品展示图片左右滚动功能(示例代码)
2014/01/02 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
浅谈javascript的分号的使用
2015/05/12 Javascript
用Move.js配合创建CSS3动画的入门指引
2015/07/22 Javascript
聊聊那些使用前端Javascript实现的机器学习类库
2017/09/18 Javascript
JavaScript实现重力下落与弹性效果的方法分析
2017/12/20 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
vue+moment实现倒计时效果
2019/08/26 Javascript
js图数据结构处理 迪杰斯特拉算法代码实例
2019/09/11 Javascript
微信小程序自定义组件components(代码详解)
2019/10/21 Javascript
js实现列表按字母排序
2020/08/11 Javascript
[02:17]2016国际邀请赛中国区预选赛VG战队领队采访
2016/06/26 DOTA
Python 登录网站详解及实例
2017/04/11 Python
windows下Virtualenvwrapper安装教程
2017/12/13 Python
python学习开发mock接口
2019/04/28 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
Django 博客实现简单的全文搜索的示例代码
2020/02/17 Python
Expected conditions模块使用方法汇总代码解析
2020/08/13 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
大学自荐信
2013/12/12 职场文书
四群教育工作实施方案
2014/03/26 职场文书
出生公证书样本
2014/04/04 职场文书
教师作风整改措施思想汇报
2014/10/12 职场文书
外贸采购员岗位职责
2015/04/03 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
运动会观后感
2015/06/09 职场文书
一个家长教育孩子的心得体会
2016/01/15 职场文书
MySQL8.0.18配置多主一从
2021/06/21 MySQL