- 原生微信小程序开发,使用 lottiejs-miniapp 实现 Lottie 动画的播放
在原生微信小程序开发中,使用 lottiejs-miniapp 实现 Lottie 动画的播放。 lottiejs-miniapp 基于 lottie-web ,当前使用的 lottie-web 版本号为: 5.8.1 “动效”微信小程序 演示: [图片] 打开微信开发工具: 我在这里新建了一个代码片段作为演示: (代码片段:https://developers.weixin.qq.com/s/Eo0K1emN7zwj) [图片] 1、在项目目录(我这里是在index目录)执行命令,初始化 npm 项目: npm init 2、安装 lottiejs-miniapp 组件: npm i lottiejs-miniapp 安装完 lottiejs-miniapp 组件后,我们可以发现在 index 目录下多出了一个 node_modules 文件夹,里面将包含 lottiejs-miniapp。 [图片] 3、构建 npm 这是很重要的一步,在微信开发者工具 -- 顶部菜单 -- 工具 中找到“构建 npm”功能,并点击。 [图片] [图片] 开发者工具提示“完成构建”即可。 构建npm完成后,会在项目中多出一个 miniprogram_npm 文件夹,如下: [图片] 4、下一步,我们开始进行动画的调用。 第一,打开 index.wxml 文件,我们需要在页面文件中 预置一个 <canvas> 组件: <canvas id="lottiejs-canvas" canvas-id="lottiejs-canvas" class="lottiejs-canvas" type="2d"></canvas> 其中,id 和 canvas-id 都命名为"lottiejs-canvas"。 [图片] 第二,打开 index.js 文件,先引入 lottiejs-miniapp import * as lottie from 'lottiejs-miniapp' [图片] 第三,在 index.js 文件,onReady() 中使用如下代码调用动画 wx.createSelectorQuery().select('#lottiejs-canvas').fields({node: true, size: true}).exec(res => { const canvas = res[0].node; const ctx = canvas.getContext('2d'); const dpr = wx.getSystemInfoSync().pixelRatio; canvas.width = res[0].width * dpr; canvas.height = res[0].height * dpr; ctx.scale(dpr, dpr); lottie.setup(canvas); lottie.loadAnimation({ loop: true, autoplay: true, //animationData: animationData, path: 'https://www.lottiejs.com/wp-content/uploads/2022/01/83351-taking-the-duggy-out.json', rendererSettings: { context: ctx, }, }); }); 大家主要替换 loadAnimation 中的 path 参数为自己Lottie动画json文件的http地址即可。 [图片] 我们使用了一个测试动效json: https://www.lottiejs.com/wp-content/uploads/2022/01/83351-taking-the-duggy-out.json 大家一定注意执行时要开启 不校验域名的 功能。 [图片] 第四,在 index.wxss 文件,可以对 <canvas> 组件添加样式,也可以在此为Lottie 动效添加背景颜色效果: .lottiejs-canvas{ width: 100%; height: 300px; background-color: rgb(255, 187, 0); } [图片] 到此,我们就可以预览动画效果了: [图片] 代码片段地址:https://developers.weixin.qq.com/s/Eo0K1emN7zwj 代码片段使用注意事项: 1、填写自己的小程序测试appid; 2、执行 npm install 安装依赖; 3、执行构建 npm 功能。
2022-01-11 - 地图瓦片/ Leaflet/自定义图层WMSLayer,小程序都不能用?来试试这个方法
需求 最近项目甲方想把PC端的地图线路绘制在手机上,并且还要在小程序上,听得我心里一惊,那么多线,那么多点符号,我该如何画啊,小程序最大setData也有1M的限制。但是需求来了就得想办法解决。 寻找方法 1、小程序方法[代码]polyline[代码]+[代码]marker[代码](适用普通的点位渲染) 小程序文档翻了翻,发现map组件文档有个 “聚合能力” 我似乎看见了新大陆,觉得肯定可以满足,经过一番研究,还是不能满足,因为这种方法只能用[代码]polyline[代码]来画线,而点或符号用[代码]marker[代码]来画,这种方法数据要处理大多了,因为我的项目线多,符号也多还不同形状的符号,PC端的显示是使用瓦片来渲染,没有分那么多符号和点位,这个方法以失败告终。有兴趣可以看下这个博客写的内容和我这里讲的差不多:微信小程序添加外部地图服务数据 2、自定义图层WMSLayer 上面方法不行,于是我找了gis,跟他讨论了我这个需求,看看有没有办法可以满足我的需求,他们就给我推荐了自定义图层WMSLayer,他说PC端就是用这种方式实现,导入一份数据就可以了。我就说好的,我自己回去研究了一番,发现是需要引入GL的包,但是小程序不支持dom操作,和普通web页面还是有区别,于是我就放弃了该方法。 3、Leaflet插件 这个方法也是gis那边介绍的一个插件库,我寻找了很多遍,发现没有支持小程序的插件库,只是支持web网页开发,还是无法使用到小程序中。传送门leaflet地址 4、小程序个性化图层 这个方法我研究过,就是可以直接导入图层瓦片,最终腾讯生成一个个性化地图id,然后小程序调用个性化图层id。该方法好像还行,但是我没有具体操作,因为我的数据不是固定的,随时会改变,如果每次改变又去改个性化地图就惨了,这种方法适用于景区景点类型。 腾讯地图个性化图层 看见社区有人发的web效果图地址 个性化地图使用指南 我使用的方法 思来索去既然瓦片是图,那能不能让gis那边直接返回一张图片呢?我这边就贴图就行?因为小程序刚好有个[代码]自定义图片图层[代码]可以跟着地图变大变小[图片] 感觉这个方法挺好的,联想了加入是一张张瓦片我也可以对准位置贴上去,连在一起就是我想要的效果了。于是找了gis那边的同事,发现他们有这种方法可以获取图片。addGroundOverlay文档地址 思路 先看下addGroundOverlay的参数 [图片] 单独一个参数抽出来 [图片] 由图可见,有一个很重要的参数[代码]bounds[代码]这个参数,这个参数就是获取地图的对角点,用来确定当前地图视野范围,有了这个参数,我们就叫gis那边生成一张图片,然后粘贴到我们小程序的地图上面就完成了渲染。这里需要注意几点: gis那边生成的图片需要几个参数, a、需要对角点即[代码]bounds[代码]一样的参数,可以通过小程序提供的MapContext.getRegion获取当前地图的视野范围 b、需要获取你当前手机全屏屏幕宽高(windowWidth这个),用这个宽高传给gis那边生成图片的宽高 c、使用地图map组件提供的方法[代码]bindregionchange[代码]来监听,当前缩放或者中心点移动,然后去请求最新视野的图片粘贴上去 d、这里有个不好的问题就是用[代码]MapContext.updateGroundOverlay[代码]方法,更新上一张的贴图会出现闪动问题(即更新最新的图片会发生显示原来图片位置、然后隐藏才显示最新的图片位置),为了解决这个问题,我使用了每次变动位置请求最新图片,都用增加方法[代码]MapContext.addGroundOverlay[代码]去添加贴图到地图,然后把旧的贴图全部删除,为了效果看起来像懒加载,等加载完最新的图片在去删除旧的图片,这样就不会出现闪动的问题 核心代码如下: [代码]onReady: function (options) { this.MapContext = wx.createMapContext('mapId', this) this.getSystemInfo = wx.getSystemInfo().then(res => { this.getSystemInfo = res }) this.indexId = 1 }, bindregionchange: function (e) { if (e.type === 'end') { const northeast = e.detail.region.northeast const southwest = e.detail.region.southwest if (mapTimer) clearTimeout(mapTimer) mapTimer = setTimeout(()=> { this.updataMap(southwest, northeast) }, 100) } }, updataMap(southwest, northeast) { const northeast1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(northeast.longitude, northeast.latitude)[1] } const southwest1 = { longitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[0], latitude: CoordTransformUtil.GCJ02ToWGS84(southwest.longitude, southwest.latitude)[1] } overlayId.push(this.indexId) this.indexId = this.indexId + 1 this.MapContext.addGroundOverlay({ id: this.indexId, src: `https://xxx/export?bbox=${northeast1.longitude},${northeast1.latitude},${southwest1.longitude},${southwest1.latitude}&bboxSR=4490&layers=&layerDefs=&size=${this.getSystemInfo.windowWidth},${this.getSystemInfo.windowHeight}`, bounds: { southwest: southwest, northeast: northeast }, success: async (res) => { // 由于使用updata图层会出现每次闪图渲染问题,所以每次获取图层都是新增的,故这里需要把每次渲染的图层删除,只留最后一次 if (mapTimer2) clearTimeout(mapTimer2) mapTimer2 = setTimeout(async() => { await Promise.all(overlayId.map(async (item) => { await this.MapContext.removeGroundOverlay({ id: item }); overlayId = overlayId.filter(fil => fil != item) })); }, 500) }, fail: (err) => { console.error(err, 'fail...addGroundOverlay') } }) } [代码] 总结 抱歉了,其实我这是不讲武德,把技术点给gis那边处理了,我这边只需要把他们处理好的图片粘贴上去就好了,经过验证该方法确实可行的哦 解决问题才是王道 代码片段:https://developers.weixin.qq.com/s/taAR41mz7GHT
2023-03-27 - 小程序formId生成多个的解决方案
小程序消息推送formId生成多个
2018-11-28