- [拆弹时刻]使用官方wxml-to-canvas组件生成海报的注意事项和坑点
使用官方组件[代码]wxml-to-canvas[代码]的背景 由于现在很多小程序业务都需要生成海报 保存成图片便于用户分享,以往生成canvas的海报需要用户手写canvas对应的JS比较麻烦,所以官方提供了一个组件[代码]wxml-to-canvas[代码],的确方便了不少,但也有一些坑和注意事项。 [图片] 基础注意事项 默认尺寸为400*300,需要在引入的标签里自定义修改。 [代码]<wxml-to-canvas class="widget" height="996" width="500"></wxml-to-canvas> [代码] canvas 支持最大尺寸为 4096,实际像素 < 4096,实际高度需 < 4096/3 = 1356 只支持[代码]text[代码]、[代码]view[代码]和[代码]image[代码]三种标签,[代码]text[代码]和[代码]image[代码]标签必须指定 width 和 height 属性,否则会导致布局错误。[代码]view[代码]可以只制定宽度 文字 必须放在[代码]text[代码]中,放在[代码]view[代码]中无法显示 如果你要设置背景颜色,请使用[代码]backgroundColor[代码],而非[代码]background[代码],[代码]border[代码]同理~ 多个absolute元素时,因为没有z-index,template元素自上而下渲染,对应z-index依次增高 导出图片过大,可以通过[代码]canvasToTempFilePath({fileType, quality})[代码]配置里面的[代码]quality[代码]字段来减小 解决一些坑 1、[代码]wxml-to-canvas[代码]组件只支持临时地址和网络地址,不支持base64和本地图片,可以通过[代码]writeFile[代码] 把base64转成临时地址 [代码]const fs = wx.getFileSystemManager(); let qrcodeBase64 = QRresult.data; let qrcodeLink = `${wx.env.USER_DATA_PATH}/qrcodeLink.gif`; fs.writeFile({ filePath: qrcodeLink, data: qrcodeBase64, encoding: 'base64', success: res => { console.log(res) shopJson.qrcode = qrcodeLink; this.renderToCanvas(); }, fail(res) { console.error(res) } }) [代码] 2、[代码]text[代码]设置不同style不是连续inline-block效果,而是block的换行效果 这个只能通过计算字数来设置[代码]text[代码]的width,将不同css的文字连续在一起。 上代码! 样式构建代码(仅供参考) [代码]//DEMO.JS 部分参数外部传入 const style = { canvas_box: { width: 330, height: 420, borderRadius: 20, backgroundColor: '#fff', padding: 20, }, pop_img: { width: 290, height: 146, borderRadius: 20, overflow: "hidden", display: "block" }, pop_h3: { lineHeight: 24, height: 24, paddingTop: 10, fontSize: 16, color: "#333", width: 290, }, pop_border_bottom: { width: 290, height: 1, backgroundColor: '#eee', }, pop_h4: { lineHeight: 20, paddingTop:10, width:300, fontSize: 14, color: "#666", paddingBottom: 10, }, pop_h4_text: { width: 300, height: 20, }, pop_h5: { lineHeight: 20, paddingTop: 12, fontSize: 12, width: 290, position: "relative", zIndex: 2, }, pop_h5_txt: { fontSize: 12, color: "#000", height: 20, }, pop_orange: { fontSize: 12, color: "#FD6805", height: 20, }, pop_hint: { position: "absolute", right: 20, bottom: 20, width: 290, height: 20, display: "block", }, pop_hint_txt: { height: 20, width: 290, fontSize: 12, color: "#999", }, pop_QRcode: { position: "absolute", right: 20, bottom: 20, width: 90, height: 90, display: "block", zIndex: 1, }, } const poster = (shop: any) => { if (shop) { console.log(shop.address.length) //判断文字是否过长 if(shop.address && shop.address.length > 20){ shop.allAddress = `<view class="pop_h4"><text class="pop_h4_text">${shop.address.slice(0, 20)}</text><text class="pop_h4_text">${shop.address.slice(20)}</text></view>` }else { shop.allAddress = `<view class="pop_h4"><text class="pop_h4_text">${shop.address}</text></view>` } const wxml = ` <view class="canvas_box"> <image class="pop_img" mode="widthFix" src="${shop.img}" /> <view class="pop_h3"><text class="pop_h3">这里是名字</text></view> ${shop.allAddress} <view class="pop_border_bottom"></view> <view class="pop_h3"><text class="pop_h3">这里是title</text></view> <image class="pop_QRcode" src="${shop.qrcode}" /> <view class="pop_h5"><text class="pop_h5_txt">最新活动请扫码</text><text class="pop_orange">扫描二维码享受店家专属折扣!</text></view> <view class="pop_hint"><text class="pop_hint_txt">神秘社区强力支持</text></view> </view>` return { wxml, style }; } } module.exports = { poster, } [代码] [代码]let shopJson = { name: "皮卡球", address: "阿罗拉阿罗拉", img: "https://aaa.png", qrcode: "https://aaa.png", }; page({ renderToCanvas() { let { wxml, style } = poster(shopJson); const p1 = this.widget.renderToCanvas({ wxml, style }) console.log(p1) p1.then((res: any) => { console.log('container', res.layoutBox) this.container = res }) }, }) [代码] 将转化好的canvas保存到手机中 [代码]const p2 = this.widget.canvasToTempFilePath(); p2.then((res: any) => { console.log(res.tempFilePath); //保存到本地 wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success(res) { console.log(res); wx.showToast({ title: "保存成功", icon: "success", duration: 2000, }); }, //被拒绝后的操作 fail(res) { console.log(res); wx.showModal({ title: "提示", content: "保存失败,重新打开", success(res) { if (res.confirm) { console.log("用户点击确定"); wx.getSetting({ success(res) { console.log(res.authSetting); }, }); } }, }); }, }); }); [代码] 官方地址 https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/extended/component-plus/wxml-to-canvas.html 代码片段 https://developers.weixin.qq.com/s/r6UBlEm17pc6
2023-10-20 - 云数据库聚合(aggregate)时如何操作数组型字段的查询与分组?
[代码]{[代码][代码] [代码][代码]"_id"[代码][代码]:[代码][代码]"f885cb355d9ad18d0cc3aed45dc42e87"[代码][代码],[代码][代码] [代码][代码]"status"[代码][代码]:0,[代码][代码] [代码][代码]"items"[代码][代码]:[代码][代码] [代码][代码][[代码][代码] [代码][代码]{[代码][代码]"pId"[代码][代码]:[代码][代码]"075734515d99df300c4f12df68415e50"[代码][代码],[代码][代码]"pPrice"[代码][代码]:110.0,[代码][代码]"pCost"[代码][代码]:85.0,[代码][代码]"quantity"[代码][代码]:1.0},[代码][代码] [代码][代码]{[代码][代码]"pId"[代码][代码]:[代码][代码]"392890432d99df300c4f12df68415f99"[代码][代码],[代码][代码]"pPrice"[代码][代码]:110.0,[代码][代码]"pCost"[代码][代码]:85.0,[代码][代码]"quantity"[代码][代码]:2.0}[代码][代码] [代码][代码]],[代码][代码] [代码][代码]"_openid"[代码][代码]:[代码][代码]"oVCJa5DGovfnzgKr0u2Gn5viMHug"[代码][代码]}[代码] 类似于这种典型的数据结构,items为一个对象数组型字段,相当于关系型数据库的子表数据。我业务上需要对items做一些匹配和分组查询。如下语句: [代码]const ordersRes = await db.collection([代码][代码]'orders'[代码][代码])[代码][代码] [代码][代码].aggregate()[代码][代码] [代码][代码].addFields({[代码][代码] [代码][代码]matched: $.[代码][代码]in[代码][代码]([[代码][代码]'$items.pId'[代码][代码],pIds])[代码][代码] [代码][代码]})[代码][代码] [代码][代码].match({[代码][代码] [代码][代码]sellerId: sellerId,[代码][代码] [代码][代码]status: $.neq(-1),[代码][代码] [代码][代码]matched: [代码][代码]true[代码][代码] [代码][代码]})[代码][代码] [代码][代码].group({[代码][代码] [代码][代码]_id: [代码][代码]'$items.pId'[代码][代码],[代码][代码] [代码][代码]pQuantity: $.sum([代码][代码]'$items.quantity'[代码][代码])[代码][代码] [代码][代码]})[代码][代码] [代码][代码].end()[代码] 遇到两个问题: 问题1:查询时,想针对pId进行筛选,我事先准好了一个有效的pIds数组,match有效的pId,但输出为0。而我用类似的语法,使用where可以工作,能把匹配上的记录输出。 [代码].where({[代码][代码] [代码][代码]sellerId: sellerId,[代码][代码] [代码][代码]status: _.neq(-1),[代码][代码] [代码][代码]'items.pId'[代码][代码]: _.[代码][代码]in[代码][代码](pIds)[代码][代码] [代码][代码]})[代码] 问题2,想针对pId进行分组,合计对应pId的quantity,但是并不能有效分组。实际输出的group条件是一个pId数组,也就是把items下面的多个pId抽取出来组成数组作为group条件了,并不是我所期望的单个pId进行分组,输出结果如下所示: [代码]list: Array(10)[代码][代码]0: {_id: Array(2), pQuantity: 0}[代码][代码]1: {_id: Array(2), pQuantity: 0}[代码][代码]2: {_id: Array(3), pQuantity: 0}[代码][代码]3: {_id: Array(3), pQuantity: 0}[代码][代码]4: {_id: Array(2), pQuantity: 0}[代码][代码]5: {_id: Array(2), pQuantity: 0}[代码][代码]6: {_id: Array(1), pQuantity: 0}[代码][代码]7: {_id: Array(1), pQuantity: 0}[代码][代码]8: {_id: Array(1), pQuantity: 0}[代码][代码]9: {_id: Array(1), pQuantity: 0}[代码]
2019-10-09 - wx.showToast()的duration不起作用?
图片中第123行,wx.showToast()的持续时间我设置的5秒,但是实际情况是,在显示「发送成功」的瞬间,就开始跳转页面了。 为什么duration不起作用?以及如何解决? [图片]
2020-04-14