在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实现UTF8编码转换成gb2312编码
Dec 22 Javascript
IE6下js通过css隐藏select的一个bug
Aug 16 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
Feb 01 Javascript
Javascript的表单验证-初识正则表达式
Mar 18 Javascript
jQuery 限制输入字符串长度
Jun 20 Javascript
js实现精确到毫秒的倒计时效果
Aug 05 Javascript
深入理解bootstrap框架之第二章整体架构
Oct 09 Javascript
vue 虚拟dom的patch源码分析
Mar 01 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
Oct 25 Javascript
微信小程序实现多选删除列表数据功能示例
Jan 15 Javascript
layerui代码控制tab选项卡,添加,关闭的实例
Sep 04 Javascript
js数组中去除重复值的几种方法
Aug 03 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设计模式中的工厂模式
2008/06/12 PHP
ThinkPHP模型详解
2015/07/27 PHP
thinkphp3.2.3 分页代码分享
2016/07/28 PHP
Zend Framework分发器用法示例
2016/12/11 PHP
php实现查询功能(数据访问)
2017/05/23 PHP
laravel手动创建数组分页的实现代码
2018/06/07 PHP
jQuery 获取对象 基本选择与层级
2010/05/31 Javascript
纯js网页画板(Graphics)类简介及实现代码
2012/12/24 Javascript
javascript表单验证 - Parsley.js使用和配置
2013/01/25 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
javascript验证身份证号
2015/03/03 Javascript
javascript基于DOM实现省市级联下拉框的方法
2015/05/14 Javascript
浅谈Javascript中Object与Function对象
2015/09/26 Javascript
Angularjs处理页面闪烁的解决方法
2017/03/09 Javascript
vue 的keep-alive缓存功能的实现
2018/03/22 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
2018/06/19 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
2019/03/01 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
2020/03/09 Javascript
微信小程序轮播图swiper代码详解
2020/12/01 Javascript
Python实现简单多线程任务队列
2016/02/27 Python
django实现用户登陆功能详解
2017/12/11 Python
微信跳一跳python辅助软件思路及图像识别源码解析
2018/01/04 Python
Python自定义线程池实现方法分析
2018/02/07 Python
详解python中eval函数的作用
2019/10/22 Python
大家都说好用的Python命令行库click的使用
2019/11/07 Python
python 读取更新中的log 或其它文本方式
2019/12/24 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
HTML5 中新的全局属性(整理)
2013/07/31 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
爱情检讨书大全
2014/01/21 职场文书
环保建议书400字
2014/05/14 职场文书
红色电影观后感
2015/06/18 职场文书
解析原生JS getComputedStyle
2021/05/25 Javascript
Spring Data JPA框架自定义Repository接口
2022/04/28 Java/Android