Advertisement

微信小程序2D canvas绘制分享海报

阅读量:

效果图:

wxml

复制代码
 <view>

    
 	<canvas type="2d" id="canvas_box" style="width:260px;height:430px "></canvas>
    
 	<button class='bottom' catchtap="bc" canvas-id="mycanvas"> 保存到相册    </button>
    
 </view>

type:指定 canvas 类型

id:canvas 组件的唯一标识符

样式根据自己情况自定义

复制代码
 page{

    
   background: rgb(223, 165, 165);
    
   
    
 }
    
 canvas{
    
   margin:20rpx auto;
    
   border: 1rpx solid #ccc;
    
   background: #fff;
    
   color: #fff;
    
 }

js重点

(完整js代码在最下面)

复制代码
   onReady: function () {

    
     const query = wx.createSelectorQuery()
    
     query.select('#canvas_box')
    
       .fields({
    
     id: true,
    
     node: true,
    
     size: true
    
       })
    
       .exec(this.init.bind(this));
    
   },

id:true 是否返回节点 id

node:true 是否返回节点对应的 Node 实例

size:true 是否返回节点尺寸(width height

wx.createSelectorQuery()

生成一个 SelectorQuery 对象实例,在具有自定义组件的页面中,请确保您使用 this.createSelectorQuery() 来代替当前的方式。

select

在当前页面上定位首个匹配的selector节点,并通过获取该NodesRef对象来实现相关操作。

selector 语法

selector类似于 CSS 的选择器,但仅支持下列语法。

以下是对输入文本的同义改写版本

fields

查询节点相关信息。所需字段需从fields参数中进行指定设置。返回结果为 nodesRef 标识符与 selectorQuery 参数的组合体。

注意

computedStyle 被赋予了更高的 precedence over size;当同时在 computedStyle 中指定了 width 和 height 并且传入了 size: true 时,则会优先返回 computedStyle 所获取到的宽度和高度值。

复制代码
  init(res) {

    
     console.log(res)
    
     const canvas = res[0].node
    
     const ctx = canvas.getContext('2d')
    
     const dpr = wx.getSystemInfoSync().pixelRatio
    
     //新接口需显示设置画布宽高;
    
     canvas.width = res[0].width * dpr
    
     canvas.height = res[0].height * dpr
    
     ctx.scale(dpr, dpr);
    
     this.setData({
    
       canvas,
    
       ctx
    
     });
    
   //向画布方法
    
     this.canvasDraw(ctx);
    
    this.title(ctx);
    
    this.name(ctx)
    
    this.code(ctx).then(rrr=>{
    
     this.hande(ctx)
    
    })
    
   },

wx.getSystemInfoSync() // wx.getSystemInfo 的同步版本

通过Canvas.getContext('d') API可以访问CanvasRenderingContext2D对象,并提供了HTML Canvas 2D Context所定义的功能

画图

复制代码
   canvasDraw(ctx) {

    
     let img = this.data.canvas.createImage(); 
    
     img.src = "img/2.jpg";
    
     img.onload = () => {
    
       this.data.ctx.drawImage(img, 0, 0, 260, 260);
    
     };
    
      
    
   },

let img = this.data.canvas.createImage(); //创建img对象

img.src = "图片地址"

img.onload 图片加载监听

this.data.ctx.drawImage(img, 10, 10, 260, 260); // (图片,左距离,上距离,宽,高)

画文字

复制代码
 title(ctx) {

    
     // ctx.setFontSize(12)
    
     let text = '接小程序开发,web开发,H5开发,小程序云开发,PHP开发'
    
     let moy =  '有需要的直接微信扫码'
    
     ctx.font = 'normal bold 12px sans-serif';
    
     ctx.fillStyle = "rgba(60, 59, 59)";
    
     console.log('======,', text.length)
    
     if (text.length <= 19) {
    
       ctx.fillText(text, 10, 275, 280)
    
       ctx.fillStyle = "rgba(0,0,0)";
    
       ctx.font = 'normal bold 16px sans-serif';
    
       ctx.fillStyle = "red";
    
       ctx.fillText(moy, 10, 290, 280)
    
     }
    
     if (text.length <= 38) {
    
       let firstLine = text.substring(0, 20);
    
       let secondLine = text.substring(20, 38);
    
       ctx.fillText(firstLine, 10, 275, 280)
    
       ctx.fillText(secondLine, 10, 290, 280)
    
       ctx.fillStyle = "rgba(0,0,0)";
    
       ctx.font = 'normal bold 16px sans-serif';
    
       ctx.fillStyle = "red";
    
       ctx.fillText(moy, 10, 315, 280)
    
     } else {
    
       let firstLine = text.substring(0, 20);
    
       let secondLine = text.substring(20, 38) + '...';
    
       ctx.fillText(firstLine, 10, 280, 280)
    
       ctx.fillText(secondLine, 10, 295, 280)
    
       ctx.font = 'normal bold 16px sans-serif';
    
       ctx.fillStyle = "red";
    
       ctx.fillText(moy, 10, 320, 280)
    
     }
    
      
    
   },

保存到相册

普通的保存

复制代码
 wx.canvasToTempFilePath({

    
   x: 100,
    
   y: 200,
    
   width: 50,
    
   height: 50,
    
   destWidth: 100,
    
   destHeight: 100,
    
   canvasId: 'myCanvas',
    
   success(res) {
    
     console.log(res.tempFilePath)
    
   }
    
 })

2d的保存

复制代码
   bc() {

    
     // 保存到相册
    
     console.log('保存canvasId',this.data.canvas._canvasId)
    
     wx.canvasToTempFilePath({     //将canvas生成图片
    
       canvas:this.data.canvas,
    
       x: 0,
    
       y: 0,
    
       width: this.data._width,
    
       height: this.data._height,
    
       destWidth: this.data._width,     //截取canvas的宽度
    
       destHeight:this.data._height,   //截取canvas的高度
    
       success: function (res) {
    
     console.log('生成图片成功:',res)
    
     wx.saveImageToPhotosAlbum({  //保存图片到相册
    
       filePath: res.tempFilePath,
    
       success: function () {
    
         wx.showToast({
    
           title: "保存图片成功!",
    
           duration: 2000
    
         })
    
       }
    
     })
    
  
    
       },
    
     },this)
    
  
    
   },

请留意区分二者的主要差别,请参考官方文档https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.canvasToTempFilePath.html

完整js代码

复制代码
 Page({

    
   data: {
    
  
    
   },
    
   onLoad: function () {
    
  
    
   },
    
   onReady: function () {
    
     const query = wx.createSelectorQuery()
    
     query.select('#canvas_box')
    
       .fields({
    
     id: true,
    
     node: true,
    
     size: true
    
       })
    
       .exec(this.init.bind(this));
    
   },
    
   init(res) {
    
     console.log(res)
    
     const canvas = res[0].node
    
     const ctx = canvas.getContext('2d')
    
     const dpr = wx.getSystemInfoSync().pixelRatio
    
     //新接口需显示设置画布宽高;
    
     canvas.width = res[0].width * dpr
    
     canvas.height = res[0].height * dpr
    
     ctx.scale(dpr, dpr);
    
     this.setData({
    
       canvas,
    
       ctx
    
     });
    
   //向画布载入图片的方法
    
     this.canvasDraw(ctx);
    
   //向画布载入标题的方法
    
    this.title(ctx);
    
    this.name(ctx)
    
    this.code(ctx).then(rrr=>{
    
    // 头像加载
    
   this.hande(ctx)
    
    })
    
   },
    
   // 封面图
    
   canvasDraw(ctx) {
    
     let img = this.data.canvas.createImage(); //创建img对象
    
     img.src = "img/2.jpg";
    
     img.onload = () => {
    
       console.log(img.complete); //true
    
       this.data.ctx.drawImage(img, 0, 0, 260, 260);
    
     };
    
      
    
   },
    
   // 标题
    
   title(ctx) {
    
     // ctx.setFontSize(12)
    
     let text = '接小程序开发,web开发,H5开发,小程序云开发,PHP开发'
    
     let moy =  '有需要的直接微信扫码'
    
     ctx.font = 'normal bold 12px sans-serif';
    
     ctx.fillStyle = "rgba(60, 59, 59)";
    
     console.log('======,', text.length)
    
     if (text.length <= 19) {
    
       // 一行字
    
       ctx.fillText(text, 10, 275, 280)
    
       ctx.fillStyle = "rgba(0,0,0)";
    
      
    
     }else if (text.length <= 38) {
    
       // 两行字
    
       let firstLine = text.substring(0, 20);//第一行
    
       let secondLine = text.substring(20, 38);第二行
    
       ctx.fillText(firstLine, 10, 275, 280)
    
       ctx.fillText(secondLine, 10, 290, 280)
    
  
    
     } else {
    
       // 超过两行省略多的加省略号
    
       let firstLine = text.substring(0, 20);
    
       let secondLine = text.substring(20, 38) + '...';
    
       ctx.fillText(firstLine, 10, 280, 280)
    
       ctx.fillText(secondLine, 10, 295, 280)
    
     
    
     }
    
     ctx.font = 'normal bold 16px sans-serif';
    
     ctx.fillStyle = "red";
    
     ctx.fillText(moy, 10, 320, 280)
    
   },
    
   // 头像
    
   hande(ctx) {
    
     let hande = this.data.canvas.createImage(); //创建img对象
    
     hande.onload = () => {
    
       console.log(hande.complete); //true
    
    // 绘制头像图片
    
    ctx.arc(30, 370, 40/2, 0, 2 * Math.PI) //画出圆
    
    ctx.clip(); //裁剪上面的圆形
    
    ctx.drawImage(hande, 10, 350, 40, 40)
    
    ctx.restore();
    
     };
    
     hande.src = "img/1.jpg";
    
   },
    
   // 名字
    
   name(ctx){
    
     ctx.fillStyle = "rgba(60, 59, 59)";
    
     ctx.font = 'normal bold 12px sans-serif';
    
     ctx.fillText('Loust', 60, 365, 280)
    
     ctx.fillStyle = "rgba(60, 59, 59)";
    
     ctx.font = 'normal bold 10px sans-serif';
    
     ctx.fillStyle = "#999";
    
     ctx.fillText('希望大佬们能够多多指教', 60, 380, 280)
    
   },
    
   // 二维码
    
   code(ctx) {
    
     return new Promise(rrr=>{
    
       let code = this.data.canvas.createImage(); //创建img对象
    
       code.onload = () => {
    
     console.log(code.complete); //true
    
     this.data.ctx.drawImage(code, 180, 340, 60, 60);
    
       };
    
       code.src = "img/code.jpg";
    
       setTimeout(() => {
    
     rrr(true)
    
       }, 100);
    
     })
    
   },
    
   bc() {
    
     // 保存到相册
    
     console.log('保存canvasId',this.data.canvas._canvasId)
    
     wx.canvasToTempFilePath({     //将canvas生成图片
    
       canvas:this.data.canvas,
    
       x: 0,
    
       y: 0,
    
       width: this.data._width,
    
       height: this.data._height,
    
       destWidth: this.data._width,     //截取canvas的宽度
    
       destHeight:this.data._height,   //截取canvas的高度
    
       success: function (res) {
    
     console.log('生成图片成功:',res)
    
     wx.saveImageToPhotosAlbum({  //保存图片到相册
    
       filePath: res.tempFilePath,
    
       success: function () {
    
         wx.showToast({
    
           title: "保存图片成功!",
    
           duration: 2000
    
         })
    
       }
    
     })
    
  
    
       },
    
     },this)
    
  
    
   },
    
 })

全部评论 (0)

还没有任何评论哟~