前言
简单整理一下小程序生成海报的思路
实现效果
实现步骤
第一步创建画布以及获取画布
- 简单实现也布局
<template>
<view class="content">
<!-- style控制画布大小 -->
<canvas
type="2d"
style="width: 75vw; height: 80vh"
canvas-id="canvasView"
id="canvasView"
></canvas>
<button class="save-btn">保存</button>
</view>
</template>
<script>
export default {};
</script>
<style lang="scss">
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.save-btn {
margin-top: 20rpx;
width: 240rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 16px;
}
}
</style>
- 获取 canvas 元素
- 参考文档
- (微信小程序文档)[developers.weixin.qq.com/miniprogram…]
- (uniapp 文档)[uniapp.dcloud.net.cn/api/ui/node…]
<script>
export default {
onReady() {
this.onCanvasInit();
},
methods: {
onCanvasInit() {
const query = uni.createSelectorQuery();
query
.select("#canvasView")
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
//获取设备像素比,并设置canvas大小
const dpr = uni.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
const ctx = canvas.getContext("2d");
});
},
},
};
</script>
第二步进行背景图绘制
onCanvasInit() {
const query = uni.createSelectorQuery();
query
.select("#canvasView")
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
const dpr = uni.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
const ctx = canvas.getContext("2d")
onDrawBack(ctx,{width:canvas.width,height:canvas.height})
});
}
onDrawBack(ctx,{width,height}){
//绘制一个纯白色背景
ctx.fillStyle = "white";
ctx.beginPath();
ctx.rect(0, 0, width, height);
ctx.fill();
//也可以绘制一张图片作为背景色
// const image = canvas.createImage();
// image.onload = () => {
// ctx.drawImage(image, 0, 0, width,height);
// };
// image.src = "http://img.netbian.com/file/2022/1212/small0039153blMa1670776755.jpg";
}
效果图如下
第三步实现附加商品图片以及商品二维码图
onDrawShop(ctx, canvas, { width, height }) {
const imageshop = canvas.createImage();
imageshop.onload = () => {
const size = width - 30
ctx.drawImage(imageshop, 30, 30, size - 30, size - 30);
};
imageshop.src = "https://img.alicdn.com/imgextra/i3/58732120/O1CN01iEyOjY1RX0EZjjCog_!!0-saturn_solar.jpg_468x468q75.jpg_.webp";
}
第四步标注商品名称以及价格
onDrawShopInfo(ctx, canvas, { width, height }) {
//绘制名称
ctx.beginPath()
ctx.fillStyle = 'black';
ctx.font = '34px serif';
ctx.fillText("精品卫衣", 30, width + 30)
ctx.closePath();
//绘制商品价格
ctx.beginPath()
ctx.fillStyle = 'red';
ctx.font = '34px';
ctx.fillText("¥129.00", 30, width + 100)
ctx.closePath();
},
第五步标注商品二维码
onDrawShopQrcode(ctx, canvas, { width, height }) {
const imageshop = canvas.createImage();
imageshop.onload = () => {
const size = 160
const left = width - size - 30
const top = height - size - 30
ctx.drawImage(imageshop, width - size - 30, height - size - 30, size, size);
};
const qrcode = "data:image/png;base64,iVBORw...."
imageshop.src = qrcode;
},
第六步标注平台信息
onDrawPlatformInfo(ctx, canvas, { width, height }) {
ctx.beginPath()
ctx.fillStyle = 'black';
ctx.font = '26px serif';
ctx.fillText("裁晨", 30, height - 60)
ctx.closePath();
ctx.beginPath()
ctx.fillStyle = 'black';
ctx.font = '22px serif';
ctx.fillText("实现一个简单商品海报", 30, height - 30)
ctx.closePath();
}
第七步实现导出海报到本地
function base64src(base64data, cb) {
const fsm = uni.getFileSystemManager();
const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
return (new Error('ERROR_BASE64SRC_PARSE'));
}
const time = new Date().getTime(); //自定义文件名
const filePath = `${wx.env.USER_DATA_PATH}/${time}.${format}`;
const buffer = uni.base64ToArrayBuffer(bodyData);
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
cb(filePath);
},
fail() {
return (new Error('ERROR_BASE64SRC_WRITE'));
},
});
}
onSave() {
// 获取元素
const query = uni.createSelectorQuery();
query
.select("#canvasView")
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
//使用toDataURL方法获取到base64
const base64 = canvas.toDataURL("image/jpeg")
//将base64数据转成零时链接
base64src(base64, (filePath) => {
//保存到本地
uni.saveImageToPhotosAlbum({
filePath,
success: function () {
uni.showToast({
title: '保存成功',
icon: "none",
})
},
})
})
})
}
参考文档
- 微信小程序 canvas 文档
- uniapp小程序canvas文档
- canvas mdn文档