這是本身當時剛從後端切到前端時,實現的第一個功能,當時都沒有接觸過先後端分離的開發模式,更不知道react,抱着現學現作的態度作的.....,可能有須要的同窗,作個參考吧。css
import React, {Component} from 'react';
import {DatePicker, Input, Icon, Button, Table, Progress, Slider, notification} from 'antd';
import ol from 'openlayers';
import moment from 'moment';
import axios from 'axios';
import playback from '../../Images/playback.png';
import speedcar from '../../Images/car.png';
import move from '../../Images/move.png';
import direction from '../../Images/direction.png';
import stop from '../../Images/stop.png';
import daemarker from '../../Images/direction.png';
import './CarMove.less';
import 'openlayers/css/ol.css';
const RangePicker = DatePicker.RangePicker;
//地圖上原先的vector
let prevVector;
//肯定地圖放縮級別
let zoomSize = [100, 200, 500, 1000, 2000, 8000, 14000, 20000, 25000, 50000, 100000, 200000, 500000, 1000000, 2000000];
let zoomlevel = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3];
class CarMove extends Component {
constructor(props) {
super(props);
this.state = {
columns: [], //table的表頭信息
DAENumber: '', //默認的編號
DAEStatus: '', //默認的狀態
DEAAddress: '', //默認的地址
queryKeyWord: this.props.keyword === undefined ? '' : this.props.keyword, //用戶輸入的查詢關鍵字
pathTableData: [], //table中的數據
scrollPathTableHeight: '', //設置table出現滑動條的高度
userChooseStartTime: this.props.starttime === undefined ? '' : this.props.starttime, //用戶選擇的起始時間
userChooseEndTime: this.props.endtime === undefined ? '' : this.props.endtime, //用戶選擇的結束時間
defaultShowBtnFlag: this.props.showBtnFlag === undefined ? false : this.props.showBtnFlag, //用戶傳入是否顯示返回按鈕
defaultModeFlag: this.props.modeFlag === undefined ? false : this.props.modeFlag, //區分用戶進入方式
tableBodyData: [], //默認查詢到的數據的總條數
showAdjustSpeed: false, //默認的調節小車行駛的進度條不顯示
carProgerss: 0, //默認的小車在軌跡上行駛的進度
canRefreshAnimation: true, //默認小車的從新運動按鈕可用
mapCenterLongitude: 105.442574, //默認的地圖顯示中心的經度
mapCenterLatitude: 28.871718, //默認的地圖顯示中心的緯度
mapUrl: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'//默認的在線地圖的服務地址
}
this.map = null; //定義的地圖容器句柄
this.marker = null; //默認點擊出現彈出框
this.index = 0; //默認的小車在軌跡的位置
this.defaultCarSpeed = 12; //默認小車的行駛速度
}
//構造查詢軌跡table的頭信息
// eslint-disable-next-line react/sort-comp
generateTableHeaderData() {
const columns = [
{title: '採集時間', dataIndex: 'column0', key: '1', width: 150, align: 'center'},
{title: '採集器序列號', dataIndex: 'column1', key: '2', width: 150, align: 'center'},
{title: '位置', dataIndex: 'column2', key: '3', width: 180, align: 'center'}
];
this.setState({
columns: columns
})
}
// 輸入插敘的關鍵字
userInputKeyWord = (e) => {
this.setState({
queryKeyWord: e.target.value
})
}
//清空輸入的查詢關鍵詞
clearUserKeyWord = () => {
this.setState({
queryKeyWord: ''
})
}
//用戶選擇查詢的時間時
userChangeQueryTime = (date, dateString) => {
this.setState({
userChooseStartTime: dateString[0],
userChooseEndTime: dateString[1]
})
}
//用戶點擊查詢軌跡
getPathDatas = () => {
let mapData = [], tableData = [];
let queryKey = this.state.queryKeyWord;
//當用戶選擇的時間間隔超過三天的給出提示
let startTime = this.state.userChooseStartTime;
let endTime = this.state.userChooseEndTime;
//把時間轉化爲毫秒,計算差值
let time = new Date(endTime).getTime() - new Date(startTime).getTime();
//必填項的校驗
if (queryKey === "" || queryKey == null) {
notification.warn({
message: '輸入的車牌號或標籤號不能爲空',
description: `請從新輸入車牌號或者標籤號進行查詢`,
duration: 3,
placement: 'bottomRight'
});
return;
}
if (startTime === "" || endTime === "") {
notification.warn({
message: '請選擇查詢的時間段',
description: `查詢的時間段不能爲空,請從新選擇時間進行查詢`,
duration: 3,
placement: 'bottomRight'
});
return;
}
if (time > 259200000) {
notification.warn({
message: '時間間隔不能超過三天',
description: `查詢的時間段不能超過三天,請從新選擇時間進行查詢`,
duration: 3,
placement: 'bottomRight'
});
return;
}
//數據請求的方法
var url = "http://localhost:8080/getAllDaeInfo";
axios.get(url).then(function (response) {
console.log("response-------------->", response.data);
}).catch(function (error) {
console.log(error);
});
let enterTime, daeStatus, longitude, latitude, maxDistance = 0, distance = 0;
let carPathData = new Array();
//生成模擬數據
for (let i = 0; i < 20; i++) {
let time = Date.now() + i * 1000;
let carPathDataItem = {};
carPathDataItem.collectTime = time;
carPathDataItem.devStatus = 0;
carPathDataItem.devId = 'ts10001' + i;
carPathDataItem.devAddr = 'XX市市測試區測試街道' + i;
carPathDataItem.longitude = 107.4425790689 + Math.random() * (i + 1) / 500;
carPathDataItem.latitude = 29.8717183035 + Math.random() * (i + 1) / 500;
carPathData.push(carPathDataItem);
}
for (let i = 0; i < carPathData.length; i++) {
enterTime = moment(carPathData[i].collectTime).format("YYYY-MM-DD HH:mm:ss");
if (carPathData[i].devStatus === 0) {
daeStatus = "離線";
} else {
daeStatus = "在線";
}
//計算經緯度之間最大的距離
if (i < carPathData.length - 1) {
distance = this.getDistance(carPathData[i].latitude, carPathData[i].longitude, carPathData[i + 1].latitude, carPathData[i + 1].longitude);
if (distance > maxDistance) {
maxDistance = distance;
}
}
//表格數據的構造
tableData.push({
key: `${i}`,
column0: enterTime,
column1: carPathData[i].devId,
column2: carPathData[i].devAddr
});
longitude = carPathData[i].longitude;
latitude = carPathData[i].latitude;
//地圖數據的構造
mapData.push([longitude, latitude, carPathData[i].devId, daeStatus, carPathData[i].devAddr]);
}
if (mapData.length > 0) {
let level = 13;
//肯定地圖的放縮等級
for (let i = 0; i < zoomSize.length; i++) {
if (maxDistance > 100) {
if (maxDistance < zoomSize[i]) {
level = zoomlevel[i - 1];
break;
}
} else {
if (maxDistance === 0) {
level = 5;
break;
} else {
level = 17;
break;
}
}
}
this.setState({
tableBodyData: tableData,
canRefreshAnimation: true
})
//每次添加新的座標點時清空原先的座標點
this.map.removeLayer(prevVector);
//清空以移動的小車
this.map.un('postcompose', this.moveFeature);
//當用戶打開彈出窗口的時候,點擊查詢的狀況狀況
this.closeMapMarker();
this.map.getView().setZoom(level);
//從新設置地圖的中心(不設置的話小車移動報錯)
this.map.getView().setCenter(ol.proj.transform([mapData[0][0], mapData[0][1]], 'EPSG:4326', 'EPSG:3857'));
this.generateCarMoveOnMap(mapData);
} else {
this.setState({
tableBodyData: tableData,
carProgerss: 0,
canRefreshAnimation: false
})
//每次添加新的座標點時清空原先的座標點
this.map.removeLayer(prevVector);
//清空以移動的小車
this.map.un('postcompose', this.moveFeature);
//當用戶打開彈出窗口的時候,點擊查詢的狀況狀況
this.closeMapMarker();
//從新設置地圖的中心(不設置的話小車移動報錯)
this.map.getView().setCenter(ol.proj.transform([this.state.mapCenterLongitude, this.state.mapCenterLatitude], 'EPSG:4326', 'EPSG:3857'));
this.generateCarMoveOnMap(mapData);
notification.info({
message: '沒有查詢到軌跡信息',
description: `根據你輸入車牌號或者標籤號以及時間沒有查詢到信息`,
duration: 3
});
}
}
//計算經緯度之間的距離(單位米)
getDistance = (lat1, lng1, lat2, lng2) => {
let radLat1 = lat1 * Math.PI / 180.0;
let radLat2 = lat2 * Math.PI / 180.0;
let a = radLat1 - radLat2;
let b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * 6378.137;// EARTH_RADIUS;
s = Math.round(s * 10000) / 10;
return s;
}
componentDidMount() {
//設置表格默認滾動區域
this.setState({
scrollPathTableHeight: this.tableContrainer.clientHeight - 60
});
//監聽窗口的放縮,動態的設置table出現出現滾動的高度
window.onresize = () => {
let tableContainer = this.tableContrainer;
if (tableContainer) {
let tableHeight = tableContainer.clientHeight - 60;
this.setState({
scrollPathTableHeight: tableHeight
})
}
}
//調用構造table頭信息的函數
this.generateTableHeaderData();
//生成地圖層
let raster = new ol.layer.Tile({source: new ol.source.XYZ({url: this.state.mapUrl})});
//總地圖
this.map = new ol.Map({
target: 'pathMapContainer', layers: [raster],
view: new ol.View({
center: ol.proj.transform([this.state.mapCenterLongitude, this.state.mapCenterLatitude], 'EPSG:4326', 'EPSG:3857'),
//指定地圖投影類型
projection: 'EPSG:3857',
//定義地圖顯示的層級
zoom: 13, maxZoom: 18, minZoom: 5
})
});
//用戶打開座標顯示
this.openMapMarker(this.map);
}
//構造軌跡回放動畫
generateCarMoveOnMap = (coordinate) => {
let that = this;
//標記層
let layer = new ol.layer.Vector({
source: new ol.source.Vector()
});
let styles = {
//線路的樣式
'route': new ol.style.Style({stroke: new ol.style.Stroke({width: 5, color: "#66ACED"})}),
//起點的樣式
'start': new ol.style.Style({image: new ol.style.Icon({scale: 0.75, src: direction})}),
//起點的樣式
'end': new ol.style.Style({image: new ol.style.Icon({scale: 0.8, anchor: [0.5, 0.82], src: stop})}),
//小車的樣式
'geoMarker': new ol.style.Style({image: new ol.style.Icon({scale: 0.65, anchor: [0.5, 0.8], src: move})}),
//真實點的樣式
'point': new ol.style.Style({image: new ol.style.Icon({scale: 1, src: daemarker})})
}
let animating = false, now, speed;
let routeCoords, routeLength, geoMarker;
let startButton = document.getElementById('start-animation');
let traversed = 0; //走過的路程
let elapsedTime = 0; //用過的時間
let retime = 0; //保存上次運動所用的時間
if (coordinate.length > 2) {
let geometry = new ol.geom.LineString();
let anchor;
let minScale = 0.001;
let lngValue, latValue, times;
let lnglatArray = new Array();
//構造座標點之間的線路
for (let i = 0; i < coordinate.length; i++) {
//構造座標點的時候構造路徑
if (i > 0) {
//構造座標點之間的路徑
lngValue = coordinate[i][0] - coordinate[i - 1][0];
latValue = coordinate[i][1] - coordinate[i - 1][1];
//有一種特殊的狀況當相鄰的兩個座標點重合,或者當兩個座標點很是近的時候
let zLength = Math.sqrt(lngValue * lngValue + latValue * latValue);
if (zLength === 0 || Math.round(zLength / minScale) === 0) {
geometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
} else {
times = Math.round(zLength / minScale);
let xminScale = lngValue / times;
let yminScale = latValue / times;
for (let j = 0; j < times; j++) {
lnglatArray[0] = coordinate[i - 1][0] + j * xminScale;
lnglatArray[1] = coordinate[i - 1][1] + j * yminScale;
// eslint-disable-next-line no-use-before-define
anchor = setAnchorStyle(geometry, lnglatArray);
layer.getSource().addFeature(anchor);
}
}
}
}
//設置座標點之間連線點的座標
// eslint-disable-next-line no-inner-declarations
function setAnchorStyle(geometry, lnglatArray) {
geometry.appendCoordinate(ol.proj.transform(lnglatArray, 'EPSG:4326', 'EPSG:3857'));
let anchor = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(lnglatArray, 'EPSG:4326', 'EPSG:3857'))
});
return anchor;
}
//標記小車運動軌跡上真實的座標點
let reallyGeometry = new ol.geom.LineString();
//從第二個點到倒數第二個點
for (let i = 1; i < coordinate.length - 1; i++) {
reallyGeometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
}
let reallyCoords = reallyGeometry.getCoordinates();
let reallyPoint = new Array();
for (let i = 0; i < reallyCoords.length; i++) {
//構造小車運動的線路上真實通過的座標點
reallyPoint.push(new ol.Feature({
type: 'point', state: 0,
num: coordinate[i + 1][2],
status: coordinate[i + 1][3],
address: coordinate[i + 1][4],
geometry: new ol.geom.Point(reallyCoords[i])
}));
}
routeCoords = geometry.getCoordinates();
routeLength = routeCoords.length;
//小車行走的線路
let routeFeature = new ol.Feature({
type: 'route', state: 1,
geometry: geometry
});
//運動的小車
geoMarker = new ol.Feature({
type: 'geoMarker', state: 1,
geometry: new ol.geom.Point(routeCoords[0])
});
//軌跡開始座標
let startMarker = new ol.Feature({
type: 'start', state: 0,
num: coordinate[0][2],
status: coordinate[0][3],
address: coordinate[0][4],
geometry: new ol.geom.Point(routeCoords[0])
});
//軌跡終止座標
let endMarker = new ol.Feature({
type: 'end', state: 0,
num: coordinate[coordinate.length - 1][2],
status: coordinate[coordinate.length - 1][3],
address: coordinate[coordinate.length - 1][4],
geometry: new ol.geom.Point(routeCoords[routeLength - 1])
});
//軌跡上全部的座標的集合
let vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature, ...reallyPoint, geoMarker, startMarker, endMarker]
}),
style: function (feature) {
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
}
});
//保存上一次的layer
prevVector = vector;
//在地圖上添加座標的點集
that.map.addLayer(vector);
// eslint-disable-next-line no-use-before-define
startButton.addEventListener('click', startAnimation, false);
// eslint-disable-next-line no-use-before-define
setTimeout(() => startAnimation(), 50);
} else if (coordinate.length > 0 && coordinate.length < 3) {
//當作標點小於3個大於0個的時候
let geometry = new ol.geom.LineString();
for (let i = 0; i < coordinate.length; i++) {
geometry.appendCoordinate(ol.proj.transform([coordinate[i][0], coordinate[i][1]], 'EPSG:4326', 'EPSG:3857'));
}
routeCoords = geometry.getCoordinates();
routeLength = routeCoords.length;
//小車行走的線路
let routeFeature = new ol.Feature({
type: 'route', state: 1,
geometry: geometry
});
//運動的小車
geoMarker = new ol.Feature({
type: 'geoMarker', state: 1,
geometry: new ol.geom.Point(routeCoords[0])
});
//軌跡開始座標
let startMarker = new ol.Feature({
type: 'start', state: 0,
num: coordinate[0][2],
status: coordinate[0][3],
address: coordinate[0][4],
geometry: new ol.geom.Point(routeCoords[0])
});
//軌跡終止座標
let endMarker = new ol.Feature({
type: 'end', state: 0,
num: coordinate[coordinate.length - 1][2],
status: coordinate[coordinate.length - 1][3],
address: coordinate[coordinate.length - 1][4],
geometry: new ol.geom.Point(routeCoords[routeLength - 1])
});
//軌跡上全部的座標的集合
let vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature, geoMarker, startMarker, endMarker]
}),
style: function (feature) {
if (animating && feature.get('type') === 'geoMarker') {
return null;
}
return styles[feature.get('type')];
}
});
//保存上一次的layer
prevVector = vector;
//在地圖上添加座標的點集
that.map.addLayer(vector);
// eslint-disable-next-line no-use-before-define
startButton.addEventListener('click', startAnimation, false);
// eslint-disable-next-line no-use-before-define
setTimeout(() => startAnimation(), 50);
}
//小車運動函數
this.moveFeature = function (event) {
let vectorContext = event.vectorContext;
let frameState = event.frameState;
if (animating) {
if (retime === 0) {
elapsedTime = frameState.time - now;
} else {
elapsedTime = frameState.time - retime;
}
retime = frameState.time;
let index = Math.round(that.defaultCarSpeed * elapsedTime / 1000);
traversed += index;
that.index = traversed;
if (traversed >= routeLength) {
//當小車運動到終點的時候
// eslint-disable-next-line no-use-before-define
moveEnd(true);
return;
}
let currentPoint = new ol.geom.Point(routeCoords[traversed]);
let feature = new ol.Feature(currentPoint);
vectorContext.drawFeature(feature, styles.geoMarker);
}
//設置運動的進度條
that.setState({
carProgerss: Math.round((that.index + 1) / routeLength * 100)
})
that.map.render();
};
//開始小車的運動
function startAnimation() {
traversed = 0; //走過的路程
elapsedTime = 0; //用過的時間
retime = 0; //保存上次運動所用的時間
if (animating) {
// eslint-disable-next-line no-use-before-define
refreshAnimation();
} else {
animating = true;
now = new Date().getTime();
//speed = that.defaultCarSpeed;
geoMarker.setStyle(null);
that.map.on('postcompose', that.moveFeature);
that.map.render();
}
}
//當小車運動到終點
function moveEnd(isend) {
animating = false;
let coord = isend ? routeCoords[routeLength - 1] : routeCoords[0];
(geoMarker.getGeometry()).setCoordinates(coord);
//防止出現問題當調用次函數的時在設置一下進度條爲100%
that.setState({
carProgerss: 100
})
that.map.un('postcompose', that.moveFeature);
}
//小車從新運動
function refreshAnimation() {
if (that.state.carProgerss === 100) {
that.setState({
carProgerss: 0
})
}
animating = false;
if (that.state.canRefreshAnimation) {
startAnimation();
}
}
}
//顯示調節小車運動速度
adjustSpeed = () => {
this.setState((prevState) => ({
showAdjustSpeed: !prevState.showAdjustSpeed
}))
}
//改變小車隊的行駛速度
setNewSpeed = (value) => {
this.defaultCarSpeed = value + 4;
}
//關閉用戶打開的顯示框
closeMapMarker = () => {
this.marker.setPosition(undefined);
return false;
}
//監聽地圖的點擊事件
openMapMarker = (map) => {
let that = this;
let element = that.alertContainer;
that.marker = new ol.Overlay({
element: element,
positioning: 'bottom-center',
stopEvent: true,
offset: [-5, -24],
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(that.marker);
let dom = document.createElement('div');
dom.setAttribute('id', 'closeAlert');
that.alertContainer.appendChild(dom);
map.on('click', function (event) {
let feature = map.forEachFeatureAtPixel(event.pixel, function (feature) {
return feature;
})
if (feature) {
//點擊地圖上大的座標點的時候出現彈出框
if (feature.get("state") === 0) {
let coordinatePoint = feature.getGeometry().getCoordinates();
that.marker.setPosition(coordinatePoint);
//彈出框顯示出來
element.style.display = "block";
dom.onclick = that.closeMapMarker;
that.setState({
DAENumber: feature.get("num"),
DAEStatus: feature.get("status"),
DEAAddress: feature.get("address")
})
}
}
});
}
//返回上一級菜單
goBackUpperLevel = () => {
this.props.backPrevLavel(this.state.defaultModeFlag);
}
render() {
let {queryKeyWord} = this.state;
const suffix = queryKeyWord ? <Icon type="close-circle" onClick={this.clearUserKeyWord}/> : null;
return (
<div className="pathContainer">
<div className="headerContainer">
<Input
placeholder="請輸入車牌號進行查詢"
suffix={suffix}
onChange={this.userInputKeyWord}
value={queryKeyWord}
className="userInputKeyWord"
/>
<RangePicker
onChange={this.userChangeQueryTime}
format="YYYY-MM-DD HH:mm"
showTime
className="userSelectQueryTime"
value={this.state.userChooseStartTime ? [moment(this.state.userChooseStartTime), moment(this.state.userChooseEndTime)] : null}
/>
<Button onClick={this.getPathDatas} icon="search" className="queryButton">查詢軌跡</Button>
</div>
<div className="displayContainer">
<div className="displayLeftContainer">
<div id="pathMapContainer" className="pathMapContainer">
{this.state.defaultShowBtnFlag &&
<Button onClick={this.goBackUpperLevel} icon="left" className="goBack">返回</Button>}
<div className="alertContainer" ref={(box) => {
this.alertContainer = box
}}
><br/>
<div className="alertItem">
<span className="alertSpan">採集器編號:</span><span
className="alertSpanValue"
>{this.state.DAENumber}</span>
</div>
<div className="alertItem">
<span className="alertSpan">採集器狀態:</span><span
className="alertSpanValue"
>{this.state.DAEStatus}</span>
</div>
<div className="alertItem">
<span className="alertSpan">採集器地址:</span><span
className="alertSpanValue"
>{this.state.DEAAddress}</span>
</div>
<div className="triangleDown"></div>
</div>
<div className="adjustSpeed">
<img src={playback} className="imgSize" id="start-animation"/>
<Progress percent={this.state.carProgerss} status="active" className="progress"/>
<img src={speedcar} className="carImgSize" onClick={this.adjustSpeed}/>
{this.state.showAdjustSpeed && <div className="adjustSlider">
<Slider vertical min={1} defaultValue={this.defaultCarSpeed}
className="sliderChoose" onChange={this.setNewSpeed}
/>
</div>}
</div>
</div>
</div>
<div className="displayRightContainer">
<div className="pathTitle">
<span className="spanTitle">車輛軌跡查詢</span>
</div>
<div className="pathTable" ref={(box) => {
this.tableContrainer = box
}}
>
<Table
pagination={false}
columns={this.state.columns}
dataSource={this.state.tableBodyData}
scroll={{y: this.state.scrollPathTableHeight}}
/>
</div>
</div>
</div>
</div>
)
}
}
export default CarMove;
複製代碼
.pathContainer{
width: 100%;
height: calc(~'100% - 60px');
margin-top: 60px;
}
.headerContainer{
width: 100%;
height: 40px;
padding-top: 4px;
}
.displayContainer{
width:100%;
height: calc(~'100% - 40px');
}
.userInputKeyWord{
width: 280px;
margin-left: 10px;
}
.userSelectQueryTime{
width: 280px;
margin-left: 4px;
}
.queryButton{
margin-left: 4px;
width: 100px;
}
.displayLeftContainer{
width: calc(~'100% - 480px');
height: 100%;
float: left;
}
.displayRightContainer{
width: 480px;
height: 100%;
z-index: 1;
float: right;
background-color: rgb(236, 236, 236);
}
.pathTitle{
width: 100%;
height: 35px;
padding: 7px;
}
.spanTitle{
font-size: 14px;
color: #4291E9;
margin-left: 5px;
}
.pathTable{
width: 100%;
height: calc(~'100% - 35px');
}
.pathMapContainer{
height: 100%;
position: relative;
.ol-zoom{
left: calc(~'100% - 46px');
top: calc(~'100% - 72px');
padding: 0px;
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.15);
.ol-zoom-in{
height: 26px;
width: 26px;
background-color: rgb(255, 255, 255);
font-size: 20px;
color: rgb(150, 150, 150);
cursor: pointer;
overflow: hidden;
::selection{
color: white !important;
}
}
.ol-zoom-out{
cursor: pointer;
height: 26px;
width: 26px;
background-color: rgb(255, 255, 255);
font-size: 20px;
color: rgb(150, 150, 150);
overflow: hidden;
}
}
.ol-attribution{
display: none;
}
}
.goBack{
position: absolute;
top: 17px;
left: 35px;
z-index: 1;
color: rgb(100, 173, 255);
}
.adjustSpeed{
width: 500px;
height: 40px;
position: absolute;
z-index: 1;
bottom: 2.7%;
border-radius: 5px;
background-color: rgb(254, 254, 254);
left: 50%;
margin-left: -250px;
}
.imgSize{
width: 35px;
height: 35px;
margin-top: 4px;
margin-left: 5px;
cursor: pointer;
}
.progress{
width: 400px;
margin-left: 4px;
position: absolute;
margin-top: 11px;
}
.carImgSize{
width: 35px;
height: 35px;
position: absolute;
cursor: pointer;
margin-left: 414px;
margin-top: 2px;
}
.adjustSlider{
background-color: snow;
width: 28px;
height: 181px;
position: absolute;
margin-top: -229px;
border-radius: 6px;
margin-left: 456px;
padding-bottom: 16px;
padding-top: 5px;
}
.alertContainer{
width: 190px;
height: 120px;
background-color:white;
border-radius: 5px;
display: none;
border: 1px solid lightgrey;
-moz-user-select: text;
user-select: text;
}
#closeAlert{
position: absolute;
right: 5%;
top: 3%;
width: 15px;
height: 15px;
cursor: pointer;
background: url('../../Images/loginout.png') no-repeat ;
}
.alertItem{
width: 93.6%;
white-space: normal;
word-break: break-all;
margin-left: 8px;
}
.alertSpan{
font-family: 'Microsoft YaHei';
font-size: 12px;
color: #111111;
}
.alertSpanValue{
font-family: 'Microsoft YaHei';
font-size: 12px;
margin-left: 7px;
}
.triangleDown{
position: absolute;
width: 0;
height: 0;
border-left: 15px solid transparent ;
border-right: 15px solid transparent ;
border-top: 20px solid white;
left: 50%;
margin-left: -10px;
bottom: -13px;
}
複製代碼
效果:前端