- 原生微信小程序开发,使用 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 - 关于申请小程序地理位置相关接口的规范
随着小程序生态的发展,越来越多小程序开发者会通过官方接口来给用户提供便捷的服务。如何在提供良好的体验时又能保障用户合法权益,如何正确的进行相关接口准入申请?本文将会从以下方面进行详细说明。 一、可通过相应接口准入申请的小程序 对象:自身已有地理位置相关使用场景或需地理位置相关场景完善服务内容的小程序 申请wx.getLocation接口参考案例1)含有交通服务类目,同时含有代驾服务、租车网点查询服务、查询附近车辆服务、城市共享交通服务等 [图片] [图片] 2)含有餐饮-点餐平台、餐饮-外卖平台类目、餐饮-餐饮服务场所/餐饮服务管理企业,并涉及实际送餐场景 [图片] [图片] 3)含有工具-信息查询、工具-办公、工具-设备管理类目,并涉及与地理位置相关的打卡服务业务,如智能门禁、智能穿戴设备等 [图片] 4)含有汽车服务-维修保养、汽车服务-汽车用品、汽车服务-汽车经销商/4S店、汽车服务-汽车厂商、汽车服务-汽车预售、汽车服务-二手车类目,涉及提供汽车售卖、维保洗美服务、查找附近的维修点/洗车网点等导航服务 [图片][图片] 5)含有电商平台/商家自营类目,涉及提供售卖商品线下发货、收货服务、线下商超导览、导航服务 [图片] 6)含有金融-银行、金融-非金融机构自营小额贷款/融资担保/商业保理类目,涉及银行小程序提供线下网点预约、基于地理位置取号并现场报到、附近网点导航等服 [图片] 7)含有电商平台/商家自营类目,涉及提供售卖商品非即刻交易线下发货、收货服务,比如线下跑腿收货、社区团购线下自提点收货等服务场景 [图片] [图片] 申请wx.onLocationChange接口参考案例1)含有交通服务类目,同时含有代驾服务、城市共享交通服务等 [图片] 2)含有生活服务类目,同时含有线下跑腿、开锁服务、其他上门作业等实际服务内容 [图片] 3)含有旅游-景区服务、旅游-住宿服务,涉及提供景区导航、导览服务、酒店导航服务 [图片] 二、无法通过相关接口准入申请的小程序 1)开发者因涉及营销活动,希望申请wx.getLocation接口便于帮助用户定位所在位置,但根据服务内容可知当前仅需获取用户所在城市/地区,无需通过wx.getLocation获取详细的经纬度定位,使用wx.getFuzzyLocation、wx.chooseLocation或wx.choosePoi接口实现上述场景 [图片] 2)开发者因涉及提供外卖平台服务,希望申请wx.onLocationchange接口监听用户实时地理位置运动轨迹,但根据服务内容可知当前外卖平台服务仅需要获取用户外卖收货地址,并不展示派送员实时位置,无需通过wx.onLocationchange获取用户的实时运动轨迹,使用wx.getFuzzyLocation、wx.chooseLocation或wx.choosePoi接口实现上述场景 [图片] 3) 开发者因涉及提供新闻资讯服务,希望申请wx.onLocationchange接口监听用户实时地理位置运动轨迹,但小程序内未含有相关使用场景,所以暂时不支持 [图片] 4)开发者因涉及线上商城发货服务,需用户提供收货地址,希望申请wx.getLocation接口获取用户当前详细的实时位置,如果需要获取用户的收货地址可以使用wx.chooseAdress接口一键导入。如果需要省去用户手动填写地址的流程,可以使用wx.chooseLocation或wx.choosePoi让用户自行选择当前地理位置,无需获取用户获取用户当前详细的实时位置。 [图片] 5)房地产、餐饮、商家自营等小程序,希望申请wx.getLocation接口获取用户当前实时位置信息,为用户展示附近、周边门店信息,提供推荐营销服务,且小程序内未提供线下门店导航服务,仅在小程序内为用户提供附近、周边门店信息展示服务,该场景不支持使用wx.getLocation、wx.onLocationchange这类高精度位置接口,建议开发者使用wx.getFuzzylocation、wx.chooseLocation或wx.choosePoi实现上述场景。 [图片] 三、接口准入申请的步骤 1)登录微信公众平台:https://mp.weixin.qq.com,进入小程序后台「首页」,左侧导航栏点击「开发管理」模块 [图片] 2)「开发管理」模块下「接口设置」 [图片] 3)找到需要申请的地理位置接口点击「去开通」进入接口申请页面 [图片] 4)进入接口申请页面后,在接口「申请原因」中详细描述申请接口在小程序内的使用场景,或选择性提供小程序的图片视频或网页辅助审核,最后点击「提交申请」即完成该接口申请 [图片] 5)接口申请审核结果可通过「接口设置」模块的接口状态,或「通知中心」站内信进行查看 [图片] [图片]
03-13 - 地图瓦片/ 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