html2canvas(将dom元素转为canvas),wxml2canvas(微信小程序)_小程序 html2canvas-程序员宅基地

技术标签: 微信小程序  小程序  

某些场景需要通过 canvas 绘制一些图片, 其中包含一些文字、可能的二维码等等。 然后实现时如果完全手动的去定位元素在 canvas 中的位置,结果就会产生大量不能复用和难以维护的代码。(使用背景图可能会模糊,可以使用img,结合定位)

html2canvas

1.安装

npm install --save html2canvas

  也可以直接官网下载js文件 然后引用

  2. 使用

//按自己的文件位置引用
import html2canvas from "../../utils/html2canvas.js";

canvasfun() {
      //把你需要转为图片的标签放在一个根元素内 直接获取根元素
      let save2 = document.getElementsByClassName('list')[0];
      html2canvas(save2,{
        useCORS: true  //很重要支持跨域图片,否则需要自己将线上图片转为本地图片(转base64)
      }).then((canvas) => {
        //利用a标签实现下载(浏览器环境)
        let url = canvas.toDataURL("image/png");
        let aLink = document.createElement("a");
        aLink.style.display = "none";
        url.replace(/^data:image\/png/, "data:application/octet-stream")
        aLink.href = url;
        aLink.download = "截图.png";
        document.body.appendChild(aLink);
        aLink.click();
        document.body.removeChild(aLink);
        console.log(canvas)

//***********************************************************
        //小程序webview页面
        let url = canvas.toDataURL("image/png");
        url.replace(/^data:image\/png/, "data:application/octet-stream")
        console.log(canvas)
        wx.miniProgram.postMessage({
          data: { 
            base64: url
          }
        });
        //触发 wx.miniProgram.postMessage的bindmessage
        wx.miniProgram.redirectTo({
          url: '此页面路径',
        })



      });
    },

 3.属性

属性名 默认值 描述
allowTaint false 是否允许跨域图像。会污染画布,导致无法使用canvas.toDataURL 方法
backgroundColor #ffffff 画布背景色(如果未在DOM中指定)。设置null为透明
canvas null 现有canvas元素用作绘图的基础

foreignObjectRendering

false 如果浏览器支持,是否使用ForeignObject渲染
imageTimeout 15000 加载图像的超时时间(以毫秒为单位)。设置0为禁用超时。
ignoreElements (element) => false 谓词功能,可从渲染中删除匹配的元素
logging true 启用日志以进行调试
onclone null 克隆文档以进行渲染时调用的回调函数可用于修改将要渲染的内容,而不会影响原始源文档。
proxy null 代理将用于加载跨域图像的网址。如果保留为空,则不会加载跨域图像。
removeContainer true 是否清除html2canvas临时创建的克隆DOM元素
scale

window.devicePixelRatio

用于渲染的比例。默认为浏览器设备像素比率。(图片清晰控制)
useCORS false 是否尝试使用CORS从服务器加载图像
width Element width canvas的宽度
height Element height canvas的高度
x Element x-offset 裁剪画布X坐标
y Element y-offset 裁剪画布y坐标
scrollX Element scrollX 渲染元素时要使用的x滚动位置(例如,如果Element使用position: fixed)
scrollY Element scrollY 呈现元素时要使用的y-scroll位置(例如,如果Element使用position: fixed)
windowWidth Window.innerWidth 渲染时使用的窗口宽度Element,这可能会影响媒体查询之类的内容
windowHeight Window.innerHeight

渲染时要使用的窗口高度Element,这可能会影响媒体查询之类的内容

如果应用在小程序webview中,需要将base64传到小程序端通过 wx.miniProgram.postMessage(小程序后退、组件销毁、分享、复制链接才会触发)传,然后再web-view标签上绑定bindmessage="callback",通过wx.miniProgram.redirectTo重新打开此页面触发(看着最合适的方式)

//接上面webview的代码
<web-view src="{
   {srchtml}}"  bindmessage="callback"/>




callback(e){
      var data = e.detail.data
      console.log(data)

      let img =  e.detail.data[data.length-1].base64
      let imgname = new Date().getTime()

      wx.getFileSystemManager().writeFile({
      filePath: wx.env.USER_DATA_PATH + '/'+ imgname + '.png',  //这里先把文件写到临时目录里. 
      data: img.slice(22), //****************
      encoding: 'base64',
      success: res => {
        console.log('success')
        wx.saveImageToPhotosAlbum({
          filePath: wx.env.USER_DATA_PATH + '/'+ imgname + '.png', //这是把临时文件 保存到 相册
          success: res => {
            wx.showToast({ title: '保存成功!' })
          },
          fail: error => { console.log(error) }
        })
      },
      fail: error => { console.log(error) }
    })
    },

wxml2canvas

有的github上的文件有点问题

这里拷js文件,把demo下载下来跑一遍

分析一下

 drawCanvas() {
    wx.showLoading()
    const that = this
    const query = wx.createSelectorQuery().in(this);
    query.select('#wrapper').fields({ // 选择需要生成canvas的范围
        size: true,
        scrollOffset: true
    }, data => {
        let width = data.width;
        let height = data.height;
        that.setData({
            width,
            height
        })
        setTimeout(() => {
            that.startDraw()
        }, 1500);
   }).exec()
},
startDraw() {
    let that = this
     
    // 创建wxml2canvas对象
    let drawMyImage = new wxml2canvas({
      element: 'canvas-map', // canvas的id,
      obj: that, // 传入当前组件的this
      width: that.data.width * 2,
      height: that.data.height * 2,
      background: '#141415', // 生成图片的背景色
      progress(percent) { // 进度
        // console.log(percent);
      },
      finish(url) { // 生成的图片
        wx.hideLoading()
        console.log(url)
        that.savePoster(url)
      },
      error(res) { // 失败原因
        console.log(res);
        wx.hideLoading()
      }
    }, this);
    let data = {
        // 获取wxml数据
        list: [{
            type: 'wxml',
            class: '.draw .draw1',  // draw要绘制的wxml元素根类名, draw1单个元素的类名(所有所有所有要绘制的单个元素都要添加该类名)
            limit: '.draw', // 要绘制的wxml元素根根根类名
            x: 0,
            y: 0
        }]
    }
    // 绘制canvas
    
    drawMyImage.draw(data, this)
},
savePoster() {
    const that = this
    wx.saveImageToPhotosAlbum({
        filePath: that.data.imgUrl,
        success: function() {
            wx.showToast({
                title: '保存成功',
                icon: 'none',
                duration: 1500
            });
        },
        fail(err) {
          if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
            wx.showModal({
              title: '提示',
              content: '需要您授权保存相册',
              showCancel: false,
              success: modalSuccess => {
                wx.openSetting({
                  success(settingdata) {
                    if (settingdata.authSetting['scope.writePhotosAlbum']) {
                        wx.saveImageToPhotosAlbum({
                            filePath: that.data.imgUrl,
                            success: function () {
                              wx.showToast({
                                title: '保存成功',
                                icon: 'success',
                                duration: 2000
                              })
                            },
                        })
                    } else {
                        wx.showToast({
                            title: '授权失败,请稍后重新获取',
                            icon: 'none',
                            duration: 1500
                        });
                    }
                  }
                })
              }
            })
          }
        }
      })
  },

还有 wxml-to-canvas(小程序官方) 等插件

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45536315/article/details/131051457

智能推荐

Beats:如何在 Docker 容器中运行 Filebeat_must use asl logging (which requires cgo) if runni-程序员宅基地

文章浏览阅读3.1k次。今天在这篇博客中,我们将学习如何在容器环境中运行 Filebeat。我们在 Host 机器上部署 Elasticsearch 及 Kibana。然后在 Docker 里部署 NGINX。我们使用 Filebeat 来收集 NGINX 里的日志。这个想法是 Filebeat 容器应该从客户端机器上运行的所有容器收集所有日志,并将它们发送到主机上运行的 Elasticsearch。我的主机的 IP 地址是 192.168.0.3。_must use asl logging (which requires cgo) if running as root

布置theano(Windows10,无cuda)-程序员宅基地

文章浏览阅读202次。软件包准备1、Anaconda 下载地址,包含python、numpy、scipy、nose、pip等包,嗯,很爽。2、tdm64-gcc 下载地址,windows下的gcc、g++编译器,用来theano性能优化的,不然速度会很慢(官方文档如是说)3、theano源码 下载地址,github上的实时更新的thenao源码,可以下载zip包,或者clone。一、安装Anacon..._theano .thanorc.txt

猫眼电影MySQL数据库怎么写_MySQL简要分析猫眼电影TOP100榜-程序员宅基地

文章浏览阅读1.9k次。作者:国服帅座 经济学在读硕士公众号:统计之家提出问题对于广大电影爱好者来说,猫眼平台提供了海量电影信息。在其官网上有一个TOP100榜单,我们使用SQL语句简单分析该榜单电影,试图了解如下这些信息。评分最高的电影评分最低的电影上映时间最早的电影周星驰主演的电影按年份统计上映电影数量分别统计喜剧片和恐怖片的数量观影时间超过180分钟的电影获得数据本文数据由笔者利用selenium爬取,爬虫代码附在..._pymysql猫眼电影

NUll的作用和意义_null指针的地址-程序员宅基地

文章浏览阅读2.9k次,点赞2次,收藏16次。空地址NULL意义所在深入核心技术与架构,分享典型创新之道,全景展现全栈式分析服务主题演讲和6大分会场,40+前沿技术主题,尽在亚马逊云科技数据驱动在线峰会NULL其地址值为0,而由于任何进程的0地址开始存储的都是系统关键地址,比如进程的退出,堆栈维护,键盘处理等系统控制程序的地址。因此0地址是不允许用户代码中直接读写访问的(hacking除外),如果某指针被赋予NULL,之后该指针被用来操作对象或内存,要么在编译时报错,要么运行时程序崩溃。指针被赋值为NULL的意义在于,将NULL作为唯一无效指针_null指针的地址

基础概念——TP、FP、TN、FN、IOU、PR、AP、Interpolated AP、AUC、mAP_tp,fp-程序员宅基地

文章浏览阅读5.6k次,点赞2次,收藏17次。TP、FP、TN、FN都是站在预测的立场看的:TP:预测为正是正确的FP:预测为正是错误的TN:预测为负是正确的FN:预测为负是错误的准确率(accuracy),精确率(Precision)和召回率(Recall)准确度:分类器正确分类的样本数与总样本数之比(TP+TN)/ (TP+TN+FP+FN)精确度:所有被预测为正样本的样本中预测对的比例(TP) / (TP+NP)召回率:被正确预测的正样本占所有正样本的比例(TP)/ (TP+FN)..._tp,fp

angular4项目中引入ngx-bootstrap模块步骤_angular 安装ngx bootstrap-程序员宅基地

文章浏览阅读424次。1、引入ngx-bootstrapnpm install ngx-bootstrap -save用cnpm的把npm改为cnpm即可,这时你会发现在你的package.json中包含有ngx-bootstrap,此时引入成功,但是此时只是引入了逻辑文件,bootstrap的样式需要自己引入全局文件中2、引入bootstrap的css文件在index.html文件中引入即可(要保证你的b..._angular 安装ngx bootstrap

随便推点

Chrome中的消息循环-程序员宅基地

文章浏览阅读182次。主要是自己做个学习笔记吧,我经验也不是很丰富,以前学习多线程的时候就感觉写多线程程序很麻烦。主要是线程之间要通信,要切线程,要同步,各种麻烦。我本身的工作经历决定了也没有太多的工作经验,所以chrome的messageloop可以说是我用到的第一个成熟的线程消息封装库,用的很简单,舒服。主要涉及MessageLoop和MessagePump这两个类系。以前不太清楚chrome当时在设计这两..._chrome taskloop

ymail 客户端 android,Android-YMail-Warmtel-程序员宅基地

文章浏览阅读1.9k次。package com.mail163.email.util;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io...._ymail客户端设置

python报错:Cannot run the event loop while another loop is running-程序员宅基地

文章浏览阅读2.9k次。在教程中:执行这行代码会报错:Cannot run the event loop while another loop is running解决方法:在 jupyter-notebook 的一个单元格中输入:!pip install nest_asyncioimport nest_asyncionest_asyncio.apply()_cannot run the event loop while another loop is running

vite使用总结_postcss-preset-env vite-程序员宅基地

文章浏览阅读493次,点赞9次,收藏3次。今天就到这,下次想到再更新!_postcss-preset-env vite

python都学什么啊-那些效率高的人都在偷偷学什么?-程序员宅基地

文章浏览阅读319次。原标题:那些效率高的人都在偷偷学什么?提起潘石屹,你的印象是不是还停留在“SOHO中国”、“房产大亨”的标签上?那你真是“图样图森破”!潘总搞木工、玩摄影,兴趣广泛,现在已经把手伸到Python去了。去年年底,他在微博上表示, 自己将开始学习新的语言Python,作为自己人生的礼物,并且实实在在有坚持学习,还每天打卡#用Python解决100个问题#。 咋一看,一个年过半百的房地产大佬,怎么想都和..._python都学什么

Ryu控制器部署及其与Rest API接口调用问题解决_调用ryu的api-程序员宅基地

文章浏览阅读2.1k次。系统环境为Ubuntu14.04所用restful接口调用软件为postman首先要安装部署Ryu控制器,这个很多人没成功我觉得其实主要是前面的基本环境和依赖包要先搞好,即以下步骤一所示: 步骤一:依赖环境安装sudo apt-get updatesudo apt-get install gitsudo apt-get install Python-pip build-es_调用ryu的api