在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 相关文章推荐
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
Jan 09 Javascript
使用jQuery简化Ajax开发 Ajax开发入门
Oct 14 Javascript
jquery无缝向上滚动实现代码
Mar 29 Javascript
解析Javascript小括号“()”的多义性
Dec 03 Javascript
js中日期的加减法
May 06 Javascript
js老生常谈之this,constructor ,prototype全面解析
Apr 05 Javascript
jQuery防止重复绑定事件的解决方法
May 14 Javascript
全面了解函数声明与函数表达式、变量提升
Aug 09 Javascript
如何用webpack4带你实现一个vue的打包的项目
Jun 20 Javascript
JavaScript数据结构与算法之二叉树添加/删除节点操作示例
Mar 01 Javascript
react使用CSS实现react动画功能示例
May 18 Javascript
微信小程序实现左滑删除效果
Nov 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引用(&amp;)
2014/09/04 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
javascript实现轮显新闻标题链接
2007/08/13 Javascript
火狐浏览器(firefox)下获得Event对象以及keyCode
2008/11/13 Javascript
jquery 简短右键菜单 多浏览器兼容
2010/01/01 Javascript
JavaScript高级程序设计 扩展--关于动态原型
2010/11/09 Javascript
js中的eventType事件及其浏览器支持性介绍
2013/11/29 Javascript
Nodejs极简入门教程(二):定时器
2014/10/25 NodeJs
javascript实现跨域的方法汇总
2015/06/25 Javascript
浅谈JavaScript中的作用域和闭包问题
2015/07/07 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
2017/02/28 Javascript
js+canvas实现动态吃豆人效果
2017/03/22 Javascript
js模仿微信朋友圈计算时间显示几天/几小时/几分钟/几秒之前
2017/04/27 Javascript
vue 中动态绑定class 和 style的方法代码详解
2018/06/01 Javascript
深入分析element ScrollBar滚动组件源码
2019/01/22 Javascript
iSlider手机端图片滑动切换插件使用详解
2019/12/24 Javascript
js基于canvas实现时钟组件
2021/02/07 Javascript
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
通过C++学习Python
2015/01/20 Python
Python中操作mysql的pymysql模块详解
2016/09/13 Python
Python爬取当当、京东、亚马逊图书信息代码实例
2017/12/09 Python
使用Python更换外网IP的方法
2018/07/09 Python
解决pycharm运行时interpreter为空的问题
2018/10/29 Python
python3爬虫怎样构建请求header
2018/12/23 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
2020/03/18 Python
Numpy 理解ndarray对象的示例代码
2020/04/03 Python
英国健身专家:WIT Fitness
2021/02/09 全球购物
在校生汽车维修实习自我鉴定
2013/09/19 职场文书
元旦联欢会策划方案
2014/06/11 职场文书
幼儿园教师考核评语
2014/12/31 职场文书
单位实习鉴定评语
2015/01/04 职场文书
从事会计工作年限证明
2015/06/23 职场文书
《弟子规》读后感:知廉耻、明是非、懂荣辱、辨善恶
2019/12/03 职场文书
零基础学java之带参数以及返回值的方法
2022/04/10 Java/Android
pytorch实现加载保存查看checkpoint文件
2022/07/15 Python