使用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的数据就简单处理一下。判断是否存在相交的线段(当前对象的位置和将要到达的点),如果线段相交,车辆暂停移动。

相关推荐
老大白菜10 分钟前
在 Ubuntu 中使用 FastAPI 创建一个简单的 Web 应用程序
前端·ubuntu·fastapi
渔阳节度使18 分钟前
React
前端·react.js·前端框架
LCG元2 小时前
Vue.js组件开发-如何实现异步组件
前端·javascript·vue.js
Lorcian2 小时前
web前端12--表单和表格
前端·css·笔记·html5·visual studio code
问道飞鱼2 小时前
【前端知识】常用CSS样式举例
前端·css
wl85112 小时前
vue入门到实战 三
前端·javascript·vue.js
ljz20163 小时前
本地搭建deepseek-r1
前端·javascript·vue.js
爱是小小的癌3 小时前
Java-数据结构-优先级队列(堆)
java·前端·数据结构
傻小胖3 小时前
vue3中Teleport的用法以及使用场景
前端·javascript·vue.js
wl85114 小时前
Vue 入门到实战 七
前端·javascript·vue.js