• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

小程序生成海报并分享

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

    先放图,哈哈哈

    

 

 

 整体思路:

        页面需要有一个canvas容器,用来放后面绘制的结果,canvas不熟练,底下没有画圆角,所以展现给用户看的不是canvas画的,当保存下来的时候才是canvas生成的图片.

 1 <canvas class="sharePoster" canvas-id="poster"></canvas>
 2     <view class="show-img" wx:if="{{sharePoster}}">
 3     <!-- <view class="show-img"> -->
 4         <view class="show-con">
 5             <image class="share-del" src="/images/unshare.png" alt="" catchtap="unshare" />
 6             <view class="canvas-img">
 7                 <image class="share-bg" src="/images/share-bg.png" alt="" />
 8                 <view class="canvas-user">
 9                     <image class="user-img" src="{{shareInfo.avatar}}" alt=""></image>
10                     <view class="canvas-info">
11                         <view class="user-name">{{shareInfo.nickname}}</view>
12                         <view class="tip">正在参赛...</view>
13                     </view>
14                 </view>
15                 <view class="canvas-works">
16                     <image src="{{shareInfo.opus_type==1?  shareInfo.opus_url :  shareInfo.opus_banner_image || \'/images/vote-wei.png\'}}" alt="" />
17                 </view>
18                 <view class="canvas-info">
19                     <view class="canvas-name">{{shareInfo.opus_name}}</view>
20                     <view class="canvas-content">{{shareInfo.opus_content}}</view>
21                 </view>
22                 <view class="canvas-footer">
23                     <image class="canvas-code" src="{{shareInfo.qrcode_url}}" alt="" />
24                     <view class="code-tip">
25                         <view>长按识别二维码</view>
26                         <view>为好友加油,一起参赛!</view>
27                     </view>
28                 </view>
29             </view>
30         </view>
31         <view class="sava-img" catchtap=\'savePoster\'>保存到本地</view>
32     </view>
wxml代码

        在用户点击生成海报的时候,获取海报所需要的的信息,开始下载图片资源,并绘制canvas,期间需要一些时间,可以先弹个\'生成中...\'的弹窗给用户看.

 1 getPosterInfo(ho_id) {
 2     let params = { ho_id: ho_id };
 3     let that = this;
 4     //获取海报所需信息
 5       wx.hideLoading();
 6       this.setData({
 7         shareInfo: res.data,
 8         shareFlag: false,
 9         sharePoster: true
10       });
11       //这里需要下载对应的网络图片资源并且开始绘画canvas
12       this.downloadImg(this.data.shareInfo.avatar, "userImg");
13       if (this.data.item.type == 1) {
14         this.downloadImg(this.data.shareInfo.opus_url, "showImg"); //图片下载
15       } else {
16         this.downloadImg(this.data.shareInfo.opus_banner_image, "showImg"); //视频封面下载
17       }
18       this.downloadImg(this.data.shareInfo.qrcode_url, "code"); //二维码下载
19       setTimeout(() => {
20         wx.getSystemInfo({
21           success: function(res) {
22             var v = 750 / res.windowWidth; //获取手机比例
23             that.drawPoster(v);  
24           }
25         });
26       }, 500);
29     });
30   }
因为我要下载的图片比较多,所以这边把微信的下载图片接口封装了一下,直接使用 \'wx.downloadFile({})\' 下载图片即可.
这是第一次做海报分享,而且canvas很菜,比例抓不住,后来才知道用比例直接计算,基本上就比较好了
  1 drawPoster(v) {
  2     let that = this;
  3     let ratio = 0.5;
  4     let ctx = wx.createCanvasContext("poster", this);
  5     ctx.drawImage(this.data.imgs, 0, 0, 630 / v, 812 / v);
  6     ctx.save();
  7     ctx.beginPath();
  8     //头部
  9     // ctx.rect(30 / v, 31 / v, 570 / v, 96 / v)
 10 
 11     ctx.save();
 12     // 圆的圆心的 x 坐标和 y 坐标,25 是半径,后面的两个参数就是起始和结束,这样就能画好一个圆了
 13     ctx.arc(78 / v, 78 / v, 48 / v, 0, 2 * Math.PI);
 14     ctx.clip();
 15     ctx.drawImage(this.data.userImg, 30 / v, 31 / v, 96 / v, 96 / v);
 16     ctx.restore();
 17     ctx.setFontSize(30 / v);
 18     ctx.setFillStyle("white");
 19     ctx.fillText(this.data.shareInfo.nickname, 150 / v, 65 / v);
 20     ctx.setFontSize(28 / v);
 21     ctx.setFillStyle("white");
 22     ctx.fillText("正在参赛......", 150 / v, 115 / v);
 23     ctx.restore(); //恢复限制
 24     //分享图片
 25     ctx.rect(30 / v, 157 / v, 570 / v, 380 / v);
 26     ctx.lineJoin = "round";
 27     ctx.lineWidth = 20 / v;
 28     //作品图片
 29     let worksImg = this.data.showImg || "/images/vote-wei.png";
 30     ctx.drawImage(worksImg, 30 / v, 157 / v, 570 / v, 380 / v);
 31 
 32     //作品名称
 33     ctx.setFontSize(40 / v);
 34     ctx.setFillStyle("white");
 35     ctx.fillText(this.data.shareInfo.opus_name, 30 / v, 598 / v, 560 / v);
 36     ctx.save();
 37     //作品内容
 38     // ctx.rect(30 * ratio, 616 * ratio, 570 * ratio, 172 * ratio)
 39 
 40     ctx.setFontSize(36 * ratio);
 41     ctx.setFillStyle("white");
 42     //可以尝试切割字符串,循环数组,达到换行的效果
 43     let info = this.data.shareInfo.opus_content;
 44     let len = 0;
 45     if (info.length > 15 && info.length < 30) {
 46       //两行以内
 47       for (var a = 0; a < 2; a++) {
 48         let content = info.substr(len, 15);
 49         len += 15;
 50         ctx.fillText(content, 30 * ratio, (658 + a * 48) / v);
 51       }
 52     } else if (info.length > 30) {
 53       //超过三行
 54       let con1 = info.substr(len, 15);
 55       let con2 = info.substr(15, 14) + "...";
 56       ctx.fillText(con1, 30 * ratio, 658 / v);
 57       ctx.fillText(con2, 30 * ratio, (658 + 48) / v);
 58     } else {
 59       //就一行
 60       ctx.fillText(info, 30 * ratio, 658 / v);
 61     }
 62 
 63     ctx.restore();
 64 
 65     //二维码
 66     ctx.save();
 67     ctx.setFillStyle("white");
 68     // ctx.lineJoin = "round";
 69     // ctx.lineWidth = 20 / v;
 70 
 71     ctx.fillRect(0 / v, 740 / v, 630 / v, 235 / v);
 72     ctx.drawImage(this.data.code, 30 / v, 761 / v, 153 / v, 153 / v);
 73     ctx.setFontSize(36 / v);
 74     ctx.setFillStyle("#666666");
 75     ctx.fillText("长按识别二维码", 210 / v, 826 / v);
 76     ctx.fillText("为好友加油,一起参赛!", 210 / v, 877 / v);
 77     // ctx.setFillStyle(\'white\');
 78     // ctx.fill();
 79     // ctx.draw();
 80     ctx.restore();
 81     let windowWidth = wx.getSystemInfoSync().windowWidth;
 82     ctx.draw(true, () => {
 83       let timer = setTimeout(() => {
 84         wx.canvasToTempFilePath(
 85           {
 86             x: 0,
 87             y: 0,
 88             width: 315,
 89             height: 470,
 90             destWidth: (315 * 750) / windowWidth,
 91             destHeight: (470 * 750) / windowWidth,
 92             canvasId: "poster",
 93             // fileType: \'jpg\',  //如果png的话,图片存到手机可能有黑色背景部分
 94             success(res) {
 95               //生成成功
 96               that.setData({
 97                 tempImg: res.tempFilePath
 98               });
 99               clearTimeout(timer);
100             },
101             fail: res => {
102               //生成失败
103               clearTimeout(timer);
104             }
105           },
106           this
107         );
108       }, 100);
109     });
110   }
canvas绘图

    直接用所需像素除以上面得到的比例,就OK了.我是在外面又建了一个项目画完之后直接移进来,canvas画了很久,边看文档边画

    关于多行字符串可以手动计算字符串长度,然后给他切割出来,分段绘制.主要是我也不懂怎么用canvas绘制多行省略???完全没有找到相关方法,如果有更好的方法,求教,谢谢!!

    wx.canvasToTempFilePath(obj,this)  官方文档:  https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.canvasToTempFilePath.html

    把当前画布指定区域的内容导出生成指定大小的图片. 在draw()回调里调用该方法才能保证图片保存成功, 输出的图片宽度和高度需要按比例,不能写死.这样不同手机生成的图片就不一样了.

    接下来就是要保存图片到本地了,仍然使用小程序接口,将上面生成图片后的临时路径放进来就可以了,本来以为这边分分钟,后面差点忘了做授权处理.不要粗心大意!!!

 1 wx.saveImageToPhotosAlbum({
 2         filePath: that.data.tempImg,
 3         success(res) {
 4           wx.showToast(
 5             {
 6               title: "保存成功",
 7               icon: "success"
 8             },
 9             1000
10           );
11           that.unshare();
12           that.shareOff(); //关闭窗口
13         },
14         fail(err) {
15           //授权问题报错
16           if (
17             err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
18             err.errMsg === "saveImageToPhotosAlbum:fail auth deny" ||
19             err.errMsg === "saveImageToPhotosAlbum:fail authorize no response"
20           ) {
21             wx.showModal({
22               title: "提示",
23               content: "需要您授权保存相册",
24               showCancel: false,
25               success: modal=> {
26                 wx.openSetting({
27                   success(settingdata) {
28                     //授权状态
29                     if (settingdata.authSetting["scope.writePhotosAlbum"]) {
30                       wx.showToast(
31                         {
32                           title: "获取权限成功,再次点击即可保存",
33                           icon: "none"
34                         },
35                         500
36                       );
37                     } else {
38                       wx.showToast(
39                         {
40                           title: "获取权限失败,将无法保存到相册哦~",
41                           icon: "none"
42                         },
43                         500
44                       );
45                     }
46                   },
47                   fail(failData) {
48                     console.log("failData", failData);
49                   }
50                 });
51               }
52             });
53           }
54         }
55       });

做完之后竟然对讨厌的canvas产生了一点点好感,嗯,只要不画贝塞尔曲线,一切都好商量,代码感觉还有冗余,需要进一步的改进,不过这是第一次做,就不想删了,看优化后的和看第一次做出来的,感觉总是有点不同的.我应该是个恋旧的人吧,哈哈哈,开个玩笑.




鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
小程序生成海报 canvas发布时间:2022-07-18
下一篇:
小程序生成海报图片发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap