1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 微信小程序-海报制作(canvas)

微信小程序-海报制作(canvas)

时间:2018-08-31 02:24:57

相关推荐

微信小程序-海报制作(canvas)

文档

https://developers./miniprogram/dev/api/canvas/wx.createOffscreenCanvas.html以下是按照1倍图画的,可以先画出来再调整合适的倍图以下宽度、文字间距等可以使用变量代替

wxml

<view class="canvas-container"><canvascanvas-id="myCanvas"class="myCanvas"style="width: {{canvasWidth}}px; height: {{canvasHeight}}px;"></canvas><view class="btn-save" bindtap="savePoster">保存到相册</view></view>

wxss

.myCanvas {display: block;margin: 0 auto;}.btn-save {margin: 20rpx;padding: 10rpx;border: 1rpx solid #eee;text-align: center;font-size: 24rpx;border-radius: 4rpx;}

js

// pages/canvas/canvas.jsPage({/*** 页面的初始数据*/data: {canvasWidth: 296, // 绘图区域宽度canvasHeight: 426, // 绘图区域高度bgUrl: 'https://img-/standard/new_buy_poster_bg2.png',goodsUlr: 'https://img-/goods16233105466440.jpg',card_url: '' // 生成图片的id},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {const {canvasWidth, canvasHeight, bgUrl, goodsUlr } = this.data;// 定义画布对象const ctx = wx.createCanvasContext("myCanvas", this);// 获取图片Promise.all([this.getCode(bgUrl),this.getCode(goodsUlr)]).then(res => {// 背景图ctx.drawImage(res[0].tempFilePath, 0, 0, canvasWidth, canvasHeight);// 白背景this.roundedRect(ctx,10,56,275,360,5,5,5,5);ctx.fillStyle = "#ffffff";ctx.fill();// 商品图ctx.drawImage(res[1].tempFilePath, 20, 66, 255, 255);// 标题this.drawText(ctx, {x: 20,y: 255 + 66 + 20,color: "#333333",size: 14,// isCenter: true,text: '哈哈哈,大傻瓜,哈哈哈,大傻瓜哈哈哈',width: "",bold: true});this.drawText(ctx, {x: 20,y: 255 + 66 + 40,color: "#333333",size: 14,isCenter: true,text: '哈哈哈,大傻瓜,哈哈哈',width: 255,bold: true});// 价格this.drawText(ctx, {x: 20,y: 390,color: "#FA4046",size: 16,isCenter: true,text: "¥",width: "",bold: true});// 元this.drawText(ctx, {x: 20 + this.measureText('¥'),y: 378,color: "#FA4046",size: 32,isCenter: true,text: 2,width: "",bold: true});// 角分this.drawText(ctx, {x: 20 + 3 + this.measureText('¥') + this.measureText('2', 32),y: 390,color: "#FA4046",size: 16,isCenter: true,text: "." + '02',width: "",bold: true});// 划线价this.drawText(ctx, {x: 20 + 3 + 10 + this.measureText('¥') + this.measureText('2', 32) + this.measureText('.02', 16),y: 394,color: "#a6a6a6",size: 12,isCenter: true,text: '¥7.99',width: "",bold: true});// 划线this.lineation(ctx, {sx: 20 + 3 + 10 + this.measureText('¥') + this.measureText('2', 32) + this.measureText('.02', 16),sy: 399,ex: 20 + 3 + 5 + 10 + this.measureText('¥') + this.measureText('2', 32) + this.measureText('.02', 16) + this.measureText('¥7.99', 12),ey: 399,lineWidth: "",color: "#a6a6a6"});ctx.draw();setTimeout(() => {console.log('生成', '....')this.exportImg("myCanvas", 296, 426);}, 1000);})},//把网路图片下载成本地图片getCode(img) {return new Promise((resolve, reject) => {wx.downloadFile({url: img,success: (res) => {resolve(res)}})})},// 生成指定的图片exportImg(idn, w, h) {console.log(idn, w, h)let that = this;wx.canvasToTempFilePath({x: 0,y: 0,width: w,height: h,destWidth: w,destHeight: h,canvasId: idn,success: function(res) {console.log(res)wx.getImageInfo({src: res.tempFilePath,success: function(res) {console.log(that, '.......');// 生成的canvas图片路径that.setData({card_url: res.path})}});},fail(err) {console.error(err);},complete() {}},this);},// 保存海报savePoster() {// 将图片保存到相册wx.saveImageToPhotosAlbum({filePath: this.data.card_url,success(res) {wx.showToast({title: '成功',icon: 'success',duration: 2000})},fail() {// 判断是否获得了用户保存相册授权wx.getSetting({success: auth => {if (!auth.authSetting["scope.writePhotosAlbum"]) {wx.showToast({title: '请开启相册授权',icon: 'error',duration: 2000})}}});}});},/*** 工具 圆角矩形* x, y 坐标* width, height 宽高* 圆角: 左下, 右下, 右上, 左上*/roundedRect(ctx,x,y,width,height,RTradius,RBradius,LBradius,LTradius) {// ctx.strokeStyle = "#fffbff";ctx.beginPath();// 右上ctx.moveTo(x, y + RTradius);ctx.lineTo(x, y + height - RTradius);ctx.quadraticCurveTo(x, y + height, x + RTradius, y + height);// 右下ctx.lineTo(x + width - RBradius, y + height);ctx.quadraticCurveTo(x + width,y + height,x + width,y + height - RBradius);// 左下ctx.lineTo(x + width, y + LBradius);ctx.quadraticCurveTo(x + width, y, x + width - LBradius, y);// 左上ctx.lineTo(x + LTradius, y);ctx.quadraticCurveTo(x, y, x, y + LTradius);// ctx.stroke();ctx.closePath();},/*** 文本填充方法* @param {String} ctx 画布实例对象名* @param {Object} obj 文本属性* obj = {x: 绘制文本的左上角 x 坐标位置,如果这个文本要基于一个盒子水平居中,此值应该写盒子的左上角 x 坐标位置,y: 绘制文本的左上角 y 坐标位置,color: 绘制文本的颜色,size: 绘制文本的字体大小,isCenter: 文字的水平对齐方式(true,false),text: 在画布上输出的文本内容,width: 展示当前文本盒子的宽度,在文本需要水平居中是要加这个参数,bold: 字体是否需要加粗(true、false)}*/drawText(ctx, obj) {ctx.save();ctx.fillStyle = obj.color;ctx.setTextBaseline("top");if (obj.bold) {ctx.font = `normal bold ${obj.size}px PingFangSC-Regular`;} else {ctx.font = `normal 100 ${obj.size}px PingFangSC-Regular`;}if (obj.isCenter && obj.width) {ctx.fillText(obj.text,obj.x + (obj.width - ctx.measureText(obj.text).width) / 2,obj.y);} else {ctx.fillText(obj.text, obj.x, obj.y);}ctx.restore();ctx.closePath();},// 文本宽度计算measureText(text, fontSize = 10) {let width = 0;String(text).split("").forEach(item => {if (/[a-zA-Z]/.test(item)) {width += 7;} else if (/[0-9]/.test(item)) {width += 5.5;} else if (/\./.test(item)) {width += 2.7;} else if (/-/.test(item)) {width += 3.25;} else if (/[\u4e00-\u9fa5]/.test(item)) {// 中文匹配width += 10;} else if (/\(|\)/.test(item)) {width += 3.73;} else if (/\s/.test(item)) {width += 2.5;} else if (/%/.test(item)) {width += 8;} else {width += 10;}});return (width * fontSize) / 10;},/*** 文本划线* @param {String} ctx 画布实例对象名* @param {Object} obj* obj = {sx: 划线的开始位置的 x 坐标位置,sy: 划线的开始位置的 y 坐标位置,ex: 划线的结束位置的 x 坐标位置,ey: 划线的结束位置的 y 坐标位置,lineWidth: 线条的宽度,color: 画线的颜色}*/lineation(ctx, obj) {// 开始一个新的绘制路径ctx.beginPath();// 设置线条的宽度ctx.setLineWidth(1);// 定义直线的起点坐标为ctx.moveTo(obj.sx, obj.sy);// 定义直线的终点坐标为ctx.lineTo(obj.ex, obj.ey);// 设置画线的颜色ctx.strokeStyle = obj.color;// 沿着坐标点顺序的路径绘制直线ctx.stroke();// 关闭当前的绘制路径ctx.closePath();}})

效果图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。