具体实现效果就是上面这个图片。里面的元素都是自己根据自己实际情况拼接进去的。
在开发小程序时,我们经常会遇到【分享】这个功能,在实现分享功能时,我们一般会基于当前页面,生成一个海报进行分享。
在实现时,基本上是通过canvas
画一个图片,然后生成一个图片,具体的可以看下面的代码。
视图代码
<!-- 报价按钮 -->
<view :style="{marginTop: '30rpx'}">
<view class="container-price">
<view class="container-price-left">
<view style="display: flex;flex-direction: column;align-items: center;margin-left: 30rpx;"
@click="shareing">
<view>
<image src="../../static/img/share.svg" style="height: 46rpx;width: 46rpx;"></image>
</view>
<view style="font-size: 16rpx;height: 30rpx;">分享</view>
</view>
<view style="display: flex;flex-direction: column;align-items: center;margin-left: 30rpx;"
@click="subscribeMsg4Bid">
<view>
<image src="../../static/img/subscribe.svg" style="height: 46rpx;width: 46rpx;">
</image>
</view>
<view style="font-size: 16rpx;height: 30rpx;">订阅</view>
</view>
</view>
</view>
</view>
<!-- 生成海报 -->
<canvas v-if="ifGeneratingPosters" :style="{height: pupopHeight + 'px',width: pupopWidth + 'px'}"
canvas-id="myCanvas"></canvas>
<uni-popup ref="popupPosters" type="bottom" border-radius="10px 10px 0 0">
<view class="popup-posters-wrap">
<image :src="posterImg" mode="aspectFill" :style="{height:'420px',width:'100%'}">
</image>
<view class="popup-footer" :style="{marginBottom : (0-safeAreaHeight) + 'px'}">
<view style="text-align: center;font-size: 20rpx;">立即分享</view>
<view style="display: flex;flex-direction: row;font-size: 20rpx;margin: 0 20rpx;">
<view style="display: flex;flex-direction: column;align-items: center;">
<button class="noneButton" data-name="shareBtn" open-type="share">
<u-icon size="80" color="#03de6d" name="weixin-circle-fill"></u-icon>
</button>
<view>微信好友</view>
</view>
<view style="display: flex;flex-direction: column;align-items: center;margin-left: 20rpx;">
<view @click="saveToLocal">
<u-icon size="80" color="#18a5f0" name="photo-fill"></u-icon>
</view>
<view>保存海报</view>
</view>
</view>
<view
:style="{bottom:(safeAreaHeight+5)+'px',left:'50%',position:'fixed',fontSize:'24rpx',transform:'translate(-50%,-50%)',padding:'5rpx 15rpx'}"
@click="this.$refs.popupPosters.close()">
<view>取消</view>
</view>
</view>
</view>
</uni-popup>
js代码
//生成海报--微信端
createPoster() {
let _this = this
const canvasId = "myCanvas"
let ctx = uni.createCanvasContext(canvasId, _this) // 自定义组件中 一定要传this ,这里一开始没加,困惑很久,一定要写一下
// 填充背景
ctx.setFillStyle('#FFFFFF')
ctx.fillRect(0, 0, _this.pupopWidth, _this.pupopHeight);
ctx.save()
//生成车辆图册
uni.getImageInfo({
src: _this.imageFileList[0], //这里的banner是展示的商品图
success(image) {
let bannerW = _this.pupopWidth
let bannerH = 400 * _this.pixelRatio
let bannerX = 0 * _this.pixelRatio
let bannerY = 20 * _this.pixelRatio
// 将banner到画布上
ctx.drawImage(image.path, bannerX, bannerY, bannerW, bannerH)
ctx.restore()
ctx.save()
//车辆描述
ctx.setFontSize(18 * _this.pixelRatio)
ctx.setFillStyle("#000")
let bannerTextX = 20 * _this.pixelRatio
let bannerTextY = bannerY + bannerH + 20 * _this.pixelRatio + 20
let title = _this.inquiry.vehicleBrand + _this.inquiry.vehicleSeries +
_this.inquiry.vehicleYear + _this.inquiry.vehicleModel
if (title.length > 20) {
title = title.slice(0, 20) + '...'
}
ctx.fillText(title, bannerTextX, bannerTextY, _this.pupopWidth);
// 第二行文字
ctx.setFontSize(14 * _this.pixelRatio)
ctx.setFillStyle("#cb171d")
//事故类型
let titleAccidentType = _this.inquiry.accidentTypeName
ctx.fillText(titleAccidentType, bannerTextX, bannerTextY + 30 * _this.pixelRatio, _this
.pupopWidth);
let accidentTypeWidth = ctx.measureText(titleAccidentType).width
//所有人性质
let vehicleOwnerNature = _this.inquiry.vehicleOwnerNatureName
ctx.fillText(vehicleOwnerNature, bannerTextX + accidentTypeWidth + 5 * _this.pixelRatio,
bannerTextY + 30 * _this.pixelRatio, _this
.pupopWidth);
let vehicleOwnerNatureWidth = ctx.measureText(vehicleOwnerNature).width
// 使用性质
let vehicleUsageNature = _this.inquiry.vehicleUsageNatureName
ctx.fillText(vehicleUsageNature, bannerTextX + accidentTypeWidth + 5 * _this.pixelRatio +
vehicleOwnerNatureWidth + 5 * _this.pixelRatio,
bannerTextY + 30 * _this.pixelRatio, _this
.pupopWidth);
let vehicleUsageNatureWidth = ctx.measureText(vehicleUsageNature).width
// 初登日期及地方位置
ctx.setFontSize(12 * _this.pixelRatio)
ctx.setFillStyle("#b3b3b3")
let vehicleRegisterDate = '初登日期 ' + _this.inquiry.vehicleRegisterDate
let position = '停放地 ' + _this.inquiry.parkingPositionProvinceName + _this.inquiry
.parkingPositionCityName
let vehicleRegisterDateWithPosition = vehicleRegisterDate + " / " + position
ctx.fillText(vehicleRegisterDateWithPosition,
bannerTextX,
bannerTextY + 30 * _this.pixelRatio + 20 * _this.pixelRatio,
_this.pupopWidth);
let vehicleRegisterDateWithPositionWidth = ctx.measureText(vehicleRegisterDateWithPosition)
.width
//画间隔线
ctx.moveTo(40 * _this.pixelRatio, bannerTextY + 20 * _this.pixelRatio +
20 * _this.pixelRatio +
20 * _this.pixelRatio);
//设置起点状态
ctx.lineTo(_this.pupopWidth - 40 * _this.pixelRatio, bannerTextY + 20 *
_this.pixelRatio + 20 * _this.pixelRatio +
20 * _this.pixelRatio);
//设置末端状态
ctx.lineWidth = 1 * _this.pixelRatio; //设置线宽状态
ctx.strokeStyle = '#EEEEEE'; //设置线的颜色状态
ctx.stroke();
//二维码
uni.getImageInfo({
src: 'https://oss.guochewang.cn/banner/app/wechat_app.jpg',
success(res) {
// 画当前页面的二维码
const img_x = 20 * _this.pixelRatio
const img_w = 60 * _this.pixelRatio
const img_y = bannerTextY + 20 *
_this.pixelRatio + 20 * _this.pixelRatio +
20 * _this.pixelRatio + 20 * _this.pixelRatio
ctx.drawImage(res.path, img_x, img_y, img_w, img_w)
//画提示文字
const tiptextX = img_x + img_w + 20 * _this.pixelRatio
const tiptext1Y = img_y + 20 * _this.pixelRatio
const tiptext2Y = img_y + 20 * _this.pixelRatio + 20 * _this
.pixelRatio + 12 * _this.pixelRatio
const tiptext1 = '国车网 '
const tiptext1_1 = '一个专注事故车的交易平台 '
const tiptext2 = '识别二维码查看车辆更多详情'
ctx.setFontSize(16 * _this.pixelRatio)
ctx.setFillStyle("#cb171d")
ctx.fillText(tiptext1, tiptextX, tiptext1Y);
ctx.stroke();
let tiptext1Width = ctx.measureText(tiptext1).width
ctx.setFontSize(12 * _this.pixelRatio)
ctx.setFillStyle("#333333")
ctx.fillText(tiptext1_1, tiptextX + tiptext1Width, tiptext1Y);
ctx.stroke();
ctx.setFontSize(12 * _this.pixelRatio)
ctx.setFillStyle("#333333")
ctx.fillText(tiptext2, tiptextX, tiptext2Y);
ctx.stroke();
ctx.draw(false, () => {
uni.canvasToTempFilePath({
width: _this.pupopWidth,
height: _this.pupopHeight,
destWidth: _this.pupopWidth,
destHeight: _this.pupopHeight,
canvasId: canvasId,
fileType: 'png',
quality: 1,
success: function(res) {
_this.posterImg = res
.tempFilePath; //最终将canvas转换为图片
_this.$refs.popupPosters
.open();
uni.hideLoading()
_this.ifGeneratingPosters = false
},
fail(error) {
console.log('4', error)
uni.showToast({
title: '生成海报失败,请稍后重试!'
})
setTimeout(() => {
uni.hideLoading()
_this.ifGeneratingPosters = false
}, 2000)
}
}, _this)
})
},
fail(error) {
console.log('获取二维码失败', error)
uni.showToast({
title: '生成海报失败,获取二维码失败'
})
setTimeout(() => {
uni.hideLoading()
_this.ifGeneratingPosters = false
}, 2000)
}
})
},
fail(error) {
console.log('生成商品图失败', error)
uni.showToast({
title: '生成海报失败,获取商品图失败'
})
setTimeout(() => {
uni.hideLoading()
_this.ifGeneratingPosters = false
}, 2000)
}
});
},
//将图片保存到本地相册
saveToLocal() {
//#ifdef MP-WEIXIN
uni.saveImageToPhotosAlbum({
filePath: this.posterImg,
success: () => {
uni.showToast({
icon: 'success',
title: '保存到相册成功'
})
this.$refs.popupPosters.close()
},
fail: (err) => {
console.log("保存到相册失败", err)
}
});
//#endif
},
评论 (0)