在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 相关文章推荐
js返回上一页并刷新代码整理
Dec 21 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
Mar 17 Javascript
多引号嵌套的变量命名的问题
May 09 Javascript
详谈LABJS按需动态加载js文件
May 07 Javascript
jQuery实现的登录浮动框效果代码
Sep 26 Javascript
jQuery实现仿QQ在线客服效果的滚动层代码
Oct 15 Javascript
用JS实现图片轮播效果代码(一)
Jun 26 Javascript
15位和18位身份证JS校验的简单实例
Jul 18 Javascript
深入理解vue-loader如何使用
Jun 06 Javascript
深入理解JS的事件绑定、事件流模型
May 13 Javascript
Node.js API详解之 assert模块用法实例分析
May 26 Javascript
WebStorm无法正确识别Vue3组合式API的解决方案
Feb 18 Vue.js
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
十大催泪虐心动漫电影,有几部你还没看
2020/03/04 日漫
完美解决:Apache启动问题―(OS 10022)提供了一个无效的参数
2013/06/08 PHP
php加密解密实用类分享
2014/01/07 PHP
PHP中isset与array_key_exists的区别实例分析
2015/06/02 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
原生javascript实现拖动元素示例代码
2014/09/01 Javascript
JS实现生成会变大变小的圆环实例
2015/08/05 Javascript
快速学习jQuery插件 Form表单插件使用方法
2015/12/01 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
AngularJS 与Bootstrap实现表格分页实例代码
2016/10/14 Javascript
JavaScript实现的微信二维码图片生成器的示例
2016/10/26 Javascript
基于JavaScript实现拖动滑块效果
2017/02/16 Javascript
jQuery实现文档树效果
2017/02/20 Javascript
原生js实现验证码功能
2017/03/16 Javascript
微信小程序实现拖拽 image 触摸事件监听的实例
2017/08/17 Javascript
解决vue-cli + webpack 新建项目出错的问题
2018/03/20 Javascript
小程序云开发部署攻略(图文教程)
2018/10/30 Javascript
JS/jQuery实现超简单的Table表格添加,删除行功能示例
2019/07/31 jQuery
layui前端时间戳转化实例
2019/11/15 Javascript
[33:15]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VP VS Mineski
2018/03/31 DOTA
Python常用模块介绍
2014/11/21 Python
python实现爬虫下载美女图片
2015/07/14 Python
python中异常报错处理方法汇总
2016/11/20 Python
python脚本爬取字体文件的实现方法
2017/04/29 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
python飞机大战pygame游戏框架搭建操作详解
2019/12/17 Python
对python中各个response的使用说明
2020/03/28 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
资深地理教师自我评价
2013/09/21 职场文书
幼儿园评语大全
2014/04/17 职场文书
新闻专业毕业生求职信
2014/08/08 职场文书
公司仓管员岗位职责
2015/04/01 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书
心理健康教育主题班会
2015/08/13 职场文书
优秀班干部主要事迹材料
2015/11/04 职场文书
新手入门Mysql--sql执行过程
2021/06/20 MySQL