在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 相关文章推荐
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
Mar 04 Javascript
网页打开自动最大化的js代码
Aug 22 Javascript
jQuery之按钮组件的深入解析
Jun 19 Javascript
JavaScript创建对象的方式小结(4种方式)
Dec 17 Javascript
jQuery实现简单滚动动画效果
Apr 07 Javascript
BootStrap无限级分类(无限极分类封装版)
Aug 26 Javascript
Javascript 闭包详解及实例代码
Nov 30 Javascript
原生JS下拉加载插件分享
Dec 26 Javascript
js实现仿购物车加减效果
Mar 01 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
Sep 07 jQuery
Webpack 4如何动态切割JS注入文件名详解
Jul 09 Javascript
javascript设计模式 ? 享元模式原理与用法实例分析
Apr 15 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实现监听事件
2013/11/06 PHP
PHP多文件上传实例
2015/07/09 PHP
ASP.NET jQuery 实例7 通过jQuery来获取DropDownList的Text/Value属性值
2012/02/03 Javascript
JS截取字符串常用方法整理及使用示例
2013/10/18 Javascript
JavaScript 作用域链解析
2014/11/13 Javascript
JavaScript学习心得之概述
2015/01/20 Javascript
jQuery+ajax实现动态执行脚本的方法
2015/01/27 Javascript
Jquery实时监听input value的实例
2017/01/26 Javascript
浅谈js中function的参数默认值
2017/02/20 Javascript
全面解析jQuery中的$(window)与$(document)的用法区别
2017/08/15 jQuery
微信小程序登录按钮遮罩浮层效果的实现方法
2018/12/16 Javascript
Python with的用法
2014/08/22 Python
使用Python脚本对Linux服务器进行监控的教程
2015/04/02 Python
python实现下载指定网址所有图片的方法
2015/08/08 Python
python从入门到精通(DAY 2)
2015/12/20 Python
Python使用dis模块把Python反编译为字节码的用法详解
2016/06/14 Python
Python实现句子翻译功能
2017/11/14 Python
Python实现图片拼接的代码
2018/07/02 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
浅谈Python中的可迭代对象、迭代器、For循环工作机制、生成器
2019/03/11 Python
关于python中密码加盐的学习体会小结
2019/07/15 Python
python控制台实现tab补全和清屏的例子
2019/08/20 Python
基于django 的orm中非主键自增的实现方式
2020/05/18 Python
浅谈CSS3中的变形功能-transform功能
2017/12/27 HTML / CSS
免费获得微软MCSD证书赶快行动吧!
2012/11/13 HTML / CSS
芬兰汽车配件商店:Autonvaraosat24
2017/01/30 全球购物
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
Shopbop中文官网:美国亚马逊旗下时尚购物网站
2020/12/15 全球购物
高级护理专业大学生求职信
2013/10/24 职场文书
应届生人事助理求职信
2013/11/09 职场文书
美工的岗位职责
2013/11/14 职场文书
供电工程专业求职信
2014/08/09 职场文书
2014年法务工作总结
2014/12/11 职场文书
请病假条范文
2015/08/17 职场文书
Python 使用dict实现switch的操作
2021/04/07 Python
图解排序算法之希尔排序Java实现
2021/06/26 Java/Android