• 微信小程序canvas绘制海报,并且实现图片保存至相册例子


    微信小程序绘制分享图例子:

    demo下载地址:https://gitee.com/v-Xie/wxCanvasShar

     大致代码会再以下说明 

    基础知识点:

    了解canvas基础知识

    wx.createCanvasContext()//微信小程序创建画布

    wx.canvasToTempFilePath()//将画布canvas转为图片

    wx.saveImageToPhotosAlbum() //微信小程序保存至相册

    canvas绘制以及绘制过程中的坑:(请看后面的代码部分)

    1.绘制头像后之后绘制的内容不显示 

    2.头像地址换成网络地址后无法显示

    3.实现多行文本换行并且获取绘制的文本的高度

    <!--index.wxml-->
    <view class="container">
    <!-- 画布 -->
    <!-- canvas -->
    <canvas canvas-id="myCanvas" style="300px;height:320px;position:fixed;top:40px;"></canvas>
    
    <!-- 要保存至相册的图片 -->
    
    <view class='imagePathBox'>
        <text>要分享的图片</text>
        <image src="{{imagePath}}"></image>
    </view>
    
    <button bindlongpress='baocun'>长按保存分享</button>
    </view>
    //index.js
    const app = getApp()
    
    Page({
      data: {
        imagePath:'',
        imgurl:'https://aecpm.alicdn.com/simba/img/TB1p4s3GVXXXXb6XVXXSutbFXXX.jpg'
      },
    
      onLoad: function() {
        // 调用画布
        // this.createNewImg();
        var self=this;
        wx.downloadFile({
          url: self.data.imgurl,
          success: function (res) {
            // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
            if (res.statusCode === 200) {
              console.log(res, "rrrr")
              self.setData({
                imgurl: res.tempFilePath
              })
              console.log('头像临时路径=====');
              console.log(self.data.imgurl);
    
              // self.createNewImg(); // 调用canvas绘制的结果图
            }
          }
        })
        setTimeout(function(){
          self.createNewImg(); 
        },500);
      },
      /*
        绘制圆行头像
        
        clip()从原始画布中剪切任意形状和尺寸。
        坑点:1.绘制头像后之后绘制的内容不显示
              2.头像地址换成网络地址以后无效
        提示:一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。
        解决方案:坑1:
                    原因:clip()造成
                    解决方案:可在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,
                         并在以后的任意时间通过 restore() 方法对其进行恢复
                  坑2:
                    原因:1.未将网络地址转换为临时路径  2.未配置download选项的合法域名
                    解决方案:wx.downloadFile()实现临时路径转换,并配置合法域名
        */
      circleImg(ctx, img, x, y, r) {
        ctx.save();
        var d = 2 * r;
        var cx = x + r;
        var cy = y + r;
        ctx.arc(cx, cy, r, 0, 2 * Math.PI);
        
        ctx.clip();
        ctx.drawImage(img, x, y, d, d);
        ctx.restore();
      },
      /*
        如何实现多行文本分段  (废弃) 
    更新多行文本相关:https://www.cnblogs.com/lingXie/p/13048745.html 语法: ctx.fillText('文本','文本的左上角x坐标位置','文本的左上角y坐标位置'); startXpoint:文本左上角x坐标位置 startYpoint:左上角y坐标位置 textHeight:文本与顶部基线距离[文本高度] canvasWidth:画布大小 fontSize:文本字体大小 lineHeight:行高
    */ /*drawText(ctx, str, startXpoint, startYpoint, textHeight, canvasWidth, fontSize, lineHeight) { var textWidth = 0; var lastSubStrIndex = 0; //每次开始截取的字符串的索引 for (let i = 0; i < str.length; i++) { textWidth += ctx.measureText(str[i]).width; if (textWidth > canvasWidth) { ctx.font = "normal 14px Arial"; ctx.fillStyle = 'green'; ctx.fillText(str.substring(lastSubStrIndex, i), startXpoint, startYpoint); //绘制截取部分 startYpoint += fontSize; //16为字体的高度 textWidth = 0; lastSubStrIndex = i; textHeight += lineHeight; } if (i == str.length - 1) { //绘制剩余部分 ctx.fillText(str.substring(lastSubStrIndex, i + 1), startXpoint, startYpoint); } } // 绘制后文本的高度 return textHeight },
    */
    /* 1.绘制画布 2.将canvas转换为图片保存到本地,然后将图片路径传给image图片的src */ createNewImg: function () { var self = this; var ctx = wx.createCanvasContext('myCanvas'); // 初始要画一个相当于画布大小的容器 //设计稿分享图多大,画布就多大 ctx.strokeStyle = "#ccc"; ctx.strokeRect(0, 0, 300, 320); //绘制矩形 //语法:填充型fillRect(x,y,w,h) 或 描边型strokeRect(x,y,w,h) x,y坐标起点 w:矩形宽度 h:矩形高度 ctx.fillStyle = "#FF0000"; ctx.fillRect(20, 20, 50, 40); ctx.strokeStyle = "blue"; ctx.strokeRect(140, 20, 50, 40); //绘制线条 //语法:moveTo(x,y)线条起始坐标 (同样可以用来改变画笔的起始坐标点) lineTo(x,y);线条结束坐标 ctx.moveTo(20, 80); ctx.lineTo(200, 100); ctx.textWidth = 10;//线条宽度 ctx.lineCap = 'round'//lineCap 线段端点显示的样子 ,值为butt,round 和 square。默认是 butt ctx.strokeStyle = "green"; ctx.stroke(); //绘制圆 //语法:arc(x,y,r,start,stop) x,y圆心中心点坐标 r:半径 start: 起始角度 stop:结束角度 ctx.beginPath();//重新创建路径 ctx.arc(40, 130, 30, 0, 2 * Math.PI); ctx.strokeStyle = "purple"; ctx.textWidth = 4;//描边宽度 ctx.fillStyle = "red"; ctx.fill(); ctx.stroke(); //绘制文本 //语法:fillText(text, x, y, [maxWidth]) strokeText(text, x, y, [maxWidth]) ctx.font = "normal 18px Arial"; ctx.textAlign = 'center'; ctx.textBaseline = 'bottom'; ctx.fillStyle = 'blue'; ctx.fillText("绘制文本", 120, 140); ctx.strokeText("绘制文本", 120, 170);//没有设置新的strokeStyle或textWidth等时会自动继承上一个strokeStyle或textWidth等 // ctx.textWidth = 1;//strokeStyle或textWidth // ctx.strokeStyle = "green"; ctx.strokeText("绘制文本", 120, 200); var img='../../images/2.jpg'; ctx.drawImage(img, 10, 170, 60, 70); ctx.fillStyle = 'red'; this.circleImg(ctx,img,200,20,40); ctx.fillText("继续啊", 240, 140); ctx.drawImage(self.data.imgurl, 180, 150, 100, 80); var text ="把握大好时机,认真理性投资。用自己的才华和智慧积极进取。把握大好时机,认真理性投资。用自己的才华和智慧积极进取。"; self.drawText(ctx, text, 160, 260, 0, 260, 14, 0); ctx.save(); // 保存当前ctx的状态 ctx.restore(); ctx.draw(); setTimeout(function () { wx.canvasToTempFilePath({ x: 0, y: 0, 300, height: 320, destWidth: 300 * 2,//生成图片的大小设置成canvas大小的二倍解决模糊 destHeight: 320 * 2, canvasId: 'myCanvas', success: function (res) { var tempFilePath = res.tempFilePath; self.setData({ imagePath: tempFilePath }); wx.hideToast(); console.log('canvas图片地址:' + self.data.imagePath); } }); }, 600); }, //点击保存到相册 baocun: function () { var self = this; wx.saveImageToPhotosAlbum({ filePath: self.data.imagePath, success(res) { wx.showModal({ content: '图片已保存到相册,赶紧晒一下吧~', showCancel: false, confirmText: '好的', confirmColor: '#333', success: function (res) { if (res.confirm) { console.log('用户点击确定'); } }, fail: function (res) { console.log(res) } }) } }) }, })
    一步一叩首,今天的自己比昨天好一点就行,明天的自己需追寻
  • 相关阅读:
    HBASE & DB : ACID 事务 与 相关实现
    LeetCode Largest Number
    LeetCode Power of Two
    LeetCode Dungeon Game
    LeetCode The Skyline Problem
    LeetCode Kth Smallest Element in a BST
    LeetCode Flatten Binary Tree to Linked List
    JAVA 并发:CLH 锁 与 AbstractQueuedSynchronizer
    为什么引入TSS
    特权级概述(哥子就想知道CPU是如何验证特权级的)GATE+TSS
  • 原文地址:https://www.cnblogs.com/lingXie/p/10609530.html
Copyright © 2020-2023  润新知