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
<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 ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmMGU1MDc1Yy0zZTMyLTQ0ODEtYjcxYi0yYjAyNDgyZGY1MjQiLCJpZCI6MjAxMDQ3LCJpYXQiOjE3MTAxNjM4NjF9.b9qwNlQbvo49RJTHEMpjIiOS-mOvf9MF8ZHSYTdf6CI";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.rhkb.cn/news/335553.html

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

相关文章

贝叶斯算法:机器学习中的“黄金法则”与性能提升之道

&#x1f440;传送门&#x1f440; &#x1f50d;机器学习概述&#x1f340;贝叶斯算法原理&#x1f680;贝叶斯算法的应用✨文本分类✨医疗系统 &#x1f496;贝叶斯算法优化✨贝叶斯算法优化的主要步骤✨贝叶斯算法优化的优点✨贝叶斯算法优化的局限性 &#x1f697;贝叶斯算…

设计模式21——命令模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 命令模式&#xff08;Command&…

ROS2学习——节点话题通信(2)

目录 一、ROS2节点 1.概念 2.实例 &#xff08;1&#xff09;ros2 run &#xff08;2&#xff09;ros2 node list &#xff08;3&#xff09;remapping重映射 &#xff08;4&#xff09;ros2 node info 二、话题 &#xff08;1&#xff09; ros2 topic list &#xf…

英特尔LLM技术挑战记录

英特尔技术介绍&#xff1a; Flash Attention Flash Attention 是一种高效的注意力机制实现&#xff0c;旨在优化大规模 Transformer 模型中的自注意力计算。在深度学习和自然语言处理领域&#xff0c;自注意力是 Transformer 架构的核心组件&#xff0c;用于模型中不同输入元…

解决Android studio 一直提示下载gradle-xxx-all.zip问题

今天用AndroidStdiod打开一个新工程的时候&#xff0c;发现项目一直卡在正在下载gradle-xxx-all.zip的任务上&#xff0c;网络出奇的慢&#xff0c;即使配了VPN也无济于事&#xff0c;于是按照以往经验&#xff1a;将gradle-xxx-all.zip下载到.gradle\gradle\wrapper\dists目录…

JDK8新特性之lambda表达式

大家好&#xff0c;这里是教授.F 目录 引入&#xff1a; 什么情况下使用/使用前提&#xff1a; 标准格式&#xff1a; 实现原理&#xff1a; 省略格式&#xff1a; 引入&#xff1a; lambda表达式就是简介的书写我们的匿名内部类。Lambda相当于对接口的抽象方法的重写。 什…

高并发项目-用户登录基本功能

文章目录 1.数据库表设计1.IDEA连接数据库2.修改application.yml中数据库的名称为seckill3.IDEA创建数据库seckill4.创建数据表 seckill_user5.密码加密分析1.传统方式&#xff08;不安全&#xff09;2.改进方式&#xff08;两次加密加盐&#xff09; 2.密码加密功能实现1.pom.…

QTP——功能测试

一、前言&#xff08;课设目的及内容&#xff09; QTP是quicktest Professional的简称&#xff0c;是一种自动测试工具。使用QTP的目的是想用它来执行重复的手动测试&#xff0c;主要是用于回归测试和测试同一软件的新版本。因此你在测试前要考虑好如何对应用程序进行测试&…

探索AI去衣技术中的反射应用

在当今数字时代&#xff0c;人工智能&#xff08;AI&#xff09;技术的飞速发展已经渗透到了我们生活的方方面面。其中&#xff0c;图像处理和计算机视觉作为AI的重要分支&#xff0c;正不断推动着创新应用的边界。今天&#xff0c;我们要探讨的是一个颇具争议但又技术上颇为有…

重学java51.Collections集合工具类、泛型

"我已不在地坛&#xff0c;地坛在我" —— 《想念地坛》 24.5.28 一、Collections集合工具类 1.概述:集合工具类 2.特点: a.构造私有 b.方法都是静态的 3.使用:类名直接调用 4.方法: static <T> boolean addAll(collection<? super T>c,T... el…

小阿轩yx-Shell编程之正则表达式与文本处理器

小阿轩yx-Shell编程之正则表达式与文本处理器 正则表达式 &#xff08;RegularExpression&#xff0c;RE&#xff09; 正则表达式概述 正则表达式的定义 又称 正规表达式常规表达式 代码中常简写为 regex、regexp 或 RE 正则表达式 使用单个字符串来描述、匹配一系列符…

2024 angstromCTF re 部分wp

Guess the Flag 附件拖入ida 比较简单&#xff0c;就一个异或 switcher 附件拖入ida 明文flag Polyomino 附件拖入ida 需要输入九个数&#xff0c;然后进入处理和判断&#xff0c;如果满足条件则进入输出flag部分&#xff0c;flag和输入有关&#xff0c;所以要理解需要满足什么…

信号处理中简单实用的方法

最小二乘法拟合消除趋势项 消除趋势项函数 在MATLAB的工具箱中已有消除线性趋势项的detrend函数&#xff1b;再介绍以最小二乘法拟合消除趋势项的polydetrend 函数。 函数:detrend功能:消除线性趋势项 调用格式:ydetrend(x) 说明:输入参数x是带有线性趋势项的信号序列,输出…

【网络协议】应用层协议--HTTP

文章目录 一、HTTP是什么&#xff1f;二、HTTP协议工作过程三、HTTP协议1. fiddler2. Fiddler抓包的原理3. 代理服务器是什么?4. HTTP协议格式1.1 请求1.2 响应 四、认识HTTP的请求1.认识HTTP请求的方法2.认识请求头&#xff08;header&#xff09;3.认识URL3.1 URL是什么&…

香橙派AIpro初体验

1.开发板资料 开发板资源 产品介绍主页&#xff1a;http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-AIpro.html开发板案例源码&#xff1a;https://gitee.com/ascend/EdgeAndRobotics工具&原理图&案例源码&开发手册&#x…

BH-0.66 6000/5/150电流互感器 塑壳 JOSEF约瑟

BH-0.66 15/5塑壳式电流互感器 BH-0.66 20/5塑壳式电流互感器 BH-0.66 30/5塑壳式电流互感器 BH-0.66 40/5塑壳式电流互感器 BH-0.66 50/5塑壳式电流互感器 BH-0.66 75/5塑壳式电流互感器 BH-0.66 100/5塑壳式电流互感器 BH-0.66 150/5塑壳式电流互感器 BH-0.66 200/5塑壳式…

vue3中的toRaw API

文章目录 什么是toRaw API&#xff1f;为什么需要toRaw&#xff1f;如何使用toRaw&#xff1f;实际应用场景 这两天在写项目的时候&#xff0c;发现了一个之前没用过的api&#xff0c;于是上网查了一下&#xff0c;发现这个api还是挺常用&#xff0c;所以在这记录一下 什么是t…

前端 JS 经典:Web 性能指标

什么是性能指标&#xff1a;Web Performance Metrics 翻译成 Web 性能指标&#xff0c;一般和时间有关系&#xff0c;在短时间内做更多有意义的事情。 一个站点表现得好与不好&#xff0c;标准在于用户体验&#xff0c;而用户体验好不好&#xff0c;有一套 RAIL 模型来衡量。这…

计算机毕业设计 | SpringBoot+vue仓库管理系统(附源码)

1&#xff0c;绪论 1.1 项目背景 随着电子计算机技术和信息网络技术的发明和应用&#xff0c;使着人类社会从工业经济时代向知识经济时代发展。在这个知识经济时代里&#xff0c;仓库管理系统将会成为企业生产以及运作不可缺少的管理工具。这个仓库管理系统是由&#xff1a;一…

amis 文件上传 大文件分块上传

amis 图片/文件上传组件 receiver&#xff1a;参数配置为上传接口。 {"type": "input-image", // "type": "input-file","label": "照片","name": "url", "imageClassName": &qu…