Weex正如它的目标,

一套构建高性能、可扩展的原生应用的跨平台开发方案

Weex 给大家带来的无疑是客户端开发效率的提升,我们可以通过一套代码,实现web,android, iOS的三个平台上运行。自己最近尝试了一次借助weex的插件机制,使用Weex-Amap地图插件 可以开发 LBS 相关的应用。

首先我们先来看下运行的效果吧:

iOS 版

Android 版

截图数据仅供参考

它大概具备下面的一些功能;

统计用户在运动过程中的距离累计,时间计算等。

存储用户的运动数据

使用地图定位和距离计算的API,实现距离统计。

显示地图折线,通过对定位的数据地理位置进行折线绘制

统计用户运动的数据,计算总距离和时间

点击用户的历史记录,可以查看轨迹

感觉和大家所用到的app功能相差不多了,但实际上我们借助 Weex 和 Weex-Amap 插件可以非常快速的实现这些功能,下面我们来看下具体怎么实现吧。

使用 weex-toolkit 创建项目

首先我们按照官网的教程安装weex-toolkit。如果已经安装过请忽略。

$ npm install -g weex-toolkit

安装完成后,我们创建一个项目目录,比如running-app。

weex create running-app

大家可能会看到下面的提示,输入y安装即可。

This command need to install weexpack. Install now? Yes

项目创建完成后,我们需要添加我们的运行平台比如android或者ios,这里我们添加 android 平台。

weex platform add android

添加成功后,我们在通过weex的插件机制,安装weex-amap高德的地图依赖。

weex plugin add weex-amap

安装完成后,你可以到项目目录 plugins 里面看下是否有新增的 weex-amap 的项目目录,如果存在即表示插件安装成功。你就可以在src目录下用we或者vue开发应用代码了

设计原理

[weex-amap]结合了高德地图多个功能,比如定位,地图缩放,绘制折现,进行点的标记等常用功能。实现一款跑步应用,我们需要解决最核心的问题就是:

统计一个在运动过程的总距离 (s)

当我们能够获取到总距离(s)的时候,和运动时间(t) 通过小学物理知识,我们知道:

速度(v) = 总路程(s) / 总时间(t)

在结合一些公式,我们还可以计算出我们的 卡路里(c);

其中 weex-amap 正好可以解决上面最为核心的问题,我们可以通过定位,然后在通过比较两个连续点之间的距离,进行累加(微分累计),从而获取总距离。(当然这只是最为简单的实现原理,做成完整的app还需要更加科学化的算法)

[weex-amap] 其中提供了这么两个API

getUserLocation 用于获取用户的当前位置地理位置,用户会获取经纬度 [Long, Lat]

getLineDistance 用户获取传入的两个地理位置的直线距离

除了这两个API,我们还需要用到地图的一个组件, 就是折线绘制 weex-amap-polyline 。它可以通过path属性接收到一组地理位置坐标值,从而在地图上绘制连续的折线。比如:

其中 your_path 指定类似这样的数据: [[116.487, 40.00003],[113.487, 40.0002]...]

关于更多的如何使用weex-amap 插件,可以参考这篇 文章 以及 官方Demos

设计页面功能和逻辑

大家也都用过跑步的APP,常见的界面布局如下:

那么我们页面的基本结构就已经出来了:

module.exports = {

data: {

keys: {

h5:'f4b99dcd51752142ec0f1bdcb9a8ec02',

ios: 'c551f83e1e5b19af89c74096f1c0f007',

android: 'db6a973159cb0c2639ad02c617a786ae'

},

zoom: 16,

pos: [116.48635, 40.00079],

status: 1,

polylinePath: []

},

methods: {

}

}

其中 我们使用了weex-amap组件,其中一些属性:

zoom 表示设置的地图的缩放级别

geolocation 添加地图定位插件没如果你需要定位功能,必须设置

sdk-key 设置地图的密钥,这是地图开发必须申请 (前往高德地图申请)

center 设置地图的中心,需要设置一个数组,传入地理位置坐标[116.487, 40.00003]第一个数字表示经度,第二个值表示纬度

其中的样式参考如下,当然你也可以自己实现一个布局:

.container{

position: relative;

flex: 1;

min-height: 600;

background-color: #eee;

}

.map{

flex: 1;

min-height: 600;

}

.map-controller{

z-index: 10000;

position: absolute;

left: 0;

right: 0;

bottom: 0;

height: 500;

background-color: rgba(255,255,255,1);

border-top-width: 2;

border-top-color: rgba(0,0,0,.25);

}

.distance-wrap{

flex: 1;

flex-direction: row;

justify-content: center;

align-items: center;

}

.dashboard{

flex: 1;

flex-direction: row;

}

.btn-wrap{

flex: 1;

flex-direction: row;

align-items: center;

justify-content: center;

}

定义数据模型

我们需要在界面里显示四组数据:

运动距离

运动时间

运动消耗

运动配速

自己设计的runningData里面包含了下面一些数据:

runningData: {

distance: 0, // 表示运动的累计距离

miles: 0, // 表示运动的累计距离,单位是公里用于界面显示

path: [], // 运动坐标数据

time: '00:00:00', // 用于界面的运动时间显示

seconds: 0, // 运动的时间,单位:秒

speed: 0, // 配速

calories: 0, // 运动的消耗,单位千卡

}

处于计算的方便其中我设计了几个用于数据格式的转换和计算,在我的 utils.js 里面。

这个时候我们需要在模板里面添加一些代码用于显示这些数据;

{{runningData.miles}}

公里

运动时间

{{runningData.time}}

配速

{{runningData.speed}}

热量

{{runningData.calories}}

添加地图折线polyline

添加流程控制

在我们进行跑步的过成功无疑就是这么几个状态,我将它定义在了 status.js

module.exports = {

RUNNING_READY: 1, // 跑步开始前

RUNNING_DOING: 2, // 跑步进行中

RUNNING_PAUSE: 3, // 跑步暂停中

RUNNING_END: 4 // 跑步结束,

RUNNING_PREVIEW: 5 // 数据预览

};

我们通过这几个状态来实现对界面的操作,比如开始或者暂停。这个时候我们需要添加一一些用于界面控制的按钮。

...

实现流程

我们接下来,按照流程来实现我们的程序逻辑:

const status = require('./lib/status');

...

module.exports = {

// ...

methods() {

start() {

},

stop() {

},

continue() {

},

end() {

},

}

}

start

开始的业务逻辑很简单,就是更改页面状态到运行中,然后执行程序。

start() {

this.status = status.RUNNING_DOING;

this.runningAmapGeolocation();

}

stop

暂停的话,我们需要清除掉页面的计时器。

stop() {

this.status = status.RUNNING_PAUSE;

clearInterval(this.timeRecorder); // 计算时间

clearInterval(this.amapRecorder); // 计算定位

}

end

点击结束按钮,我们需要清除计时器,然后显示出累计的数据就行了,当然做的复杂一点,还可以进行数据的存储等。

end() {

clearInterval(this.timeRecorder);

clearInterval(this.amapRecorder);

/* 使用存储

* storage.getItem('runningData', (res) => {

* ...

* })

*/

}

实现地图定位

在添加完 weex-amap 模块后,我们就可以实现地图的定位和距离计算。

// 引入 amap 模块

const Amap = require('@weex-module/amap');

etUserLocation(callback) {

Amap.getUserLocation(this.$el('map2017').ref, callback);

}

其中callback回调中会返回一个对象:

{

result: 'success' or 'fail', // 接口调用是否成功

data: {

position: [Long, Lat] // 返回经纬度

}

}

实现地图距离计算

// 我们引入第三发utils文件,用于一些计算

const utils = require('./lib/utils');

calcDistanceAndSpeed() {

const len = this.runningData.path.length

if(len > 1) {

// 计算两个点之前的距离

Amap.getLineDistance(this.runningData.path[len-1], this.runningData.path[len-2], (res) => {

if(res.result == 'success') {

console.log(res.data.distance);

this.runningData.distance += res.data.distance;

}

// 将总长度转化为千米

this.runningData.miles = utils.mtoKm(this.runningData.distance);

// 初略的计算卡路里

this.runningData.calories = (this.runningData.distance / 1000).toFixed(2);

// 速度换算

this.runningData.speed = utils.calcSpeed(this.runningData.distance, this.runningData.seconds);

});

}

}

其中 utils.js 的实现可以参考 这里。

让程序自动采集数据

大家写JS一定都实现过一个倒计时的程序,常用的解决方案就是 setInterval (关于setInterval 时间的执行的问题可以看这里) 。

当点击开始按钮后,我们需要设置一个计时器,用户进行用户时间的计算:

countDownTime() {

this.timeRecorder = setInterval(() => {

this.runningData.seconds ++;

// 进行格式转化 12s => 00:00:12

this.runningData.time = utils.setTimeFormat(this.runningData.seconds);

}, 1000);

},

// 设置定位的计时器

runningAmapGeolocation() {

this.setUserLocation((res) => {

if(res.result == 'success') {

this.pos = res.data.position;

this.runningData.path.push(res.data.position);

}

});

this.amapRecorder= setInterval(() => {

this.setUserLocation((res) => {

if(res.result == 'success') {

this.runningData.path.push(res.data.position);

this.polylinePath = Array.from(this.runningData.path);

this.pos = utils.setPosition(this.runningData.path);

this.calcDistanceAndSpeed();

}

});

}, 10000);

},

透过代码我们可以看到程序会大约每隔十秒进行一次定位,然后再进行计算和距离累加。

打包运行

开发完毕后,我们可以运行命令,让它安装到我们的测试手机上。

weex run android

PS: 当然如果你要做出一个 科学 的跑步程序,还需要你加入大量测试和数据的纠正,比如我们在使用过程会遇到定位的偏差,断网, 用户没有开启定位权限等问题,这些都是我们需要考虑和应对的

运行 Github 上项目

项目运行截图:

如果大家在实现过程中遇到问题可以参考 Github 上这个项目的一些代码。相对刚刚这个简单的功能,它完善了存储和数据预览,以及倒计时等小细节。

1.首先克隆这个项目(后面会写如何自己创建这样的项目). 确保你自己环境安装了weex-toolkit

git clone https://github.com/weex-plugins/amap-running-app

2.进入克隆的项目目录,然后执行 npm install

3.测试你的需要运行的平台,比如android 或者 ios

weex plaform add android

weex plugin add weex-amap

这个时候你就可以运行命令看具体运行的效果了:

weex run android

扩展阅读

Android地图跑步项目,通过Weex 300行代码开发一款简易的跑步App相关推荐

  1. Weex 300行代码开发一款简易的跑步App

    通过Weex 300行代码开发一款简易的跑步App 2017-03-28 Weex正如它的目标, 一套构建高性能.可扩展的原生应用的跨平台开发方案 Weex 给大家带来的无疑是客户端开发效率的提升,我 ...

  2. 三百行python代码的项目_使用300行代码创建一个分布式系统

    使用 300 行代码创建一个分布式系统 构建一个分布式系统是很困难的. 它需要可扩展性. 容错性. 高可用性. 一致性. 可伸缩以及高效.为了达到这些目的,分布式系统需要很多复杂的组件以一 种 复杂的 ...

  3. Pygame实战项目:用300行代码写出贪吃蛇小游戏

    贪吃蛇是一款逻辑清晰.操作简单.老少咸宜.备受欢迎的休闲小游戏. 下面就给大家介绍一下贪吃蛇游戏的基本原理,以及实现贪吃蛇所需要的相关方法. 一.主要思路 我们的贪吃蛇游戏将主要包括三个核心模块,分别 ...

  4. python如何自制音乐软件_70行python代码制作一款简易的音乐播放器!

    今天整理了以前的python作业代码,发现了一些有趣的小东西,比如下面这个,大概70行代码制作一款简易的音乐播放器. install some packages pip install pygame ...

  5. 特斯拉AI总监用300行代码实现“迷你版GPT”,上线GitHub三天收获3.3k星

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI "GPT并不是一个复杂的模型." 前OpenAI科学家.现任特斯拉AI总监的Andrej Karpathy在自己的Gi ...

  6. 一天star量破千,300行代码,特斯拉AI总监Karpathy写了个GPT的Pytorch训练库

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 整理:公众号@机器之心 本文仅做学术分享,如有侵权,请联系删除. 如果说 GPT 模型是所向披靡的战舰 ...

  7. android底部滑出view,Android CoordinatorLayout与NestedScrollView基于Behavior几行代码实现底部View滑入滑出...

    Android CoordinatorLayout与NestedScrollView基于Behavior几行代码实现底部View滑入滑出 在CoordinatorLayout的Behavior出现之前 ...

  8. 通过Mesos、Docker和Go,使用300行代码创建一个分布式系统

    [摘要]虽然 Docker 和 Mesos 已成为不折不扣的 Buzzwords ,但是对于大部分人来说它们仍然是陌生的,下面我们就一起领略 Mesos .Docker 和 Go 配合带来的强大破坏力 ...

  9. python编程小游戏代码-Python小游戏之300行代码实现俄罗斯方块

    前言 本文代码基于 python3.6 和 pygame1.9.4. 俄罗斯方块是儿时最经典的游戏之一,刚开始接触 pygame 的时候就想写一个俄罗斯方块.但是想到旋转,停靠,消除等操作,感觉好像很 ...

  10. python小游戏代码大全-Python小游戏之300行代码实现俄罗斯方块

    前言 本文代码基于 python3.6 和 pygame1.9.4. 俄罗斯方块是儿时最经典的游戏之一,刚开始接触 pygame 的时候就想写一个俄罗斯方块.但是想到旋转,停靠,消除等操作,感觉好像很 ...

最新文章

  1. Java面向对象知识概括归纳与总结
  2. id设置为10000开始
  3. java购物菜单的选择功能_java-第四章-升级我行我素购物管理系统,实现购物菜单的选择...
  4. python面向对象(2)—— 继承(3)
  5. SQLl中的left join、right join、inner join详解
  6. Redhat6.5中搭建Postfix邮件系统
  7. 交换排序 java_Java交换排序:冒泡排序和快速排序
  8. google四件套之Dagger2。从入门到爱不释手,之:Dagger2基础知识及在Java中使用(2)
  9. 通信原理及系统系列3—— 基于卷积编码的2ASK通信系统设计(非相干解调)
  10. simulink 菜单栏 不见了
  11. android官网m魅族15,魅族15/Plus/Lite等机型现身Android官网:设计惊艳
  12. 计算机会计期末试题及答案,山东大学网络教育期末考试试题及答案-会计信息系统 A_3...
  13. Attack Lab
  14. 第16期高级转录组分析和R数据可视化培训(2022年1月)
  15. linux关闭虚拟网卡,KVM---关闭虚拟网卡virbr0的方法
  16. 求一段字符串内最长的非空子字符串的长度(实例)
  17. 无屏幕有线情况下笔记本电脑连接树莓派
  18. 2020电工(初级)考试题及电工(初级)模拟考试系统
  19. i.MX6 ARM工控板 开发设计
  20. 安装rhel8.2虚拟机

热门文章

  1. NRF52832 PWM 占空比调整详解
  2. Matlab线性拟合和非线性拟合
  3. 微控制器和微处理器的区别(含课本原图)
  4. Oracle 查询重复字段
  5. mac电脑投屏到小米盒子_苹果手机,小米盒子投屏,连接不上,什么情况?
  6. 磁珠 符号_FB是磁珠的符号 | 学步园
  7. Linux命令对应的英文及整体学习法
  8. App登录功能(用户名+密码)
  9. 牛客小白月赛5-E-面积(area)(波尔约-格维也定理+皮克公式)
  10. 经典企业文化书籍推荐,有了这6本书企业文化落地不再是难事