做这个分享海报真的遇到一个让我深刻的问题,就是在绘制圆的时候出来的黑色边框的问题,真是搞的头痛死了,花了一下午的时候找资料,没有解决,后面跟朋友在聊这个问题的时候,在看网上案例,还是自己对canvas不熟悉的原因,才迟迟没有解决这个问题,所以我在这里记录一下,希望有可能帮忙有需求的朋友们!觉得有帮忙的朋友,麻烦点个赞,支持一下我,谢谢了
这里要感谢一下 IT小智朋友分享出来的文章,我是按照他的方法生成海报
文章地址 blog.csdn.net/zhihui1017/…
首先看一下最终效果图
html
<view class="canvasBg" wx:if="{{canvasSwith}}" catchtouchmove="ture">
<view class="canvasWaip">
<view class="canvas_con">
<view class="con_l">
<view class="canvas_ani">
<canvas canvas-id="shareCanvas" style="width:253px;height:317px" bindlongtap='saveCanvas'></canvas>
</view>
</view>
<view class="vas_cal" catchtap="posterTab" data-id="2">
<wux-icon type="ios-close" color="#666" />
</view>
</view>
<view class="canvasText">
<text>保存图片后,可分享至朋友圈</text>
</view>
<view class="canvasBtn" catchtap="saveCanvas">
<view class="btn_save">
<text>保存</text>
</view>
</view>
</view>
</view>
css
.canvasBg{
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, .5);
position: fixed;
top: 0;
left: 0;
}
.canvasWaip{
position: fixed;
width: 100%;
background: #fff;
bottom: 0;
left: 0;
padding: 20rpx 0;
}
.canvasWaip .canvas_con{
width: 100%;
display: flex;
flex-direction: column;
/* margin-top: 20rpx; */
position: relative;
}
.canvas_con .con_l{
/* width: 460rpx; */
margin: 0 auto;
display: flex;
flex-direction: column;
box-shadow: 0px 2px 15rpx 0px rgba(6, 0, 1, 0.1);
border-radius: 15rpx;
overflow: hidden;
}
.canvasWaip .canvas_con .con_l .canvas_ani{
/* width: 460rpx; */
/* height: 575rpx; */
}
.canvasWaip .canvas_con .vas_cal{
width: 60rpx;
position: absolute;
right: 0rpx;
top: 0rpx;
}
.canvasBtn{
display: flex;
flex-direction: row;
justify-content: center;
height: 100rpx;
/* margin-top: 20rpx; */
align-items: center;
}
.canvasBtn .btn_save{
width: 324rpx;
height: 70rpx;
background: linear-gradient(90deg, #45A6E9 0%, #51F4EE 100%);
border-radius: 35rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.canvasBtn .btn_save text{
font-size: 30rpx;
color: #fff;
font-weight: bold;
}
.canvasBtn .btn_cal{
width: 70rpx;
}
.canvasWaip .canvasText{
text-align: center;
font-size: 28rpx;
font-weight: bold;
margin-top: 20rpx;
}
说一下前面说了为什么绘制圆的时候会出现黑色边框的原因就是, ctx.stroke() 原因, 这个要绘制 ctx.arc圆之后就ctx.setStrokeStyle然后就是ctx.stroke(),之前把ctx.stroke()放到最后,才会出现黑色边框的问题!
分享的二维码是通过请求接口拿到的
js
// 获取分享二维码
getWxArticleShareQrcode(id) {
let articleId = id
api.getWxArticleShareQrcode({
data: {
scene: 'articleId=' + articleId,
page: 'pages/index/index',
articleId
},
success: res => {
let cavvasUrl = res.url
console.log('Qrcode', cavvasUrl)
if(res.code == -1) {
util.showToast(res.message,2)
} else {
this.setData({
cavvasUrl
})
}
}
})
},
// 绘制分享海报
wxGetCanvasImage() {
util.showLoading()
let cavvasUrl = this.data.cavvasUrl
let cardUser = this.data.cardUser
let title = this.data.list.title
console.log('title', title.length)
const wxGetImageInfo = util.promisify(wx.getImageInfo)
Promise.all([
wxGetImageInfo({
src: 'http://ytdev.cn-gd.ufileos.com/image/yh/wit21.png'
}),
wxGetImageInfo({
src: cardUser.headPortrait
}),
wxGetImageInfo({
src: cavvasUrl
})
]).then(res => {
util.hideLoading()
console.log('res',res)
const ctx = wx.createCanvasContext('shareCanvas')
// 底图
ctx.drawImage(res[0].path, 0, 0, 253, 317)
// 作者名称
ctx.setTextAlign('left') // 文字居中
ctx.setFillStyle('#000000') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
ctx.fillText(cardUser.userName, 60, 155)
if(title.length>16) {
console.log('title.length大于8')
let title1 = title.slice(0,15)
let title2 = title.slice(15, title.length)
// 标题1
ctx.setTextAlign('left') // 文字居中
ctx.setFillStyle('#666') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
ctx.fillText(title1, title.length*1, 200)
// 标题
ctx.setTextAlign('left') // 文字居中
ctx.setFillStyle('#666') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
ctx.fillText(title2, title.length*1, 220)
} else {
// 标题1
ctx.setTextAlign('left') // 文字居左
ctx.setFillStyle('#666') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
if(title.length<5) {
console.log('title.length小于5')
ctx.fillText(title, title.length*3, 220)
} else {
ctx.fillText(title, title.length*1, 220)
}
}
// 头像
ctx.save()
//绘制专属头像;
ctx.beginPath()
// 圆的圆心的 x 坐标和 y 坐标,25 是半径,后面的两个参数就是起始和结束,这样就能画好一个圆了
ctx.arc(30, 150, 20, 0, 2 * Math.PI,false)
// 下面就裁剪出一个圆形了,且坐标在 (paddingWidth + 25, paddingWidth + 25)
ctx.setStrokeStyle('#ffffff')
ctx.stroke()
ctx.clip()
ctx.drawImage(res[1].path, 10,130, 40, 40)
ctx.restore()
// 小程序码
ctx.drawImage(res[2].path, 20,250, 60, 60)
// 小程序码描述
ctx.setTextAlign('left') // 文字居中
ctx.setFillStyle('#999') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
ctx.fillText("长按小程序码查看详情", 90, 270)
// 小程序码描述
ctx.setTextAlign('left') // 文字居中
ctx.setFillStyle('#999') // 文字颜色:黑色
ctx.setFontSize(14) // 文字字号:22px
ctx.fillText("分享自 【趣联日记】", 90, 290)
ctx.draw()
})
},
// 保存分享海报
saveCanvas() {
const wxCanvasToTempFilePath = util.promisify(wx.canvasToTempFilePath)
const wxSaveImageToPhotosAlbum = util.promisify(wx.saveImageToPhotosAlbum)
wxCanvasToTempFilePath({
canvasId: 'shareCanvas'
}, this).then(res => {
return wxSaveImageToPhotosAlbum({
filePath: res.tempFilePath
})
}).then(res => {
wx.showToast({
title: '已保存到相册'
})
this.setData({
canvasSwith: false
})
})
},
util.js promisify方法
// Canvas绘制海报
const promisify = (api) => {
return (options, ...params) => {
return new Promise((resolve, reject) => {
const extras = {
success: resolve,
fail: reject
}
api({ ...options, ...extras }, ...params)
})
}
}
module.exports = {
promisify
}
总结一下
开发这个功能,总共花了差不多一天时间吧,关于哪个黑色边框问题,一个下午多的时间才解决,我也是第一次做分享海报,没经验,对canvas也不熟悉,定位不了问题出在哪里,只能花大量的时间去查资料,看别人分享出来的案例,后面我又花了下班后花二个小时看canvas基础视频,还是没有解决,后面还是通过在群里问群友和朋友,有一个热心的朋友回答我的问题,聊着聊着,自己也慢慢的静下心来,仔细的检查一下代码,最终发现了一个问题,跟网友分享的不一样,抱着试试的态度,没想到可以了,解决了这个问题,后面又去查了资料,才知道原因,
说实话这个问题真很搞心态,在搞不定就只能跟设计说,不要圆形头像了,谢天谢地,这个问题还是解决了。
感谢一路帮助我的朋友了,谢谢您们
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!