cesium绘制编辑区域

 npm 安装也是可以的 

#默认安装最新的
yarn add cesium#卸载插件
yarn remove cesium#安装指定版本的
yarn add cesium@1.96.0#安装指定版本到测试环境
yarn add cesium@1.96.0 -D
yarn install @turf/turf

token记得换成您自己的!!! 

<template><div id="cesiumContainer"></div><div class="but"><div :class="btnDraw" @click="drawPlane">开始绘制</div><div :class="btnEdit" @click="echoEditing">回显编辑</div><div :class="btnCleanup" @click="clean">清除</div><div :class="btnThorough" @click="thoroughClean">彻底清除</div></div><div class="but-boxone"><button class="btn" v-for="(item,index) in dataGPSList.dataGPSListAPI" :key="index" @click="getClickLook(item)">{{item.name}}</button></div>
</template><!-- 绘制面并且编辑 --><script setup lang="ts">
import * as Cesium from "cesium";
import { onMounted, reactive, ref, computed } from "vue";
import * as turf from "@turf/turf";// 地图实例
let viewer: any;
// 存点数组,里面对象是这个{
//       lon: '',
//       lat: '',
//       hei: '',
//     };
const points: any = ref([]);
// 区域面积
const area = ref(0);
// 实体
let handler: any = null;
// 是否点击
let mouseClick = false;
// 是否移动
let mouseMove = false;
// 取消绘制
let startPicking = ref(false);
let deleteState = ref(false);
interface PositionsList {x: number;y: number;z: number;
}
// 存储绘制点
let tableDataObj = reactive({drawList: [],
});const btnDraw = computed<string>(() => {return tableDataObj.drawList.length === 0? "zoomIn animated_three": "wobble animated_eight";
});
const btnEdit = computed<string>(() => {return tableDataObj.drawList.length === 0? "fadeOut animated_two": "fadeInDown animated";
});const btnCleanup = computed<string>(() => {return tableDataObj.drawList.length === 0? "fadeOutDownBig animated_six": "fadeInUpBig animated_four";
});const btnThorough = computed<string>(() => {return tableDataObj.drawList.length === 0? "rotateOut animated_seven": "rotateIn animated_five";
});onMounted(() => {// 初始化Cesium并创建viewerCesium.Ion.defaultAccessToken ="换成你自己的token!!!";viewer = new Cesium.Viewer("cesiumContainer", {infoBox: false, // 禁用沙箱,解决控制台报错selectionIndicator: false, //选择指示器timeline: false, // 时间轴animation: false, // 动画小组件geocoder: false, // 地理编码(搜索)组件homeButton: false, // 首页,点击之后将视图跳转到默认视角sceneModePicker: false, // 投影方式,切换2D、3D 和 Columbus View (CV) 模式。baseLayerPicker: false, // 底图组件,选择三维数字地球的底图(imagery and terrain)。navigationHelpButton: false, // 帮助按钮fullscreenButton: false, // 全屏按钮// vrButton: false, // VR模式// shouldAnimate: true, // 自动播放动画控件// shadows: true, // 是否显示光照投射的阴影// terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY, // 地质接收阴影`// imageryProvider: esri, //自定义图层,默认是谷歌的影响图层scene3DOnly: true, // 每个几何实例将只能以3D渲染以节省GPU内存sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode});viewer._cesiumWidget._creditContainer.style.display = "none"; //隐藏logo版权let destination = Cesium.Cartesian3.fromDegrees(116.3974, 39.9087, 10000); // 北京天安门广场的经纬度坐标及高度pointerdefault();viewer.camera.flyTo({destination: destination,duration: 2, // 飞行动画持续时间(单位:秒)});
});//开始绘制
const drawPlane = () => {// viewer.entities.removeAll()if (handler != null) {console.log("绘制");clean();}points.value = [];startPicking.value = false;// 点位存储let positions: any = [];area.value = 0;let polygon = new Cesium.PolygonHierarchy();let dynamicPolygon: any = new Cesium.Entity();let polyObj: any = null;let polyId = "planBy" + buildUUID();handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction((movement: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {let pick: any = pickEllisoidPosition(viewer, movement.position);mouseClick = true;if (Cesium.defined(pick) &&Cesium.defined(pick.cartesian) &&pick.cartesian.x) {positions.push(pick.cartesian.clone());polygon.positions.push(pick.cartesian.clone());if (!polyObj) {dynamicPolygon = {id: polyId,polyline: {width: 7,// ...lineStyle,material: new Cesium.PolylineOutlineMaterialProperty({color: Cesium.Color.AQUA.withAlpha(0.7), // 线的颜色outlineWidth: 4,outlineColor: Cesium.Color.WHITE.withAlpha(0.6),}),show: true,clampToGround: true,positions: new Cesium.CallbackProperty(function () {return positions;}, false),},polygon: {hierarchy: new Cesium.CallbackProperty(function () {return polygon;}, false),// 绘制区域颜色material: Cesium.Color.STEELBLUE.withAlpha(0.4),clampToGround: true,},};polyObj = viewer.entities.add(dynamicPolygon);}let ray = viewer.camera.getPickRay(movement.position);let cartesian = viewer.scene.globe.pick(ray, viewer.scene);let cartographic = Cesium.Cartographic.fromCartesian(cartesian);let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度viewer.entities.add({id: "editPoint" + buildUUID(),name: "点",point: {pixelSize: 15,color: Cesium.Color.WHITE,// ...lineStyle,show: true,clampToGround: true,// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND},distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0,3000), // 可视范围position: Cesium.Cartesian3.fromDegrees(lng, lat, 0),});}},Cesium.ScreenSpaceEventType.LEFT_CLICK);handler.setInputAction((movement: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {if (mouseClick) {let pick: any = pickEllisoidPosition(viewer, movement?.endPosition);if (positions.length >= 0 && Cesium.defined(pick)) {if (mouseMove) {positions.pop();polygon.positions.pop();}if (pick.cartesian && pick.cartesian.x) {positions.push(pick.cartesian);polygon.positions.push(pick.cartesian);mouseMove = true;}}}},Cesium.ScreenSpaceEventType.MOUSE_MOVE);handler.setInputAction((movement) => {if (mouseClick && mouseMove) {positions.pop();polygon.positions.pop();}if (positions.length < 3) {alert("必须绘制三个点以上,请重新绘制");// 再次开启drawPlane();return;}// 计算面积getCalculateArea(positions);positions.push(positions[0]);mouseMove = false;mouseClick = false;points.value = [];for (let i = 0; i < positions.length; i++) {const tmp = cartesian3ToGps(viewer, positions[i]);const tmpPoint: object = {lon: tmp[0],lat: tmp[1],hei: tmp[2],};points.value.push(tmpPoint);}const arr = points.value.map((item) => [item.lon, item.lat]);area.value = turf.area(turf.polygon([arr])).toFixed(2) as any;// let pick =  viewer.scene.pick(movement.position);// console.log("右键:")pickClear(polyObj);// 停止绘制stopDraw();handlePolyClick();// 右键删除handlePolyRightClick();}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};// 计算面积
function getCalculateArea(positions: PositionsList) {tableDataObj.drawList = positions as any;console.log("cesium坐标:", tableDataObj.drawList.length);var areaCenter = getAreaAndCenter(positions);var calculatearea = areaCenter.area;var center = areaCenter.center;var text = formateArea(calculatearea, "m");// console.log("calculatearea面积:",calculatearea)// console.log("text面积",text)let labelId = viewer.entities.add({id: "label_" + buildUUID(),position: center,label: {text: "面积:" + text,// 字体大小font: "18px sans-serif",// FILL填充/OUTLINE描边/FILL_AND_OUTLINED填充描边style: Cesium.LabelStyle.FILL_AND_OUTLINE,// 描边颜色outlineColor: Cesium.Color.WHITE,// 描边宽度outlineWidth: 5,// 字体颜色fillColor: Cesium.Color.BLUE,},});
}// 添加小手
function pointerdefault() {// 添加小手viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) {const pickedObject = viewer.scene.pick(movement.endPosition);if (pickedObject && pickedObject.id) {viewer.container.style.cursor = "pointer";} else {viewer.container.style.cursor = "default";}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}// 创建完面之后监听事件
const handlePolyClick = () => {handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);let pickData: any;handler.setInputAction((event: any) => {let windowPosition = event.position;// 通过屏幕坐标获取当前位置的实体信息let pickedObject = viewer.scene.pick(windowPosition);if (Cesium.defined(pickedObject)) {if (/planBy/.test(pickedObject.id._id)) {if (pickData && pickData._id == pickedObject._id) {return;}pickData = pickedObject.id; //获取编辑的事件editPlane(pickData, handler);}} else {if (!pickData) {return;}pickClear(pickData);pickData = undefined;}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
};// 右键删除
const handlePolyRightClick = () => {console.log("触发了么");// handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);handler.setInputAction((event: any) => {let windowPosition = event.position;// 通过屏幕坐标获取当前位置的实体信息let pickedObject = viewer.scene.pick(windowPosition);let pick = viewer.scene.pick(event.position);// 通过屏幕坐标获取当前位置的实体信息let pickData: any;if (Cesium.defined(pickedObject)) {pickData = pickedObject.id; //获取编辑的事件pickClear(pickData);pickData = undefined;if (!deleteState.value) {//右键删除createDelteDom(event.position, pick.id.id);} else {return;}}}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};// 删除
function createDelteDom(px, objId) {deleteState.value = true;if (!objId) return;let deleteDom = window.document.createElement("span");deleteDom.style.background = "red";deleteDom.style.position = "absolute";deleteDom.style.color = "white";deleteDom.style.left = px.x + 10 + "px";deleteDom.style.top = px.y + 10 + "px";deleteDom.style.padding = "6px";deleteDom.style.borderRadius = "6px";deleteDom.style.cursor = "pointer";deleteDom.id = "easy3d-plot-delete";deleteDom.setAttribute("objId", objId);deleteDom.innerHTML = `删除`;let mapDom = window.document.getElementById(viewer.container.id);mapDom.appendChild(deleteDom);const clsBtn = window.document.getElementById("easy3d-plot-delete");if (!clsBtn) return;clsBtn.addEventListener("click", (e) => {let id = deleteDom.getAttribute("objId");removeByObjId(id);});document.addEventListener("click", function () {clsBtn.remove();deleteState.value = false;});
}
/*** 根据id移除创建的对象* @param {String | Number} id 对象id*/
function removeByObjId(id) {console.log("查看写ID", id);if (!id) return;let entity = viewer.entities.getById(id);if (entity) {viewer.entities.remove(entity);}// 删除面积labellet label_id = viewer.entities.values[0].id;var reg = new RegExp("label_");if (reg.test(label_id)) {viewer.entities.removeById(label_id);}
}// 创建完面之后编辑事件
const editPlane = (pick: any, handler: any) => {console.log("编辑editPlane");if (!pick) {return;}// const view = viewer.entities.getById(polyId)pick.polyline.width = 7;pick.polyline.material.outlineWidth = 4;pick.polyline.material.outlineColor = Cesium.Color.WHITE.withAlpha(0.6);removeEntities(viewer, {filterType: "id",filterReg: /(editPoint)|labelPoy_/,});let pointId: any = [];let downStatus = false;let currentPoint: any; //当前编辑点console.log(pick.polygon.hierarchy.getValue(), "pick.polygon.hierarchy");let positions = pick.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;console.log("positions", positions, positions.length);// 生成编辑点for (let i = 0; i < positions.length; i++) {let ID = "editPoint" + buildUUID();let point = viewer.entities.add({id: ID,position: positions[i],vertexIndex: i,point: {pixelSize: 15,color: Cesium.Color.WHITE,// ...lineStyle,show: true,clampToGround: true,// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND},distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 3000), // 可视范围});// 保存点的ID以便删除pointId.push(ID);}const resp = positions.map((item) => {let cartographic = Cesium.Cartographic.fromCartesian(item);let longitude = Cesium.Math.toDegrees(cartographic.longitude);let latitude = Cesium.Math.toDegrees(cartographic.latitude);return {longitude: longitude,latitude: latitude,height: cartographic.height,};});resp.push(resp[0]);resp.forEach((item, index) => {if (resp[index + 1]?.longitude) {let longitude = (+item.longitude + +resp[index + 1].longitude) / 2;let latitude = (+item.latitude + +resp[index + 1].latitude) / 2;let height = (+item.height + +resp[index + 1].height) / 2;let position = [+longitude, +latitude, +height];let text = distanceApi(item, resp[index + 1]).toFixed(1) + "m";labelApis(`labelPoy_${buildUUID()}`, position, text);}});handler.setInputAction((event) => {// 获取屏幕坐标let windowPosition = event.position;// 通过屏幕坐标获取当前位置的实体信息let pickedObject = viewer.scene.pick(windowPosition);if (Cesium.defined(pickedObject)) {if (/editPoint/.test(pickedObject.id._id)) {downStatus = true;viewer.scene.screenSpaceCameraController.enableRotate = false;viewer.scene.screenSpaceCameraController.enableZoom = false;currentPoint = pickedObject.id;console.log(currentPoint);} else {viewer.scene.screenSpaceCameraController.enableRotate = true;viewer.scene.screenSpaceCameraController.enableZoom = true;return false;}} else {viewer.scene.screenSpaceCameraController.enableRotate = true;viewer.scene.screenSpaceCameraController.enableZoom = true;return false;}}, Cesium.ScreenSpaceEventType.LEFT_DOWN);handler.setInputAction((event) => {if (!downStatus) {return;}removeEntities(viewer, {filterType: "id",filterReg: /labelPoy_|label_/,});let windowPosition = event.startPosition;// 将屏幕坐标转为笛卡尔坐标let ellipsoid = viewer.scene.globe.ellipsoid;let cartesian = viewer.camera.pickEllipsoid(windowPosition, ellipsoid);// 如果点击到地球外,那么返回if (!cartesian) {return;}// 更新编辑点的位置// console.log(currentPoint, cartesian);currentPoint.position._value = cartesian;let point: any = []; // 线的定位let polyData: any = [];for (let id of pointId) {// console.log(viewer.entities.getById(id), "0");point.push(viewer.entities.getById(id).position._value);polyData.push(viewer.entities.getById(id).position._value);}// const data = viewer.entities.getById(polyId)positions = point;point.push({ x: point[0]["x"], y: point[0]["y"], z: point[0]["z"] });const resp = point.map((item) => {let cartographic = Cesium.Cartographic.fromCartesian(item);let longitude = Cesium.Math.toDegrees(cartographic.longitude);let latitude = Cesium.Math.toDegrees(cartographic.latitude);return {lon: longitude,lat: latitude,height: cartographic.height,};});points.value = resp;const resps = points.value.map((item) => {return {longitude: item.lon,latitude: item.lat,height: item.height,};});// resp.push(resp[0])resps.forEach((item, index) => {if (resps[index + 1]?.longitude) {let longitude = (+item.longitude + +resps[index + 1].longitude) / 2;let latitude = (+item.latitude + +resps[index + 1].latitude) / 2;let height = (+item.height + +resps[index + 1].height) / 2;let position = [+longitude, +latitude, +height];let text = distanceApi(item, resps[index + 1]).toFixed(1) + "m";labelApis(`labelPoy_${buildUUID()}`, position, text);}});pick.polyline.positions = point;pick.polygon.hierarchy = polyData;}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);handler.setInputAction(() => {if (!downStatus) {return;}// removeEntities(viewer, {//   filterType: "id",//   filterReg: /label_/,// });console.log(points.value, "value");console.log("positions", positions);// 重新计算面积getCalculateArea(positions);viewer.scene.screenSpaceCameraController.enableRotate = true;viewer.scene.screenSpaceCameraController.enableZoom = true;downStatus = false;currentPoint = undefined;}, Cesium.ScreenSpaceEventType.LEFT_UP);// }
};
const pickClear = (pickData: any) => {pickData.polyline.width = 5;pickData.polyline.material.outlineWidth = 2;pickData.polyline.material.outlineColor = Cesium.Color.WHITE.withAlpha(0.4);removeEntities(viewer, {filterType: "id",filterReg: /(editPoint)|labelPoy_/,});
};
//结束绘制
const stopDraw = () => {if (handler) {handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);handler?.destroy();startPicking.value = true;handler = null;}
};
// 随机数字
const buildUUID = () => {const hexList: string[] = [];for (let i = 0; i <= 15; i++) {hexList[i] = i.toString(16);}let uuid = "";for (let i = 1; i <= 36; i++) {if (i === 9 || i === 14 || i === 19 || i === 24) {uuid += "-";} else if (i === 15) {uuid += 4;} else if (i === 20) {uuid += hexList[(Math.random() * 4) | 8];} else {uuid += hexList[(Math.random() * 16) | 0];}}return uuid.replace(/-/g, "");
};
/*** @description: cesium获取两点之间距离 (m)* @param {*} root 当前组件的根实例* @param {*} point1 坐标1* @param {*} point2  坐标2* @return {*} 距离*/
const distanceApi = (position1: any, position2: any) => {let cartesian1 = Cesium.Cartesian3.fromDegrees(position1.longitude,position1.latitude,position1.height);let cartesian2 = Cesium.Cartesian3.fromDegrees(position2.longitude,position2.latitude,position2.height);var point1cartographic = Cesium.Cartographic.fromCartesian(cartesian1);var point2cartographic = Cesium.Cartographic.fromCartesian(cartesian2);/**根据经纬度计算出距离**/var geodesic = new Cesium.EllipsoidGeodesic();geodesic.setEndPoints(point1cartographic, point2cartographic);var distance = geodesic.surfaceDistance;//返回两点之间的距离return (distance = Math.sqrt(Math.pow(distance, 2) +Math.pow(point2cartographic.height - point1cartographic.height, 2)));
};
/*** 删除地图上的实体* @param viewer* @param option*/
const removeEntities = (viewer: Cesium.Viewer, option: any) => {if (!viewer) {return;}const removedId: string[] = [];viewer.entities.values.map((item) => {if (option.filterType == "id") {if (option.filterReg.test(item.id)) {removedId.push(item.id);}}});removedId.sort(function (a, b) {return b.indexOf("measureLineXL") !== -1 ? 1 : -1;});removedId.map(function (item) {viewer.entities.removeById(item);});
};
/*** cartesian3转gps* @param viewer* @param cartesian* @returns*/
const cartesian3ToGps = (viewer: Cesium.Viewer,cartesian: Cesium.Cartesian3
): number[] => {const cartographic =viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);return [Cesium.Math.toDegrees(cartographic.longitude),Cesium.Math.toDegrees(cartographic.latitude),cartographic.height,];
};
/*** 拾取球面坐标* @param viewer  场景视图* @param position 屏幕坐标* @returns array 地理坐标数组*/
const pickEllisoidPosition = (viewer: Cesium.Viewer,position: Cesium.Cartesian2
) => {const pickRay = viewer.scene.camera.getPickRay(position);if (pickRay) {const cartesian = viewer.scene.globe.pick(pickRay, viewer.scene);if (cartesian) {const cartographic = Cesium.Cartographic.fromCartesian(cartesian);const result = {geoPositon: [Cesium.Math.toDegrees(cartographic.longitude),Cesium.Math.toDegrees(cartographic.latitude),cartographic.height,],cartesian: cartesian,};return result;}}
};const labelApis = (id, position, text) => {viewer.entities.add({id: id,name: "labelApi",position: Cesium.Cartesian3.fromDegrees(...position),label: {text: text,showBackground: true, //显示背景backgroundColor: new Cesium.Color.fromCssColorString("rgba(0,0,0,0.7)"),horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //对齐方式font: "16px sans-serif",fillColor: Cesium.Color.MIDNIGHTBLUE,outlineColor: Cesium.Color.WHITE,style: Cesium.LabelStyle.FILL_AND_OUTLINE,outlineWidth: 4,pixelOffset: new Cesium.Cartesian2(0, -10), // 视角偏移verticalOrigin: Cesium.VerticalOrigin.BOTTOM,distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 400000), // 可视范围eyeOffset: new Cesium.Cartesian3(0, 0, -30),},});
};const clean = () => {removeEntities(viewer, {filterType: "id",filterReg: /(editPoint)|planBy|labelPoy_|label_/,});// 停止绘制stopDraw();// console.log(handler, "handler");
};
// 彻底清除
function thoroughClean() {tableDataObj.drawList = [];clean();
}
const echoEditing = () => {//   let square=ref()// console.log("square",square)clean();let polyObj: any = null;let polyId = "planBy" + buildUUID();// 点位存储let polygon = new Cesium.PolygonHierarchy();let dynamicPolygon: any = new Cesium.Entity();let pointData: any = [];pointData = tableDataObj.drawList;let points: any = [];// console.log("drawList",tableDataObj.drawList)// console.log("pointData",pointData)if (pointData.length == 0) {alert("没有点位数据,无法回显!!!");return;}for (let i = 0; i < pointData.length; i++) {const tmp = cartesian3ToGps(viewer, pointData[i]);points.push(tmp[0], tmp[1], tmp[2]);}// console.log(points, "lll");if (!polyObj) {dynamicPolygon = {id: polyId,polyline: {width: 7,// ...lineStyle,material: new Cesium.PolylineOutlineMaterialProperty({color: Cesium.Color.AQUA.withAlpha(0.7), // 线的颜色outlineWidth: 4,outlineColor: Cesium.Color.WHITE.withAlpha(0.6),}),show: true,clampToGround: true,positions: Cesium.Cartesian3.fromDegreesArrayHeights(points),},polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(points),material: Cesium.Color.STEELBLUE.withAlpha(0.4),clampToGround: true,},};polyObj = viewer.entities.add(dynamicPolygon);handlePolyClick();// 计算面积getCalculateArea(pointData);// 右键删除handlePolyRightClick();}
};//调用第三方插件计算面积 turf
function getAreaAndCenter(positions: any) {if (!positions || positions.length < 1) return;var cartographics = [];var turfPoints = [];for (var i = 0; i < positions.length; i++) {var cartesian3 = positions[i];var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);cartographics.push([Cesium.Math.toDegrees(cartographic.longitude),Cesium.Math.toDegrees(cartographic.latitude),]);turfPoints.push(turf.point([Cesium.Math.toDegrees(cartographic.longitude),Cesium.Math.toDegrees(cartographic.latitude),]));}if (!cartographics.length) return;cartographics = cartographics.concat([cartographics[0]]);var polygon = turf.polygon([cartographics]);var area = turf.area(polygon);//获取当前范围的中心点var features = turf.featureCollection(turfPoints);var turfCenter = turf.center(features);var center = turfCenter.geometry.coordinates;return {area: area,center: Cesium.Cartesian3.fromDegrees(center[0], center[1]),};
}
function formateArea(val: any, dw: string) {if (val == undefined) return;let dwStr = "";dw = dw || "m";if (dw == "km" || dw == "平方千米") {dwStr += (Number(val) / 1000000).toFixed(2) + "km²";} else if (dw == "m" || dw == "平方米") {dwStr += Number(val).toFixed(2) + "m²";} else {}return dwStr;
}
onMounted(() => {// 本地假数据getLooklook();// 假数据// falseDataLook()
});
// 背地造的数据
let dataGPSList =reactive({dataGPSListAPI:[{id: 1,name:"测试数据1",dataval: {startList: {Lon: 115.9931488639,Lat: 39.0063934815,},endList: {Lon: 115.99045942,Lat: 39.0063929,},carryoutList: [{Lon: 115.99299873,Lat: 39.006393800000005,},{Lon: 115.992,Lat: 39.0063932,},{Lon: 115.9916123,Lat: 39.0063931,},],},},{id: 2,name:"测试数据2",dataval: {startList: {Lon: 115.99045942,Lat: 39.0063929,},endList: {Lon: 115.9884542,Lat: 39.0063931,},carryoutList: [{Lon: 115.9898,Lat: 39.0063938005,},{Lon: 115.9894,Lat: 39.0063932,},{Lon: 115.9889542,Lat: 39.0063931,},],},},]
});
function getClickLook(itemval?:any){let destination = Cesium.Cartesian3.fromDegrees(itemval.dataval.endList.Lon,itemval.dataval.endList.Lat,1000); // 设置目标位置// 设置相机位置viewer.camera.flyTo({destination: destination,duration: 2, // 飞行动画持续时间(单位:秒)});
}
// 查看
function getLooklook() {let destination = Cesium.Cartesian3.fromDegrees(dataGPSList.dataGPSListAPI[0].dataval.startList.Lon,dataGPSList.dataGPSListAPI[0].dataval.startList.Lat,1000); // 设置目标位置// 设置相机位置viewer.camera.flyTo({destination: destination,duration: 2, // 飞行动画持续时间(单位:秒)});// const point2 = viewer.entities.add({//   id: "point",//   position: Cesium.Cartesian3.fromDegrees( 115.9898, 39.0063931),//   point: {//     pixelSize: 20, //像素大小//     color: Cesium.Color.RED,//     outlineColor: Cesium.Color.WHITE,//     // outlineWidth: 20,//     heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,//   },// });dataGPSList.dataGPSListAPI.map((item:any)=>{let   itemdata=item.datavallet   endListData=itemdata.endListlet   carryoutListData=itemdata.carryoutListlet   startListData=itemdata.startListlet   carryoutListLengthMinusone=carryoutListData[carryoutListData.length-1]// 总长度const totalData = getFlatternDistance(startListData.Lat, startListData.Lon, endListData.Lat, endListData.Lon);// 【面】// 未完成funPolygon(buildUUID(), "#e90707", [endListData.Lat, endListData.Lon, carryoutListData[carryoutListData.length - 1].Lat, carryoutListData[carryoutListData.length - 1].Lon]);// 完成第一阶段(最右边开始)funPolygon(buildUUID(), "#00D764", [carryoutListData[0].Lat, carryoutListData[0].Lon,startListData.Lat, startListData.Lon]);//已完成中间段(去除第一阶段)  for(let i=0;i<carryoutListData.length-1;i++){funPolygon(buildUUID(), "#00D764", [ carryoutListData[i+1].Lat, carryoutListData[i+1].Lon,carryoutListData[i].Lat, carryoutListData[i].Lon]);// 【竖线下#fff】funLine(buildUUID(), "#fff", [carryoutListData[i].Lon,carryoutListData[i].Lat]);// 【箭头百分比】//中间已完成let yesData = getFlatternDistance(carryoutListData[i].Lat, carryoutListData[i].Lon,carryoutListData[i+1].Lat, carryoutListData[i+1].Lon);//中间已完成 百分比let yesPercent=((yesData / totalData) * 100).toFixed(2);// 中间已完成funArrowLin(buildUUID(), "#33CC00", [carryoutListData[i].Lon, carryoutListData[i].Lat,carryoutListData[i+1].Lon,carryoutListData[i+1].Lat], yesPercent);}// 【竖线-下】// 最右边的竖线funLine(buildUUID(), "#fff", [endListData.Lon,endListData.Lat])// 最左边的竖线funLine(buildUUID(), "#fff", [startListData.Lon,startListData.Lat]);// 为了不多写一个循环加上(靠右的第二个竖线) 【竖线下#fff】funLine(buildUUID(), "#fff", [carryoutListLengthMinusone.Lon,carryoutListLengthMinusone.Lat]);// // 竖线循环 多一个循环 若使用次循环则注释掉【竖线下#fff】// for(let i=0;i<carryoutListData.length;i++){//   funLine(buildUUID(), "#fff", [carryoutListData[i].Lon,carryoutListData[i].Lat]);// }// 【竖线-上】funLine(buildUUID(), "#33FFFF", [startListData.Lon, startListData.Lat], true);funLine(buildUUID(), "#33FFFF", [carryoutListLengthMinusone.Lon, carryoutListLengthMinusone.Lat], true);// 【箭头百分比】// // 总长度// const totalData = getFlatternDistance(startListData.Lat, startListData.Lon, endListData.Lat, endListData.Lon);// 未完成const notData = getFlatternDistance(endListData.Lat, endListData.Lon, carryoutListLengthMinusone.Lat, carryoutListLengthMinusone.Lon);// 未完成百分比const notPercent = ((notData / totalData) * 100).toFixed(2);// 未完成funArrowLin(buildUUID(), "#FF0033", [carryoutListLengthMinusone.Lon, carryoutListLengthMinusone.Lat,endListData.Lon, endListData.Lat], notPercent);// 第一阶段已完成const alreadyData = getFlatternDistance(startListData.Lat, startListData.Lon, carryoutListData[0].Lat, carryoutListData[0].Lon);// 第一阶段已完成const alreadyPercent = ((alreadyData / totalData) * 100).toFixed(2);funArrowLin(buildUUID(), "#33CC00", [startListData.Lon,startListData.Lat, carryoutListData[0].Lon, carryoutListData[0].Lat], alreadyPercent);//已完成所有【上】 funArrowLin(buildUUID(),"#33FF00",[startListData.Lon,startListData.Lat,carryoutListLengthMinusone.Lon,carryoutListLengthMinusone.Lat],(100 - Number(notPercent)).toString(),true);
})}
function falseDataLook(){let nowLat = 39.0063934815; // 最右边let nowLon = 115.9931488639;let startLat = 39.0063929; //最左边let startLon = 115.99045942;let endLat = 39.006393800000005; //右1let endLon = 115.99299873;let endLat1 = 39.0063932;let endLon1 = 115.992;let endLat2 = 39.0063931;let endLon2 = 115.9916123;let destination = Cesium.Cartesian3.fromDegrees(115.9931488639,39.0063934815,1000); // 设置目标位置// 设置相机位置viewer.camera.flyTo({destination: destination,duration: 2, // 飞行动画持续时间(单位:秒)});// 面const arrone = [startLat, startLon, endLat2, endLon2];const arrtwo = [endLat, endLon, nowLat, nowLon];funPolygon(buildUUID(), "#e90707", arrone);funPolygon(buildUUID(), "#00D764", arrtwo);funPolygon(buildUUID(), "#00D764", [endLat1, endLon1, nowLat, nowLon]);funPolygon(buildUUID(), "#00D764", [endLat2, endLon2, endLat1, endLon1]);// 线const arrthtee = [startLon, startLat];const arrfour = [endLon, endLat];const arrfive = [nowLon, nowLat];funLine(buildUUID(), "#fff", arrthtee);funLine(buildUUID(), "#fff", arrfour);funLine(buildUUID(), "#fff", arrfive);funLine(buildUUID(), "#fff", [endLon1, endLat1]);// //总长度const totalData = getFlatternDistance(nowLat, nowLon, startLat, startLon);// 已const alreadyData = getFlatternDistance(nowLat, nowLon, endLat, endLon);const alreadyData1 = getFlatternDistance(endLat1, endLon1, endLat, endLon);const alreadyData2 = getFlatternDistance(endLat1, endLon1,endLat2, endLon2);// 未const notData = getFlatternDistance(startLat, startLon, endLat2, endLon2);// 计算百分比const alreadyPercent = ((alreadyData / totalData) * 100).toFixed(2);// 显示百分比const notPercent = ((notData / totalData) * 100).toFixed(2);const alreadyPercent1 = ((alreadyData1 / totalData) * 100).toFixed(2);const alreadyPercent2 = ((alreadyData2 / totalData) * 100).toFixed(2);// 第一阶段已完成let arrowLinyes = [nowLon, nowLat, endLon, endLat];funArrowLin(buildUUID(), "#33CC00", arrowLinyes, alreadyPercent);// 第二阶段已完成let arrowLinyes1 = [endLon, endLat, endLon1, endLat1];funArrowLin(buildUUID(), "#00CC00", arrowLinyes1, alreadyPercent1);let arrowLinyes2 = [endLon1, endLat1,endLon2, endLat2];funArrowLin(buildUUID(), "#00CC00", arrowLinyes2, alreadyPercent2);// 未完成let arrowLinnot = [endLon1, endLat1, startLon, startLat];funArrowLin(buildUUID(), "#FF0033", arrowLinnot, notPercent);funLine(buildUUID(), "#33FFFF", [nowLon, nowLat], true);funLine(buildUUID(), "#33FFFF", [endLon2, endLat2], true);let arrowLinyesall = [nowLon, nowLat, endLon2, endLat2];console.log(notPercent);funArrowLin(buildUUID(),"#33FF00",arrowLinyesall,(100 - Number(notPercent)).toString(),true);
}// 绘制竖线
const funLine = (id: string,color: string,pointsList: any,topisno?: boolean
) => {// 计算偏移后的经纬度let offsetDistance1 = 0.0001; // 调整偏移距离以满足您的需求let offsetDistance = 0.00025; // 调整偏移距离以满足您的需求if (topisno) {offsetDistance1 = -0.00035;offsetDistance = -0.0002;}// 提取经纬度const lon1 = pointsList[0];const lat1 = pointsList[1] - offsetDistance1;const lon2 = pointsList[0];const lat2 = pointsList[1] - offsetDistance;const positionsData = [lon1, lat1, lon2, lat2];let line = viewer.entities.add({id: "Linecolor_" + id,name: "Vertical",polyline: {positions: Cesium.Cartesian3.fromDegreesArray(positionsData),width: 2,material: new Cesium.PolylineOutlineMaterialProperty({color: Cesium.Color.fromCssColorString(color),outlineColor: Cesium.Color.fromCssColorString(color),}),// 是否贴地显示clampToGround: true,// 显示在距相机的距离处的属性,多少区间内是可以显示的distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500), // 可视范围,// 是否显示show: true,},});
};
// 箭头线
function funArrowLin(id: string,color: string,pointsList: any,percentage?: string,topisno?: boolean
) {// 计算偏移后的经纬度let offsetDistance = 0.0002; // 调整偏移距离以满足您的需求if (topisno) {offsetDistance = -0.0003;}// 提取经纬度const lon1 = pointsList[0];const lat1 = pointsList[1] - offsetDistance;const lon2 = pointsList[2];const lat2 = pointsList[3] - offsetDistance;const positions = [lon1, lat1, lon2, lat2];// 计算线段中点的经纬度坐标const midLon = (lon1 + lon2) / 2;const midLat = (lat1 + lat2) / 2;// 添加百分比数值标签let label = viewer.entities.add({id: "ArrowLin_" + id,position: Cesium.Cartesian3.fromDegrees(midLon, midLat),label: {text: percentage + "%",font: "14px sans-serif",fillColor: Cesium.Color.WHITE,outlineColor: Cesium.Color.WHITE,outlineWidth: 1,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, topisno ? -10 : 10), // 垂直偏移量,使其看起来在线段中间// 显示在距相机的距离处的属性,多少区间内是可以显示的distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500), // 可视范围,eyeOffset: new Cesium.Cartesian3(0, 0, -30),},});let line = viewer.entities.add({id: id,name: "schedule",polyline: {positions: Cesium.Cartesian3.fromDegreesArray(positions),width: 12,material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.fromCssColorString(color)),// 是否贴地显示clampToGround: true,// 显示在距相机的距离处的属性,多少区间内是可以显示的distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500), // 可视范围,// 是否显示show: true,},});
}
//计算两点间距离
function getFlatternDistance(lat1, lng1, lat2, lng2) {var EARTH_RADIUS = 6378137.0; //单位Mvar PI = Math.PI;function getRad(d) {return (d * PI) / 180.0;}var f = getRad((lat1 + lat2) / 2);var g = getRad((lat1 - lat2) / 2);var l = getRad((lng1 - lng2) / 2);var sg = Math.sin(g);var sl = Math.sin(l);var sf = Math.sin(f);var s, c, w, r, d, h1, h2;var a = EARTH_RADIUS;var fl = 1 / 298.257;sg = sg * sg;sl = sl * sl;sf = sf * sf;s = sg * (1 - sl) + (1 - sf) * sl;c = (1 - sg) * (1 - sl) + sf * sl;w = Math.atan(Math.sqrt(s / c));r = Math.sqrt(s * c) / w;d = 2 * w * a;h1 = (3 * r - 1) / 2 / c;h2 = (3 * r + 1) / 2 / s;return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
}
// 绘制面积
function funPolygon(id: string, color: string, pointsList: any) {// let latone = 39.0063929; //buildBeginMileageLat  1// let lonone = 115.99045942; //buildBeginMileageLon  0// let lattwo = 39.0063934815; //nowlat  3// let lontwo = 115.9931488639; //nowlon 2let latone = pointsList[0];let lonone = pointsList[1];let lattwo = pointsList[2];let lontwo = pointsList[3];// let destination = Cesium.Cartesian3.fromDegrees(lontwo, lattwo, 1000); //// //  添加小手// // pointerdefault();// viewer.camera.flyTo({//   destination: destination,//   duration: 2, // 飞行动画持续时间(单位:秒)// });// 计算偏移后的经纬度const offsetDistance = 0.0001; // 调整偏移距离以满足您的需求//   // 提取经纬度// const lon1 = lonone;// const lat1 = latone - offsetDistance;// const lon2 = lontwo;// const lat2 = lattwo - offsetDistance;// const lon1Offset = lon1;// const lat1Offset = lat1 + offsetDistance+ offsetDistance;// const lon2Offset = lon2;// const lat2Offset = lat2 + offsetDistance+ offsetDistance;// // 添加四个点的经纬度数组// // const positionsList = [// //   lon1, lat1,// //   lon2, lat2,// //   lon2Offset, lat2Offset,// //   lon1Offset, lat1Offset,// //   lon1, lat1 // 闭合面// // ];const leftTop = [lonone, latone - offsetDistance]; //左上角经度const leftBottom = [lontwo, lattwo - offsetDistance]; //左下角经度const rightTop = [lontwo, lattwo + offsetDistance * 2]; //右上角经度const rightBottom = [lonone, latone + offsetDistance * 2]; //右下角经度let dataList = [leftTop, rightBottom, rightTop, leftBottom, leftTop];let positionsList = dataList.flat(Infinity) as [];// console.log("positionsList", positionsList);// 创建多边形面let rectangleBox = viewer.entities.add({id: "Redcolor_" + id,name: "polygonMileage",polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray(positionsList),// 颜色material: Cesium.Color.fromAlpha(Cesium.Color.fromCssColorString(color), //#e907070.5),// 是否贴地显示clampToGround: true,// 显示在距相机的距离处的属性,多少区间内是可以显示的//  distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 1500), // 可视范围,// 是否显示show: true,height: 1, // 高度extrudedHeight: 1, //获取或设置数字属性,该属性指定矩形拉伸的高度。设置此属性将创建从高处开始并在此高度处结束的体积// 表示相对于地形的位置。【CLAMP_TO_GROUND 该位置固定在地形上】【NONE 该位置是绝对的。】【RELATIVE_TO_GROUND 位置高度是指地形上方的高度。】heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,outline: true, //是否展示外线outlineColor: Cesium.Color.fromAlpha(Cesium.Color.fromCssColorString("#f30202"),0.5), //外线颜色outlineWidth: 2, //外线宽度fill: true, //是否填充},});// viewer.zoomTo(rectangleBox);
}
</script><style scoped>
#cesiumContainer {position: absolute;width: 100%;height: 100%;top: 0px;left: 0px;margin: 0;padding: 0;overflow: hidden;
}
.but {position: absolute;top: 50px;left: 100px;width: 200px;height: 20px;display: flex;justify-content: space-between;/* background-color: black; */z-index: 2;
}
.but div {height: 20px;font-size: 14px;z-index: 2;cursor: pointer;min-width: 100px;text-align: center;padding: 10px;background: rgba(0, 0, 0, 0.5);color: #fff;border-radius: 5px;margin-left: 10px;
}
</style>
<style lang="scss" scoped>
.but-boxone {position: absolute;top: 100px;left: 100px;width: 200px;display: flex;justify-content: space-between;.btn {font-size: 14px;z-index: 2;cursor: pointer;min-width: 100px;text-align: center;padding: 10px;background: rgba(0, 0, 0, 0.5);color: #fff;border-radius: 5px;margin-left: 10px;}
}
</style><style lang="scss" scoped>
.animated {-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}.animated.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}.animated.hinge {-webkit-animation-duration: 2s;animation-duration: 2s;
}/*the animation definition*/@-webkit-keyframes fadeInDown {0% {opacity: 0;-webkit-transform: translate3d(0, -100%, 0);transform: translate3d(0, -100%, 0);}100% {opacity: 1;-webkit-transform: none;transform: none;}
}@keyframes fadeInDown {0% {opacity: 0;-webkit-transform: translate3d(0, -100%, 0);-ms-transform: translate3d(0, -100%, 0);transform: translate3d(0, -100%, 0);}100% {opacity: 1;-webkit-transform: none;-ms-transform: none;transform: none;}
}.fadeInDown {-webkit-animation-name: fadeInDown;animation-name: fadeInDown;
}/*base code*/
.animated_two {-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_two.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_two.hinge {-webkit-animation-duration: 2s;animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes fadeOut {0% {opacity: 1;}100% {opacity: 0;}
}
@keyframes fadeOut {0% {opacity: 1;}100% {opacity: 0;}
}
.fadeOut {-webkit-animation-name: fadeOut;animation-name: fadeOut;
}/*base code*/
.animated_three {-webkit-animation-duration: 2s;animation-duration: 2s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_three.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_three.hinge {-webkit-animation-duration: 3s;animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes zoomIn {0% {opacity: 0;-webkit-transform: scale3d(0.3, 0.3, 0.3);transform: scale3d(0.3, 0.3, 0.3);}50% {opacity: 1;}
}
@keyframes zoomIn {0% {opacity: 0;-webkit-transform: scale3d(0.3, 0.3, 0.3);-ms-transform: scale3d(0.3, 0.3, 0.3);transform: scale3d(0.3, 0.3, 0.3);}50% {opacity: 1;}
}
.zoomIn {-webkit-animation-name: zoomIn;animation-name: zoomIn;
}/*base code*/
.animated_four {-webkit-animation-duration: 2s;animation-duration: 2s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_four.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_four.hinge {-webkit-animation-duration: 3s;animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes fadeInUpBig {0% {opacity: 0;-webkit-transform: translate3d(0, 2000px, 0);transform: translate3d(0, 2000px, 0);}100% {opacity: 1;-webkit-transform: none;transform: none;}
}
@keyframes fadeInUpBig {0% {opacity: 0;-webkit-transform: translate3d(0, 2000px, 0);-ms-transform: translate3d(0, 2000px, 0);transform: translate3d(0, 2000px, 0);}100% {opacity: 1;-webkit-transform: none;-ms-transform: none;transform: none;}
}
.fadeInUpBig {-webkit-animation-name: fadeInUpBig;animation-name: fadeInUpBig;
}/*base code*/
.animated_six {-webkit-animation-duration: 2s;animation-duration: 2s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_six.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_six.hinge {-webkit-animation-duration: 3s;animation-duration: 3s;
}
/*the animation definition*/
@-webkit-keyframes fadeOutDownBig {0% {opacity: 1;}100% {opacity: 0;-webkit-transform: translate3d(0, 2000px, 0);transform: translate3d(0, 2000px, 0);}
}
@keyframes fadeOutDownBig {0% {opacity: 1;}100% {opacity: 0;-webkit-transform: translate3d(0, 2000px, 0);-ms-transform: translate3d(0, 2000px, 0);transform: translate3d(0, 2000px, 0);}
}
.fadeOutDownBig {-webkit-animation-name: fadeOutDownBig;animation-name: fadeOutDownBig;
}/*base code*/
.animated_five {-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_five.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_five.hinge {-webkit-animation-duration: 2s;animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes rotateIn {0% {-webkit-transform-origin: center;transform-origin: center;-webkit-transform: rotate3d(0, 0, 1, -200deg);transform: rotate3d(0, 0, 1, -200deg);opacity: 0;}100% {-webkit-transform-origin: center;transform-origin: center;-webkit-transform: none;transform: none;opacity: 1;}
}
@keyframes rotateIn {0% {-webkit-transform-origin: center;-ms-transform-origin: center;transform-origin: center;-webkit-transform: rotate3d(0, 0, 1, -200deg);-ms-transform: rotate3d(0, 0, 1, -200deg);transform: rotate3d(0, 0, 1, -200deg);opacity: 0;}100% {-webkit-transform-origin: center;-ms-transform-origin: center;transform-origin: center;-webkit-transform: none;-ms-transform: none;transform: none;opacity: 1;}
}
.rotateIn {-webkit-animation-name: rotateIn;animation-name: rotateIn;
}/*base code*/
.animated_seven {-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_seven.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_seven.hinge {-webkit-animation-duration: 2s;animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes rotateOut {0% {-webkit-transform-origin: center;transform-origin: center;opacity: 1;}100% {-webkit-transform-origin: center;transform-origin: center;-webkit-transform: rotate3d(0, 0, 1, 200deg);transform: rotate3d(0, 0, 1, 200deg);opacity: 0;}
}
@keyframes rotateOut {0% {-webkit-transform-origin: center;-ms-transform-origin: center;transform-origin: center;opacity: 1;}100% {-webkit-transform-origin: center;-ms-transform-origin: center;transform-origin: center;-webkit-transform: rotate3d(0, 0, 1, 200deg);-ms-transform: rotate3d(0, 0, 1, 200deg);transform: rotate3d(0, 0, 1, 200deg);opacity: 0;}
}
.rotateOut {-webkit-animation-name: rotateOut;animation-name: rotateOut;
}/*base code*/
.animated_eight {-webkit-animation-duration: 1s;animation-duration: 1s;-webkit-animation-fill-mode: both;animation-fill-mode: both;
}
.animated_eight.infinite {-webkit-animation-iteration-count: infinite;animation-iteration-count: infinite;
}
.animated_eight.hinge {-webkit-animation-duration: 2s;animation-duration: 2s;
}
/*the animation definition*/
@-webkit-keyframes wobble {0% {-webkit-transform: none;transform: none;}15% {-webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);}30% {-webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);}45% {-webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);}60% {-webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);}75% {-webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);}100% {-webkit-transform: none;transform: none;}
}
@keyframes wobble {0% {-webkit-transform: none;-ms-transform: none;transform: none;}15% {-webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);-ms-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);}30% {-webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);-ms-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);}45% {-webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);-ms-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);}60% {-webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);-ms-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);}75% {-webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);-ms-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);}100% {-webkit-transform: none;-ms-transform: none;transform: none;}
}
.wobble {-webkit-animation-name: wobble;animation-name: wobble;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/844819.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录(二叉树)

二叉树的递归遍历 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list new ArrayList<>();if(rootnull) {return list;}else {traversal(list,root);}return list;}public void traversal(List<Integer> l…

如何培养元技能?

如何培养元技能&#xff1f; 一、引言 在当今社会&#xff0c;仅仅依靠某一专业技能是远远不够的。我们需要拓宽自己的能力和视野&#xff0c;从而更好地应对日新月异的社会发展和工作需求。在这个过程中&#xff0c;培养元技能变得至关重要。元技能不仅有助于我们在各个领域中…

【全开源】驾校管理系统源码(FastAdmin+ThinkPHP)

一款基于FastAdminThinkPHP开发的驾校管理系统&#xff0c;驾校管理系统(DSS)主要面向驾驶学校实现内部信息化管理&#xff0c;让驾校管理者和工作人员更高效、更快捷的完成枯燥无味的工作&#xff0c;让工作更有条理。改变驾校传统的手工或半手工Excel文档管理的工作方式。多驾…

JavaScript数据类型;属性,对象,方法;var,let,const,局部变量,全局变量

JavaScript数据类型&#xff1a; 值类型(基本类型)&#xff1a;字符串&#xff08;String&#xff09;、数字(Number)、布尔(Boolean)、空&#xff08;Null&#xff09;、未定义&#xff08;Undefined&#xff09;、Symbol。 引用数据类型&#xff08;对象类型&#xff09;&a…

PG主从切换

文章目录 一、 不再需要配置recovery.conf文件二、 备库执行基础备份时新的命令行选项-R三、 如何生成standby.signal文件四、初次主备切换流程1、主库停止2、备库提升为新主库&#xff0c;对外提供服务3、新主库修改pg_hba.conf文件4、原主库新建$PGDATA/standby.signal文件5、…

嵌入式进阶——HID协议

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 USB烧录USB HID协议USB协议组成通讯流程 官方USB HID范例文件说明修改PC端的显示 兼容库函数HID键盘USB调试工具USB 描述符设备描述…

mysql登录报错 Client does not support authentication protocol requested by server

mysql登录报错 Client does not support authentication protocol requested by server 在使用 MySQL 数据库时&#xff0c;你可能会遇到以下错误消息&#xff1a; ERROR 1251 (08004): Client does not support authentication protocol requested by server; consider upgr…

【数据结构与算法 | 栈 + 队列篇】力扣232, 225

1. 力扣232 : 用栈实现队列 (1). 题 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移…

suse xen内核安装启动失败问题

Error 15 /boot/xen.gz not found Filesystem type is ext2fs, partition type 0x83 Error 15 原因&#xff1a; 除了安装以下三个安装包 -rw-r--r-- 1 root root 23362981 Jun 14 2013 kernel-xen-3.0.76-0.11.1.x86_64.rpm -rw-r--r-- 1 root root 14158930 Jun 14 20…

Anaconda -> Anaconda支持什么编程语言的环境配置

Anaconda是一个数据科学和机器学习的开发环境&#xff0c;它支持多种编程语言的环境配置&#xff0c;包括&#xff1a; Python&#xff1a;Anaconda默认安装了Python和必需的Python库&#xff0c;可以方便地进行Python编程和数据分析。 R&#xff1a;Anaconda也可以配置R语言环…

MFC工控项目实例之一主菜单制作

1、本项目用在WIN10下安装的vc6.0兼容版实现。创建项目名为SEAL_PRESSURE的MFC对话框。在项目res文件下添加相关256色ico格式图片。 2、项目名称&#xff1a;密封压力试验机 主菜单名称&#xff1a; 系统参数 SYS_DATA 系统测试 SYS_TEST 选择型号 TYP_CHOICE 开始试验 TES_STA…

【参会通知】第四届电子、信息与计算技术前沿国际会议

尊敬的学者/专家&#xff1a; 您好&#xff01; 我们诚挚地邀请您参与2024年电子、信息与计算技术前沿国际会议&#xff08;ICFEICT 2024&#xff09;。会议将于2024年6月22日-6月25日在北京召开。ICFEICT 2024旨在为来自国内外高等院校、科研院所、企事业单位的专家、教授、…

SAP_SD模块 物料科目分配/成本简介

SAP系统各模块与财务都有个方面的集成。文本主要说明销售模块中的科目分配和成本的一个对应关系。 1、首先是在物料主数据上销售视图中的物料科目分配组&#xff0c;S1主营、S2材料等字段&#xff0c;物料销售的时候会将这个物料产生的记录到对应的科目中。 首先是物料主数据中…

pip更新网络问题:Exception: Traceback (most recent call last): File

报错&#xff1a;rootdebian01:~# pip3.9 install --upgrade pip Collecting pip Downloading pip-24.0-py3-none-any.whl (2.1 MB) |██████████████████▉ | 1.2 MB 5.5 kB/s eta 0:02:39ERROR: Exception: Traceback (most recent call last): File “/usr…

利用cython将.py文件编译为.pyd文件

文章目录 1. 引言2. py文件编译为pyd文件步骤2.1 环境准备2.2 准备setup.py文件2.3 进行编译 3. 测试代码 1. 引言 在实际的Python开发中&#xff0c;为了防止Python脚本源码暴露&#xff0c;常常需要对python源码文件进行加密保护&#xff0c;Python的原始文件格式为.py&…

在outlook的邮件中插入HTML;HTML模板获取;页面组态手动生成HTML

本文介绍如何在outlook发送邮件时&#xff0c;在邮件中插入HTML&#xff0c;此HTML可以从获取模板自行进行修改。 文章目录 一、下载HTML模板&#xff08;或自己制作好HTML文件&#xff09;二、outlook新增宏三、新建邮件&#xff0c;插入HTML四、通过图像化页面组态手动生成HT…

做场外个股期权怎么询价

做场外个股期权怎么询价&#xff1f;没有具体的哪家做市商是询价是最低的&#xff0c;个人投资者需要通过机构通道方询价进行对比&#xff0c;各券商的报价由询价机构方提供给到投资者&#xff0c;可以参考不同券商的报价进行比对&#xff0c;再决定是否进行投资。本文来自&…

操作系统复习-操作系统概述

操作系统概述 操作系统的基本功能 操作系统统一管理着计算机资源&#xff1a; 处理器资源IO设备资源存储器资源文件资源 操作系统实现了对计算机资源的抽象&#xff1a; 用户无需向硬件接口编程IO设备管理软件&#xff0c;提供读写接口文件管理软件&#xff0c;提供操作文…

关于验证码的那些漏洞

一、短信轰炸 这类漏洞存在的原因是没有对短信验证码的发送时间、用户及其IP作一些限制。 案例1、正常的短信轰炸 burp一直发包即可 案例2、并发绕过 做了限制咋办&#xff1f;可以试试并发(万物皆可并发) 使用turbo intruder插件进行并发。 并发次数越大是不是轰炸就越多。 …

宝塔安装java环境Jdk1.8

1.打开宝塔——选择“终端”——输入SSH的服务器IP和SSH账号&#xff0c;选择密码验证&#xff0c;输入密码 2。登录成功后&#xff0c;输入&#xff1a;yum list java-1.8*&#xff0c;用于列出所有与 “java-1.8” 相关的软件包 yum list java-1.8* 3.安装Jdk1.8: yum insta…