使用pixi.js开发一个智慧路口(车辆轨迹追踪)项目

项目效果

项目功能:

  • 位置更新、航向角计算。
  • debug模式。
  • 位置角度线性补帧。
  • 变道、转弯、碰撞检测。
  • mock轨迹数据

图片效果:

视频效果:

项目启动

项目地址

(如果觉得项目对你有帮助的话, 可以给我一个star 和 赞,❤️)

启动demo项目

  1. cd car-tracking-2d/demos/react-demo

  2. yarn

  3. yarn start

界面使用

debug 模式

浏览器url ?后面(search部分)加入参数debug=1

例如:http://localhost:3000/home?tunnelNo=tunnel1&debug=1

将会展示调试信息:

如图:车旁边的白色文字信息为debug模式才会展示的内容(由上到下为:里程、车id、车道id、[x,y]、旋转角度)

实现:

技术栈:

ts+pixi.js+任意前端框架

(前端框架使用vuereact或者其他框架都可以。只需要在mounted阶段,实例化我们暴露出来class即可。然后在destroyed或者unmounted阶段destory示例即可,后面会提到。)

pixi.js

官网介绍:

Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.

pixi.js是一个2D的WebGL的渲染库。但是没有three.js知名度高。一个原因是,我们2D的需求技术路线很多,可以是dom、svg、canvas draw api等,包括本项目也可以使用其他技术方案实现,希望通过本文,大家在实现这种频繁更新元素位置的功能,可以考虑一下pixi.js。

API快速讲解

这里只讲我们项目使用到的

Application
js 复制代码
import * as PIXI from 'pixi.js';

const app = new PIXI.Application({
    view: canvasDom // canvas dom 对象
});
Container

容器,功能为一个组。 当我们设置容器的scale(缩放)、rotation(旋转)、x、y(位置)时。里面的元素都会收到影响。

(ps:app.stage也是一个Container

每个 Container可以通过addChild(增加子节点)、removeChild(删除子节点),也可以设置子元素的zIndex(和css的功能一致)。子原始的scale(缩放)、rotation(旋转)、x、y(位置)是相对于Container的。

Sprite

精灵,渲染图片对象。

js 复制代码
carObj = Sprite.from('/car.svg')

Sprite.from(url),url相同的话,只会加载一次图片。纹理对象也只会创建一次。

anchor属性其他对象也有,设置定位点,类似于csstransform-origin

执行下面代码 carObj.anchor.set(0.5, 0.5)

如果x = 10 y =10,carObj的中心点的坐标就是(10,10),旋转原点也是(10,10),缩放也是如此。

Graphics

绘制几何图形,圆弧,曲线、直线等都可以。也支持fill和stroke,canvas draw api支持的,Graphics都支持。

Text

文本,比较简单。字体、颜色、大小,都支持。

  • 值得注意的是文本内容含有换行符时(\n \r),文本会换行。
  • pixi提供测量文本的width height的方法非常好用。
Tick
js 复制代码
this.app.ticker.add(() => {})

类似于requestAnimationFrame

具体实现

分三步,vue/react都一样:

1 获取canvas dom通过ref的方式。

2 创建我们封装Stage Road

3 组件销毁时,执行 stage.destroy(注意stage是我封装的,不是pixi的。使用方不需要使用pixi.js的api)

线性插帧

当有一个对象由坐标 点a(0,0)变换到点b(1000,1000),1秒内完成。 中间的变化值为: dx =1000 dy=1000 记录每帧的时间差t(当前帧距离第0帧的,单位毫秒)

所以第n帧位置信息为(0+dx / 1000 * t, 0+ dy /1000 *t)

角度变换也是这个道理。

位置坐标获取

如果直线长度为1000px,对应的实际里程为100米。

当跑了50米,当前就是直线的中点坐标。 弯道呢,通过弧度可以推算出坐标。 可以把 Road.ts line 70的注释取消。

js 复制代码
 // 方便开发观察 绘制车道线 ---begin----
      // this.mount(lane.centerLine.paint())
航向角

直线简单,通过Math.atan2可以求出来。 弯道需要通过解析几何,计算出圆弧切线,然后推测出航向角。

转弯

可以查看我们标注的一些点

以1到7的弯道举例,相当于是从新创建一次车道,车道的点是车道1和车道7的组合。 我们通过 circle属性配置,在创建Road

js 复制代码
{
          uid: '1-2',
          x: 1072,
          y: 1605,
          circle: {
            // 编号形式 车道序号-第几个点

            linkId: '7-3'
          }
        },

这条信息表示:车道1的第2个点(uid),有圆弧链接到车道7的第3个点(circle.linkId)

碰撞检测

我们这个项目的特点是,前端展示,实际后端返回什么数据,我们就展示什么数据。(一般不需要前端处理)。 这里我们mock的数据就简单处理一下。判断是否存在相交的线段(当前对象的位置和将要到达的点),如果线段相交,车辆暂停移动。

相关推荐
明月清风徐徐5 分钟前
Vue实训---2-路由搭建
前端·javascript·vue.js
王解13 分钟前
速度革命:esbuild如何改变前端构建游戏 (1)
前端·vite·esbuild
葡萄城技术团队21 分钟前
使用 前端技术 创建 QR 码生成器 API1
前端
DN金猿23 分钟前
Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)(很详细)
前端·vue.js·pdf
鸽鸽程序猿31 分钟前
【前端】javaScript
开发语言·前端·javascript
秦时明月之君临天下39 分钟前
React和Next.js的相关内容
前端·javascript·react.js
上官花雨1 小时前
什么是axios?怎么使用axios封装Ajax?
前端·ajax·okhttp
米奇妙妙wuu1 小时前
React中 setState 是同步的还是异步的?调和阶段 setState 干了什么?
前端·javascript·react.js
李刚大人1 小时前
react-amap海量点优化
前端·react.js·前端框架
闹闹没有闹2 小时前
socket连接封装
前端