当前位置: 首页 > news >正文

石家庄网站建设seo优化营销ps做 网站标准尺寸是多少

石家庄网站建设seo优化营销,ps做 网站标准尺寸是多少,大型行业网站,微信制作软件系列文章 canvas绘制红绿灯路口#xff08;一#xff09; 无图不欢#xff0c;先上图 优化项#xff1a; 一#xff1a;加入人行道红绿信号 二#xff1a;加入专用车道标识#xff08;无方向标识时采用专用车道标识#xff09; 三#xff1a;东南西北四项路口优化绘…系列文章 canvas绘制红绿灯路口一 无图不欢先上图 优化项 一加入人行道红绿信号 二加入专用车道标识无方向标识时采用专用车道标识 三东南西北四项路口优化绘制逻辑美化图像 四加入拖拽、缩放图例 使用方法以vue3为例 templatecanvas classlane reflaneCanvas / /templatescript setup import { ref, onMounted, onUnmounted } from vue; import Lane from services/roadCanvas/lane;const laneCanvas ref(null); /*** 车道方向进口方向* 1 - 北2 - 东北3 - 东4 - 东南* 5 - 南6 - 西南7 - 西8 - 西北** 直行放行 nThrough 0不放行 1放行* 左转放行 nTurnLeft 0不放行 1放行* 右转放行 nTurnRight 0不放行 1放行* 调头 nTurnAround 0不放行 1放行** 通道相位 nChannelNumberPhase 1-红灯 2绿灯 3黄灯*/const data [{approachDirection: 1,cdireCtion: 北,lanes: [{laneNo: 1,through: 0,turnLeft: 1,turnRight: 0,turnAround: 0,directionIdentifyings: 左转,channelNumberPhase: 2,trafficLightColor: #33CC00},{laneNo: 2,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 3,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 4,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 5,through: 0,turnLeft: 0,turnRight: 1,turnAround: 0,directionIdentifyings: 右转,channelNumberPhase: 0,trafficLightColor: #ccc}],peoples: [{laneNo: 0,lfd: 0(人行),channelNumberPhase: 1},{laneNo: 99,lfd: 99(人行),channelNumberPhase: 1}]},{approachDirection: 3,cdireCtion: 东,lanes: [{laneNo: 1,through: 0,turnLeft: 1,turnRight: 0,turnAround: 0,directionIdentifyings: 左转,channelNumberPhase: 0,trafficLightColor: #ccc},{laneNo: 2,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 3,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 4,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 5,through: 0,turnLeft: 0,turnRight: 1,turnAround: 0,directionIdentifyings: 右转,channelNumberPhase: 0,trafficLightColor: #ccc}],peoples: [{laneNo: 0,lfd: 0(人行),channelNumberPhase: 2},{laneNo: 99,lfd: 99(人行),channelNumberPhase: 1}]},{approachDirection: 5,cdireCtion: 南,lanes: [{laneNo: 1,through: 0,turnLeft: 1,turnRight: 0,turnAround: 0,directionIdentifyings: 左转,channelNumberPhase: 2,trafficLightColor: #33CC00},{laneNo: 2,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 3,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 4,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 5,through: 0,turnLeft: 0,turnRight: 1,turnAround: 0,directionIdentifyings: 右转,channelNumberPhase: 0,trafficLightColor: #ccc}],peoples: [{laneNo: 0,lfd: 0(人行),channelNumberPhase: 1},{laneNo: 99,lfd: 99(人行),channelNumberPhase: 1}]},{approachDirection: 7,cdireCtion: 西,lanes: [{laneNo: 1,through: 0,turnLeft: 1,turnRight: 0,turnAround: 0,directionIdentifyings: 左转,channelNumberPhase: 0,trafficLightColor: #ccc},{laneNo: 2,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 3,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 4,through: 1,turnLeft: 0,turnRight: 0,turnAround: 0,directionIdentifyings: 直行,channelNumberPhase: 1,trafficLightColor: #FF0033},{laneNo: 5,through: 0,turnLeft: 0,turnRight: 1,turnAround: 0,directionIdentifyings: 右转,channelNumberPhase: 0,trafficLightColor: #ccc}],peoples: [{laneNo: 0,lfd: 0(人行),channelNumberPhase: 2},{laneNo: 99,lfd: 99(人行),channelNumberPhase: 1}]} ]; let laneC null;onMounted(() {laneC new Lane({canvas: laneCanvas.value,data});// 如红绿数据更新可采用setData方法刷新红绿状态// laneC.setData(data) });onUnmounted(() {laneC?.destroy();laneC null; });/scriptstyle scoped langscss .lane {width: 100%;height: 100%;background-color: #325e76; } /stylelane.js封装如下 import { getDirectionIdentifyings, computePosition } from ./baseDI;class Lane {constructor(opt) {this.dpr window.devicePixelRatio || 1;this.canvas opt.canvas;this.w null;this.h null;this.ctx null;this.data opt.data;// 车道范围坐标this.region [];// 车道线坐标this.dataXY [];// 路中心空白区域占canvas宽高最小值的比用来计算车道宽度。占比越大中心空白区域越大车道越宽线路越短。取值范围0-1不允许取0,1。this.laneCenterProportion auto || opt.laneCenterProportion; // ex: 0.8// 车道样式this.laneStyle opt.laneStyle;// 缩放this.scaleFlag false;this.mouseScaleSpeed 5; // 缩放速度this.scaleIndex 100; // 初始缩放系数this.normalScaleIndex 100; // 标准缩放系数this.minScaleIndex 50; // 最小缩放系数this.scaleC this.scaleIndex / this.normalScaleIndex; // 缩放比例// 平移this.translate {x: 0,y: 0};// 异步任务listthis.taskList [];this.hasTaskDone false;this.status do; // do or stopthis.init();}init() {if (!this.canvas) {return;}if (this.canvas.width ! Math.floor(this.canvas.offsetWidth * this.dpr) || this.canvas.height ! Math.floor(this.canvas.offsetHeight * this.dpr)) {// eslint-disable-next-linethis.w this.canvas.width Math.floor(this.canvas.offsetWidth * this.dpr);// eslint-disable-next-linethis.h this.canvas.height Math.floor(this.canvas.offsetHeight * this.dpr);} else {this.w this.canvas.width;this.h this.canvas.height;}this.ctx this.canvas.getContext(2d);this.getLaneStyle();this.formatDataXY();this.getRegion();this.draw();this.addEvent();this.addAnimationFrame();}// 获取车道样式getLaneStyle() {const laneStyle {// 车道范围region: {width: 2 * this.dpr,color: #fff,type: solid,CurveType: quadratic, // normal: 插值曲线, quadratic: 二次贝塞尔, arc: 圆弧线。arc有问题请勿使用background: #1f2748},// 车道左侧车道线innerLeft: {width: 1 * this.dpr,color: #999,type: [10 * this.dpr, 10 * this.dpr],},// 车道右侧车道线innerRight: {width: 1 * this.dpr,color: #eee,type: [10 * this.dpr, 10 * this.dpr],},// 车道分割线innerDivider: {width: 2 * this.dpr,color: #f0bf0a,type: solid},// 车道标识direction: {widthProportion: 0.1, // 占车道比例建议小于0.2HeightWidthProportion: 10, // 高宽比建议大于5maxWidth: 20 * this.dpr,arrowWidth: 2, // 箭头/方向线的比例, 建议大于1小于2background: #ddd},// 斑马线zebraCrossing: {widthProportion: 0.05, // 单个斑马线宽占车道比例建议小于0.2widthHeightProportion: 0.2, // 单个斑马线宽高比建议小于0.5color: #ddd},// 红绿灯trafficLight: {rProportion: 0.3, // 单个红绿灯半径占车道比例建议小于0.5,colors: [#fff, #FF0033, #33CC00, #FFFF33],}};if (this.laneStyle) {this.laneStyle Object.assign(laneStyle, this.laneStyle);} else {this.laneStyle laneStyle;}const laneMaxNum this.getLaneMaxNum();const sideLength this.getSideLength();// 车道宽度 / 2 表示双向this.laneStyle.width sideLength / 2 / laneMaxNum;// 方向表示线宽高this.laneStyle.direction.width this.laneStyle.width * this.laneStyle.direction.widthProportion;if (this.laneStyle.direction.width this.laneStyle.direction.maxWidth) {this.laneStyle.direction.width this.laneStyle.direction.maxWidth;}this.laneStyle.direction.height this.laneStyle.direction.width * this.laneStyle.direction.HeightWidthProportion;// 斑马线宽高this.laneStyle.zebraCrossing.width this.laneStyle.width * this.laneStyle.zebraCrossing.widthProportion;this.laneStyle.zebraCrossing.height this.laneStyle.zebraCrossing.width / this.laneStyle.zebraCrossing.widthHeightProportion;this.laneStyle.zebraCrossing.type [this.laneStyle.zebraCrossing.width * 4, this.laneStyle.zebraCrossing.width];// 红绿灯半径this.laneStyle.trafficLight.r this.laneStyle.width * this.laneStyle.trafficLight.rProportion;}// 获取最大车道数getLaneMaxNum() {let laneMaxNum 0;this.data.forEach(item {if (item.lanes.length laneMaxNum) {laneMaxNum item.lanes.length;}});if (laneMaxNum 1) {laneMaxNum 2;}return laneMaxNum;}// 获取中心路口四边形/八边形边长getSideLength() {const minW this.w this.h ? this.h : this.w;let legitimate true;let maxLans 0;const cdireCtions [东, 南, 西, 北];for (let i 0; i this.data.length; i) {if (cdireCtions.indexOf(this.data[i].cdireCtion) -1) {legitimate false;}if (this.data[i].lanes.length maxLans) {maxLans this.data[i].lanes.length;}}if (this.laneCenterProportion auto) {this.laneCenterProportion maxLans / 10 0.8 ? 0.8 : maxLans / 10;}if (legitimate) {return minW * this.laneCenterProportion / 1.1;}return minW * this.laneCenterProportion / (Math.sqrt(2) 1);}// 计算车道坐标formatDataXY() {const dataXY [];// 车道起始中心位置const centerX this.w / 2;const centerY this.h - this.h * (1 - this.laneCenterProportion) / 2;// 车道长度const laneLength Math.sqrt(this.w ** 2 * this.h ** 2);this.data.forEach(dataItem {const dataXYItem {approachDirection: dataItem.approachDirection,};// 起始xconst startX centerX - this.laneStyle.width * dataItem.lanes.length;// 起始yconst startY centerY this.laneStyle.zebraCrossing.height * 2;// 结束Yconst endY startY laneLength;// 线const lines [];// 单向车道分割线数量const innerLines dataItem.lanes.length - 1;// 车道左边线lines.push({x0: startX,y0: startY - this.laneStyle.zebraCrossing.height * 2,x1: startX,y1: endY,type: outer});// 车道左侧分割线for (let i 0; i innerLines; i) {const x startX (i 1) * this.laneStyle.width;lines.push({x0: x,y0: startY,x1: x,y1: endY,style: { ...this.laneStyle.innerLeft }});}// 左右车道分割线const dividerX startX (innerLines 1) * this.laneStyle.width;lines.push({x0: dividerX,y0: startY,x1: dividerX,y1: endY,style: { ...this.laneStyle.innerDivider }});// 车道右侧分割线for (let i 0; i innerLines; i) {const x startX (innerLines i 2) * this.laneStyle.width;lines.push({x0: x,y0: startY,x1: x,y1: endY,style: { ...this.laneStyle.innerRight }});}// 车道右边线const outerRightx startX (innerLines 1) * 2 * this.laneStyle.width;lines.push({x0: outerRightx,y0: startY - this.laneStyle.zebraCrossing.height * 2,x1: outerRightx,y1: endY,type: outer});dataXYItem.lines lines;// 方向标识const directionIdentifyings [];for (let i 0; i dataItem.lanes.length; i) {const laneItem dataItem.lanes[i];const key [laneItem.through, laneItem.turnLeft, laneItem.turnRight, laneItem.turnAround].join();const line lines[innerLines i 1];directionIdentifyings.push(getDirectionIdentifyings(key, this.laneStyle.direction.width, this.laneStyle.direction.height, {x: line.x0 this.laneStyle.width / 2,y: line.y0 this.laneStyle.direction.height / 2 this.laneStyle.trafficLight.r * 4}, this.laneStyle.direction.arrowWidth));}dataXYItem.directionIdentifyings directionIdentifyings;// 斑马线if (dataItem.peoples.length 1) {dataXYItem.zebraCrossing [{x0: lines[0].x0 this.laneStyle.zebraCrossing.width * 4,y0: startY - this.laneStyle.zebraCrossing.height,x1: lines[lines.length - 1].x0 - this.laneStyle.zebraCrossing.width * 4,y1: startY - this.laneStyle.zebraCrossing.height,color: this.laneStyle.trafficLight.colors[dataItem.peoples[0].channelNumberPhase]}];} else if (dataItem.peoples.length 2) {dataXYItem.zebraCrossing [{x0: lines[0].x0 this.laneStyle.zebraCrossing.width * 4,y0: startY - this.laneStyle.zebraCrossing.height,x1: lines[(lines.length - 1) / 2].x0,y1: startY - this.laneStyle.zebraCrossing.height,color: this.laneStyle.trafficLight.colors[dataItem.peoples[0].channelNumberPhase]}, {x0: lines[(lines.length - 1) / 2].x0,y0: startY - this.laneStyle.zebraCrossing.height,x1: lines[lines.length - 1].x0 - this.laneStyle.zebraCrossing.width * 4,y1: startY - this.laneStyle.zebraCrossing.height,color: this.laneStyle.trafficLight.colors[dataItem.peoples[1].channelNumberPhase]}];} else {dataXYItem.zebraCrossing [{x0: lines[0].x0 this.laneStyle.zebraCrossing.width * 4,y0: startY - this.laneStyle.zebraCrossing.height,x1: lines[lines.length - 1].x0 - this.laneStyle.zebraCrossing.width * 4,y1: startY - this.laneStyle.zebraCrossing.height,color: this.laneStyle.trafficLight.colors[0]}];}// 红绿灯const trafficLights [];for (let i 0; i dataItem.lanes.length; i) {const laneItem dataItem.lanes[i];const line lines[innerLines i 1];trafficLights.push({x: line.x0 this.laneStyle.width / 2,y: line.y0 this.laneStyle.trafficLight.r * 2,r: this.laneStyle.trafficLight.r,color: this.laneStyle.trafficLight.colors[laneItem.channelNumberPhase]});}dataXYItem.trafficLights trafficLights;dataXY.push(dataXYItem);});this.dataXYByRotate(dataXY);this.dataXY dataXY;}// 计算旋转坐标dataXYByRotate(dataXY) {const centerX this.w / 2;const centerY this.h / 2;dataXY.forEach(dataXYItem {// 八边形一个边占45度const rotateReg -180 (dataXYItem.approachDirection - 1) * 45;dataXYItem.lines.forEach(line {const xy0 computePosition(line.x0, line.y0, rotateReg, centerX, centerY);line.x0 xy0.x;line.y0 xy0.y;const xy1 computePosition(line.x1, line.y1, rotateReg, centerX, centerY);line.x1 xy1.x;line.y1 xy1.y;});dataXYItem.directionIdentifyings.forEach(directionIdentifying {directionIdentifying.points.forEach(point {point.forEach(item {const { x, y } computePosition(item.x, item.y, rotateReg, centerX, centerY);item.x x;item.y y;});});directionIdentifying.arrowPoints.forEach(arrowPoint {arrowPoint.forEach(item {const { x, y } computePosition(item.x, item.y, rotateReg, centerX, centerY);item.x x;item.y y;});});});dataXYItem.zebraCrossing.forEach(zebraCrossing {const xy0 computePosition(zebraCrossing.x0, zebraCrossing.y0, rotateReg, centerX, centerY);zebraCrossing.x0 xy0.x;zebraCrossing.y0 xy0.y;const xy1 computePosition(zebraCrossing.x1, zebraCrossing.y1, rotateReg, centerX, centerY);zebraCrossing.x1 xy1.x;zebraCrossing.y1 xy1.y;});dataXYItem.trafficLights.forEach(trafficLight {const { x, y } computePosition(trafficLight.x, trafficLight.y, rotateReg, centerX, centerY);trafficLight.x x;trafficLight.y y;});});}// 获取车道范围getRegion() {const region [];for (let i 0; i this.dataXY.length; i) {const dataXYItem this.dataXY[i];const linesLength dataXYItem.lines.length;if (i ! 0) {// 衔接上一车道const prevDataXYItem this.dataXY[i - 1];const data {prevapproachDirection: prevDataXYItem.approachDirection,approachDirection: dataXYItem.approachDirection,type: connect};let diffapproachDirection dataXYItem.approachDirection - prevDataXYItem.approachDirection;if (diffapproachDirection 4) {diffapproachDirection (prevDataXYItem.approachDirection 8) - dataXYItem.approachDirection;}if (diffapproachDirection 4) {// 车道正对直线即可data.point [{ x: prevDataXYItem.lines[0].x0, y: prevDataXYItem.lines[0].y0 },{ x: dataXYItem.lines[linesLength - 1].x0, y: dataXYItem.lines[linesLength - 1].y0 },];region.push(data);} else {if (this.laneStyle.region.CurveType arc) {const angle 45 * diffapproachDirection;const startAngle 45 * (prevDataXYItem.approachDirection - 5);data.OR this.findCircleCenter(prevDataXYItem.lines[0].x0,prevDataXYItem.lines[0].y0,dataXYItem.lines[linesLength - 1].x0,dataXYItem.lines[linesLength - 1].y0,angle,true);data.OR.startAngle startAngle;data.OR.endAngle startAngle - angle;data.OR.anticlockwise true;} else {// 曲线const laneXY0 this.calculateIntersection([[prevDataXYItem.lines[0].x0, prevDataXYItem.lines[0].y0],[prevDataXYItem.lines[0].x1, prevDataXYItem.lines[0].y1],], [[dataXYItem.lines[linesLength - 1].x0, dataXYItem.lines[linesLength - 1].y0],[dataXYItem.lines[linesLength - 1].x1, dataXYItem.lines[linesLength - 1].y1],]);const laneXY1 [(prevDataXYItem.lines[0].x0 dataXYItem.lines[linesLength - 1].x0) / 2, (prevDataXYItem.lines[0].y0 dataXYItem.lines[linesLength - 1].y0) / 2];const originPoints [{ x: prevDataXYItem.lines[0].x0, y: prevDataXYItem.lines[0].y0 },{ x: laneXY1[0] - (laneXY1[0] - laneXY0[0]) * diffapproachDirection / 4, y: laneXY1[1] - (laneXY1[1] - laneXY0[1]) * diffapproachDirection / 4 },{ x: dataXYItem.lines[linesLength - 1].x0, y: dataXYItem.lines[linesLength - 1].y0 },];if (this.laneStyle.region.CurveType normal) {const point this.getCurveVertex(originPoints);data.point point;} else {data.point originPoints;}}region.push(data);}}// 车道范围region.push({approachDirection: dataXYItem.approachDirection,x0: dataXYItem.lines[linesLength - 1].x0,y0: dataXYItem.lines[linesLength - 1].y0,x1: dataXYItem.lines[linesLength - 1].x1,y1: dataXYItem.lines[linesLength - 1].y1,x2: dataXYItem.lines[0].x1,y2: dataXYItem.lines[0].y1,x3: dataXYItem.lines[0].x0,y3: dataXYItem.lines[0].y0,type: lane});if (i this.dataXY.length - 1) {// 衔接起始车道const startDataXYItem this.dataXY[0];const startLinesLength startDataXYItem.lines.length;const data {startapproachDirection: startDataXYItem.approachDirection,approachDirection: dataXYItem.approachDirection,type: connect};let diffapproachDirection startDataXYItem.approachDirection 8 - dataXYItem.approachDirection;if (diffapproachDirection 4) {diffapproachDirection dataXYItem.approachDirection - startDataXYItem.approachDirection;}if (diffapproachDirection 4) {// 车道正对直线即可data.point [{ x: dataXYItem.lines[0].x0, y: dataXYItem.lines[0].y0 },{ x: startDataXYItem.lines[startLinesLength - 1].x0, y: startDataXYItem.lines[startLinesLength - 1].y0 },];region.push(data);} else {if (this.laneStyle.region.CurveType arc) {const angle 45 * diffapproachDirection;const startAngle 45 * (dataXYItem.approachDirection - 1);data.OR this.findCircleCenter(dataXYItem.lines[0].x0,dataXYItem.lines[0].y0,startDataXYItem.lines[linesLength - 1].x0,startDataXYItem.lines[linesLength - 1].y0,angle,true);data.OR.endAngle startAngle angle;data.OR.startAngle startAngle;data.OR.anticlockwise false;} else {// 曲线const laneXY0 this.calculateIntersection([[dataXYItem.lines[0].x0, dataXYItem.lines[0].y0],[dataXYItem.lines[0].x1, dataXYItem.lines[0].y1],], [[startDataXYItem.lines[startLinesLength - 1].x0, startDataXYItem.lines[startLinesLength - 1].y0],[startDataXYItem.lines[startLinesLength - 1].x1, startDataXYItem.lines[startLinesLength - 1].y1],]);const laneXY1 [(startDataXYItem.lines[startLinesLength - 1].x0 dataXYItem.lines[0].x0) / 2, (startDataXYItem.lines[startLinesLength - 1].y0 dataXYItem.lines[0].y0) / 2];const originPoints [{ x: dataXYItem.lines[0].x0, y: dataXYItem.lines[0].y0 },{ x: laneXY1[0] - (laneXY1[0] - laneXY0[0]) * diffapproachDirection / 4, y: laneXY1[1] - (laneXY1[1] - laneXY0[1]) * diffapproachDirection / 4 },{ x: startDataXYItem.lines[startLinesLength - 1].x0, y: startDataXYItem.lines[startLinesLength - 1].y0 },];if (this.laneStyle.region.CurveType normal) {const point this.getCurveVertex(originPoints);data.point point;} else {data.point originPoints;}}region.push(data);}}}this.region region;}// 获取两条直线的交点calculateIntersection(line1, line2) {// 解方程组const x1 line1[0][0];const y1 line1[0][1];const x2 line1[1][0];const y2 line1[1][1];const x3 line2[0][0];const y3 line2[0][1];const x4 line2[1][0];const y4 line2[1][1];const denominator (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);if (denominator 0) {// 直线平行没有交点return null;}const intersectionX ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator;const intersectionY ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator;return [intersectionX, intersectionY];}// 以下四个方法获取曲线getCurveVertex(vertex, pointsPow 0.4) {let length 0;for (let i 0; i vertex.length - 1; i) {length Math.sqrt((vertex[i].x - vertex[i 1].x) ** 2 (vertex[i].y - vertex[i 1].y) ** 2);}length Math.ceil(length);return this.getNewData(vertex, length * pointsPow);}// 曲线 插值getNewData(pointsOrigin, pointsPow) {const points [];const divisions (pointsOrigin.length - 1) * pointsPow;for (let i 0; i divisions; i) {points.push(this.getPoint(i, divisions, pointsOrigin, pointsPow));}return points;}getPoint(i, divisions, pointsOrigin, pointsPow) {const isRealI (i * divisions) % pointsPow;const p ((pointsOrigin.length - 1) * i) / divisions;const intPoint Math.floor(p);const weight p - intPoint;const p0 pointsOrigin[intPoint 0 ? intPoint : intPoint - 1];const p1 pointsOrigin[intPoint];const p2 pointsOrigin[intPoint pointsOrigin.length - 2 ? pointsOrigin.length - 1 : intPoint 1];const p3 pointsOrigin[intPoint pointsOrigin.length - 3 ? pointsOrigin.length - 1 : intPoint 2];return {isReal: isRealI 0,x: this.catmullRom(weight, p0.x, p1.x, p2.x, p3.x),y: this.catmullRom(weight, p0.y, p1.y, p2.y, p3.y)};}catmullRom(t, p0, p1, p2, p3) {const v0 (p2 - p0) * 0.5;const v1 (p3 - p1) * 0.5;const t2 t * t;const t3 t * t2;return (2 * p1 - 2 * p2 v0 v1) * t3 (-3 * p1 3 * p2 - 2 * v0 - v1) * t2 v0 * t p1;}// 根据圆上两点以及夹角角度 求 圆心findCircleCenter(x1, y1, x2, y2, theta, isNeg) {let cx 0;let cy 0;const dDistance Math.sqrt((x2 - x1) * (x2 - x1) (y2 - y1) * (y2 - y1));const dRadius dDistance * 0.5 / Math.sin(Math.PI / 180 * theta * 0.5);if (dDistance 0.0) {// cout \n输入了相同的点!\n;return false;}if ((2 * dRadius) dDistance) {// cout \n两点间距离大于直径!\n;return false;}let k_verticle 0.0;let mid_x 0.0;let mid_y 0.0;let a 1.0;let b 1.0;let c 1.0;const k (y2 - y1) / (x2 - x1);let cx1; let cy1; let cx2; letcy2;if (k 0) {cx1 (x1 x2) / 2.0;cx2 (x1 x2) / 2.0;cy1 y1 Math.sqrt(dRadius * dRadius - (x1 - x2) * (x1 - x2) / 4.0);cy2 y2 - Math.sqrt(dRadius * dRadius - (x1 - x2) * (x1 - x2) / 4.0);} else {k_verticle -1.0 / k;mid_x (x1 x2) / 2.0;mid_y (y1 y2) / 2.0;a 1.0 k_verticle * k_verticle;b -2 * mid_x - k_verticle * k_verticle * (x1 x2);c mid_x * mid_x k_verticle * k_verticle * (x1 x2) * (x1 x2) / 4.0- (dRadius * dRadius - ((mid_x - x1) * (mid_x - x1) (mid_y - y1) * (mid_y - y1)));cx1 (-1.0 * b Math.sqrt(b * b - 4 * a * c)) / (2 * a);cx2 (-1.0 * b - Math.sqrt(b * b - 4 * a * c)) / (2 * a);cy1 this.y_Coordinates(mid_x, mid_y, k_verticle, cx1);cy2 this.y_Coordinates(mid_x, mid_y, k_verticle, cx2);}// cx2,cy2为顺时针圆心坐标cx1,cy1为逆时针圆心坐标if (isNeg) {cx cx1;cy cy1;} else {cx cx2;cy cy2;}return { x: cx, y: cy, r: Math.sqrt((cx - x1) ** 2 (cy - y1) ** 2) };}y_Coordinates(x, y, k, x0) {return k * x0 - k * x y;}// 设置新的红绿灯数据setData(data) {this.dataXY.forEach((dataXYItem, dataXYIndex) {dataXYItem.trafficLights.forEach((trafficLight, trafficLightIndex) {if (data[dataXYIndex]?.lanes[trafficLightIndex]) {trafficLight.color this.laneStyle.trafficLight.colors[data[dataXYIndex].lanes[trafficLightIndex].channelNumberPhase];}});dataXYItem.zebraCrossing.forEach((zebra, zebraIndex) {if (data[dataXYIndex]?.peoples[zebraIndex]) {zebra.color this.laneStyle.trafficLight.colors[data[dataXYIndex].peoples[zebraIndex].channelNumberPhase];}});});this.addTask();}// 重新绘制reDraw() {this.ctx.clearRect(0, 0, this.w, this.h);this.draw();}// 绘制draw() {this.drawRegion();this.drawLines();this.drawDirectionIdentifyings();this.drawZebraCrossing();this.drawTrafficLight();// this.drawHelper()}// 缩放、平移translateAndScale() {// 缩放this.ctx.translate(this.w / 2, this.h / 2);this.ctx.scale(this.scaleC, this.scaleC);this.ctx.translate(-this.w / 2, -this.h / 2);// 平移this.ctx.translate(this.translate.x, this.translate.y);}// 绘制车道范围drawRegion() {this.ctx.save();this.translateAndScale();this.ctx.beginPath();this.ctx.fillStyle this.laneStyle.region.background;this.ctx.lineWidth this.laneStyle.region.width;this.ctx.strokeStyle this.laneStyle.region.color;this.ctx.lineJoin round;for (let i 0; i this.region.length; i) {const regionItem this.region[i];if (regionItem.type connect) {if (regionItem?.point?.length 2 this.laneStyle.region.CurveType ! arc) {// 直线regionItem.point.forEach(item {this.ctx.lineTo(item.x, item.y);});} else if (this.laneStyle.region.CurveType arc) {// 圆if (regionItem.OR) this.ctx.arc(regionItem.OR.x, regionItem.OR.y, regionItem.OR.r, regionItem.OR.startAngle * Math.PI / 180, regionItem.OR.endAngle * Math.PI / 180, regionItem.OR.anticlockwise);} else if (this.laneStyle.region.CurveType normal) {// 插值regionItem.point.forEach(item {this.ctx.lineTo(item.x, item.y);});} else {// 二次贝塞尔this.ctx.lineTo(regionItem.point[0].x, regionItem.point[0].y);this.ctx.quadraticCurveTo(regionItem.point[1].x, regionItem.point[1].y, regionItem.point[2].x, regionItem.point[2].y);}} else {this.ctx.lineTo(regionItem.x0, regionItem.y0);this.ctx.lineTo(regionItem.x1, regionItem.y1);this.ctx.lineTo(regionItem.x2, regionItem.y2);this.ctx.lineTo(regionItem.x3, regionItem.y3);}}this.ctx.fill();this.ctx.stroke();this.ctx.closePath();this.ctx.restore();}// 绘制车道线drawLines() {this.dataXY.forEach((dataXYItem) {dataXYItem.lines.forEach(lineItem {if (lineItem.type ! outer) {this.ctx.save();this.translateAndScale();this.ctx.beginPath();this.ctx.lineWidth lineItem.style.width;this.ctx.strokeStyle lineItem.style.color;if (lineItem.style.type ! solid) {this.ctx.setLineDash(lineItem.style.type);}this.ctx.lineTo(lineItem.x0, lineItem.y0);this.ctx.lineTo(lineItem.x1, lineItem.y1);this.ctx.stroke();this.ctx.closePath();this.ctx.restore();}});});}// 绘制方向箭头drawDirectionIdentifyings() {this.dataXY.forEach((dataXYItem) {dataXYItem.directionIdentifyings.forEach(directionIdentifying {this.ctx.save();this.translateAndScale();directionIdentifying.points.forEach(pointItem {this.ctx.beginPath();this.ctx.lineWidth directionIdentifying.w;this.ctx.strokeStyle this.laneStyle.direction.background;if (directionIdentifying.exclusive) {this.ctx.setLineDash([directionIdentifying.w, directionIdentifying.w]);}pointItem.forEach(item {this.ctx.lineTo(item.x, item.y);});this.ctx.stroke();this.ctx.closePath();this.ctx.setLineDash([]);});directionIdentifying.arrowPoints.forEach(arrowPoint {this.ctx.beginPath();this.ctx.fillStyle this.laneStyle.direction.background;arrowPoint.forEach(item {this.ctx.lineTo(item.x, item.y);});this.ctx.fill();this.ctx.closePath();});this.ctx.restore();});});}// 绘制信号灯drawTrafficLight() {this.dataXY.forEach((dataXYItem) {dataXYItem.trafficLights.forEach(trafficLight {this.ctx.save();this.translateAndScale();this.ctx.beginPath();this.ctx.fillStyle trafficLight.color;this.ctx.arc(trafficLight.x, trafficLight.y, trafficLight.r, 0, Math.PI * 2);this.ctx.fill();this.ctx.closePath();this.ctx.restore();});});}// 绘制斑马线drawZebraCrossing() {this.dataXY.forEach((dataXYItem) {this.ctx.save();this.translateAndScale();this.ctx.beginPath();this.ctx.lineWidth this.laneStyle.zebraCrossing.height;dataXYItem.zebraCrossing.forEach(zebraCrossing {this.ctx.strokeStyle zebraCrossing.color;this.ctx.lineTo(zebraCrossing.x0, zebraCrossing.y0);this.ctx.lineTo(zebraCrossing.x1, zebraCrossing.y1);});this.ctx.stroke();this.ctx.closePath();this.ctx.beginPath();this.ctx.lineWidth this.laneStyle.zebraCrossing.height 1;this.ctx.strokeStyle this.laneStyle.region.background;this.ctx.setLineDash(this.laneStyle.zebraCrossing.type);dataXYItem.zebraCrossing.forEach(zebraCrossing {this.ctx.lineTo(zebraCrossing.x0, zebraCrossing.y0);this.ctx.lineTo(zebraCrossing.x1, zebraCrossing.y1);});this.ctx.stroke();this.ctx.closePath();this.ctx.restore();});}drawHelper() {// 绘制车道方向数字用来查看车道是否正确this.ctx.beginPath();this.ctx.fillStyle #fff;this.ctx.font 20 * this.dpr px Arial;for (let i 0; i this.region.length; i) {const regionItem this.region[i];this.ctx.fillText(regionItem.approachDirection, regionItem.x0, regionItem.y0);}this.ctx.closePath();// 绘制坐标线this.ctx.save();this.ctx.lineWidth 2 * this.dpr;this.ctx.strokeStyle red;this.ctx.beginPath();this.ctx.lineTo(this.w / 2, 0);this.ctx.lineTo(this.w / 2, this.h);this.ctx.stroke();this.ctx.closePath();this.ctx.beginPath();this.ctx.lineTo(0, this.h / 2);this.ctx.lineTo(this.w, this.h / 2);this.ctx.stroke();this.ctx.closePath();this.ctx.restore();}// 事件相关addEvent() {// 缩放this.mousewheelBind this.mousewheel.bind(this);this.canvas.addEventListener(mousewheel, this.mousewheelBind);// 平移this.canvasMousedownBind this.canvasMousedown.bind(this);this.documentMouseupBind this.documentMouseup.bind(this);this.documentMouseMoveBind this.documentMouseMove.bind(this);this.canvas.addEventListener(mousedown, this.canvasMousedownBind);document.addEventListener(mousemove, this.documentMouseMoveBind);}removeEvent() {if (this.mousewheelBind) {this.canvas.removeEventListener(mousewheel, this.mousewheelBind);}if (this.canvasMousedownBind) {this.canvas.removeEventListener(mousedown, this.canvasMousedownBind);}if (this.documentMouseMoveBind) {document.removeEventListener(mousemove, this.documentMouseMoveBind);}if (this.documentMouseupBind) {document.removeEventListener(mouseup, this.documentMouseupBind);}}mousewheel(e) {if (this.scaleFlag) {return;}this.scaleFlag true;if (e.wheelDelta 0) {this.scaleIndex this.mouseScaleSpeed;} else if (this.scaleIndex this.minScaleIndex) {this.scaleIndex - this.mouseScaleSpeed;}this.scaleC this.scaleIndex / this.normalScaleIndex;// canvas缩放操作this.addTask();this.scaleFlag false;}canvasMousedown(e) {this.mousedownXY {x: e.clientX,y: e.clientY};document.addEventListener(mouseup, this.documentMouseupBind);e.preventDefault();}documentMouseMove(e) {if (this.moveFlag) {return;}if (!this.mousedownXY) {return;}// 长按移动this.moveFlag true;const E {x: e.clientX,y: e.clientY};this.translate.x ((E.x - this.mousedownXY.x) * this.dpr) / this.scaleC;this.translate.y ((E.y - this.mousedownXY.y) * this.dpr) / this.scaleC;// canvas拖拽操作this.addTask();this.mousedownXY {x: e.clientX,y: e.clientY};this.moveFlag false;}documentMouseup() {document.removeEventListener(mouseup, this.documentMouseupBind);this.mousedownXY null;}// 异步处理重绘机制addAnimationFrame() {this.requestAnimationFrame null;this.requestAnimationFrameDrawBind this.requestAnimationFrameDraw.bind(this);}removeAnimationFrame() {this.stop();this.clearRequestAnimationFrame();}addTask(func () {}) {this.taskList.push(func);if (this.requestAnimationFrame null) {this.addRequestAnimationFrame();this.do();}}do() {this.status do;new Promise(res {if (this.taskList[0]) {this.taskList[0]();this.taskList.shift();}this.hasTaskDone true;res();}).then(() {if (this.status do this.taskList.length) {this.do();}});}stop() {this.status stop;}requestAnimationFrameDraw() {this.stop();if (this.hasTaskDone this.reDraw) {this.hasTaskDone false;this.reDraw();}if (this.taskList.length) {this.addRequestAnimationFrame();this.do();} else {this.clearRequestAnimationFrame();}}addRequestAnimationFrame() {this.requestAnimationFrame window.requestAnimationFrame(this.requestAnimationFrameDrawBind);}clearRequestAnimationFrame() {window.cancelAnimationFrame(this.requestAnimationFrame);this.requestAnimationFrame null;}// 销毁destroy() {this.removeEvent();this.removeAnimationFrame();} }export default Lane; baseDI.js封装如下 const getType val {return Object.prototype.toString.call(val).replace(/\[object (\w)\]/, $1); };// 旋转计算 const computePosition (x, y, angle, centerX, centerY) {// 圆心const a centerX;const b centerY;// 计算const c Math.PI / 180 * angle;const rx (x - a) * Math.cos(c) - (y - b) * Math.sin(c) a;const ry (y - b) * Math.cos(c) (x - a) * Math.sin(c) b;return { x: rx, y: ry }; };// 获取方向标识坐标 const getArrow (key, w, h, w2, h2, topY, bottomY, leftX, rightX, cX, cY) {let point [];const wd (w - w2) / 2; // 三角形边长与线宽的差值的一半const rotateDeg 30;// 左转右转旋转角度const hv h2 / Math.cos(Math.PI / 180 * rotateDeg); // 计算左转右转虚拟线长const topYv topY - (hv - h2) / 2; // 虚拟起始高度switch (key) {case 1:// 调头point [{ x: leftX - wd, y: bottomY - h },{ x: leftX w2 / 2, y: bottomY },{ x: leftX w2 wd, y: bottomY - h }];break;case 2:// 左转point [{ x: cX w / 2, y: topYv h },{ x: cX, y: topYv },{ x: cX - w / 2, y: topYv h }];point.forEach(item {const newXY computePosition(item.x, item.y, -rotateDeg, cX, cY);item.x newXY.x;item.y newXY.y;});break;case 3:// 直行point [{ x: cX w / 2, y: topY h },{ x: cX, y: topY },{ x: cX - w / 2, y: topY h }];break;case 4:// 右转point [{ x: cX w / 2, y: topYv h },{ x: cX, y: topYv },{ x: cX - w / 2, y: topYv h }];point.forEach(item {const newXY computePosition(item.x, item.y, rotateDeg, cX, cY);item.x newXY.x;item.y newXY.y;});break;default:break;}return point; }; const getDirectionIdentifyings (key, w, h, centerXY, arrowWidth) {// 标识边界const topY centerXY.y - h / 2;const bottomY centerXY.y h / 2;let leftX centerXY.x - w / 2 * 3;let rightX centerXY.x w / 2 * 3;// 直行线中心位置let cX centerXY.x w;const cY centerXY.y;// 箭头宽高const arrowW w * arrowWidth;const arrowH arrowW * Math.sin(Math.PI / 3);// 线坐标const points [];// 三角形坐标const arrowPoints [];// 专用车道没有方向标识的车道let exclusive false;switch (key) {case 0001:// 调头arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: topY w / 2 },{ x: leftX w / 2 * 5, y: topY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);break;case 0100:// 左转arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[0][0].x arrowPoints[0][2].x) / 2, y: (arrowPoints[0][0].y arrowPoints[0][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1000:// 直行leftX centerXY.x - w / 2;rightX centerXY.x w / 2;cX centerXY.x;arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);break;case 0010:// 右转cX centerXY.x - w;arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[0][0].x arrowPoints[0][2].x) / 2, y: (arrowPoints[0][0].y arrowPoints[0][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 0101:// 左转调头arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1001:// 直行调头arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);break;case 0011:// 右转调头leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);cX centerXY.x;arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1100:// 直行左转arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[0][0].x arrowPoints[0][2].x) / 2, y: (arrowPoints[0][0].y arrowPoints[0][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);break;case 0110:// 左转右转leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;cX centerXY.x;arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[0][0].x arrowPoints[0][2].x) / 2, y: (arrowPoints[0][0].y arrowPoints[0][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1010:// 直行右转cX centerXY.x - w;arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1101:// 直行左转调头arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);break;case 1011:// 直行右转调头leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;cX centerXY.x;arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[2][0].x arrowPoints[2][2].x) / 2, y: (arrowPoints[2][0].y arrowPoints[2][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 0111:// 左转右转调头leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;cX centerXY.x;arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[2][0].x arrowPoints[2][2].x) / 2, y: (arrowPoints[2][0].y arrowPoints[2][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1110:// 直行左转右转leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;cX centerXY.x;arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[0][0].x arrowPoints[0][2].x) / 2, y: (arrowPoints[0][0].y arrowPoints[0][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[2][0].x arrowPoints[2][2].x) / 2, y: (arrowPoints[2][0].y arrowPoints[2][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;case 1111:// 直行左转右转调头leftX centerXY.x - w / 2 * 5;rightX centerXY.x w / 2 * 5;cX centerXY.x;arrowPoints.push(getArrow(1, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: leftX w / 2, y: bottomY - arrowH },{ x: leftX w / 2, y: cY w / 2 },{ x: leftX w / 2 * 5, y: cY w / 2 },{ x: leftX w / 2 * 5, y: bottomY },]);arrowPoints.push(getArrow(2, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[1][0].x arrowPoints[1][2].x) / 2, y: (arrowPoints[1][0].y arrowPoints[1][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);arrowPoints.push(getArrow(4, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: (arrowPoints[3][0].x arrowPoints[3][2].x) / 2, y: (arrowPoints[3][0].y arrowPoints[3][2].y) / 2 },{ x: cX, y: cY },{ x: cX, y: bottomY }]);break;default:// 专用车道采用直行坐标exclusive true;leftX centerXY.x - w / 2;rightX centerXY.x w / 2;cX centerXY.x;arrowPoints.push(getArrow(3, arrowW, arrowH, w, h, topY, bottomY, leftX, rightX, cX, cY));points.push([{ x: cX, y: topY arrowH },{ x: cX, y: bottomY }]);break;}return { arrowPoints, points, w, exclusive }; }; const getDirectionLabel (key) {let label ;switch (key) {case 0001:// 调头label 调头;break;case 0100:// 左转label 左转;break;case 1000:// 直行label 直行;break;case 0010:// 右转label 右转;break;case 0101:// 左转调头label 左转调头;break;case 1001:// 直行调头label 直行调头;break;case 0011:// 右转调头label 右转调头;break;case 1100:// 直行左转label 直行左转;break;case 0110:// 左转右转label 左转右转;break;case 1010:// 直行右转label 直行右转;break;case 1101:// 直行左转调头label 直行左转调头;break;case 1011:// 直行右转调头label 直行右转调头;break;case 0111:// 左转右转调头label 左转右转调头;break;case 1110:// 直行左转右转label 直行左转右转;break;case 1111:// 直行左转右转调头label 直行左转右转调头;break;default:// 专用车道采用直行坐标label 专用车道;break;}return label; };// 获取人行标识坐标 const getWalkIdentifyings (w, h, boundaryW, centerXY) {// 标识边界const topY centerXY.y - h / 2;const bottomY centerXY.y h / 2;const leftX centerXY.x - w / 2;const rightX centerXY.x w / 2;const boundaryW2 boundaryW / 2;const boundaryLine [[{ x: leftX boundaryW2, y: topY },{ x: leftX boundaryW2, y: bottomY },],[{ x: rightX - boundaryW2, y: topY },{ x: rightX - boundaryW2, y: bottomY },],[{ x: leftX, y: centerXY.y },{ x: rightX, y: centerXY.y },]];const walkLine [{ x: leftX, y: centerXY.y - h / 4 },{ x: rightX, y: centerXY.y - h / 4 },];return { boundaryLine, walkLine, w: boundaryW }; };// 转换margin/padding const convertMorP (val, dpr) {let MorP [];const type getType(val);if (type Number) {MorP [val * dpr, val * dpr, val * dpr, val * dpr];} else if (type Array) {switch (val.length) {case 1:MorP [val[0] * dpr, val[0] * dpr, val[0] * dpr, val[0] * dpr];break;case 2:MorP [val[0] * dpr, val[1] * dpr, val[0] * dpr, val[1] * dpr];break;case 3:MorP [val[0] * dpr, val[1] * dpr, val[2] * dpr, val[1] * dpr];break;case 4:MorP val;break;default:MorP [0, 0, 0, 0];break;}} else {MorP [0, 0, 0, 0];}return MorP; };export { getDirectionIdentifyings, getDirectionLabel, computePosition, getWalkIdentifyings, convertMorP };
http://www.dnsts.com.cn/news/161809.html

相关文章:

  • 关于农产品电子商务网站的建设eclipse做网站
  • 做个网站出来要多少钱原创wordpress主题
  • 翡翠网站建设ppt四川做文学有关的网站
  • 网站建设品牌排行榜广州网站优化工具服务
  • Wordpress 点击量 插件青岛网站建设seo优化
  • 泉州网站建设方案外包wordpress 喜欢分享插件
  • 最新网站建设方案世界优秀网页设计赏析
  • 网站开发 发布怎么创办自己的网站
  • asp.net mvc 5 网站开发之美wordpress停用谷歌字体
  • 做营销推广外包的网站17网站一起做
  • wordpress响应式网站网站平台建设模板
  • 百度减少大量网站收录wordpress同步到报价号
  • 营销网站定制公司云之创网站建设
  • 建设银行网站登录不上青海省住房和城乡建设厅网站首页
  • 上海专业的网站建设公司北京商场哪个便宜又好
  • 重庆秀山网站建设报价wordpress 新安装 慢
  • 做架构图简单的网站mvc5网站开发项目下载
  • 长春能开发网站的公司永安网站制作
  • 咖啡店网站建设模版建立公司网站的目的
  • 阿里巴巴国际站下载淄博学校网站建设公司
  • 石家庄整站优化技术商丘58同城招聘网最新招聘
  • 网站设计背景图片怎么做的深圳办公室装修效果图
  • 江西省南昌市建筑工程网苏州seo公司 翼好
  • 东阳网站建设报价莆田网站建设建站系统
  • 网站升级改版需要几天镇江网页设计
  • php服装商城网站建设爱美刻在线制作网站
  • 湖南做网站 n磐石网络wordpress调用视频
  • 专业做网站建闵行区
  • 奉贤集团网站建设广告公司起名用字大全
  • 国外 家具 网站模板下载做资源教程网站