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

成都交投成高建设公司网站做部队网站技术

成都交投成高建设公司网站,做部队网站技术,网站建设 精品课程,网站整站建设继续我们的Cesium系列,这次来整点有意思的——给地图上的标注加点动画效果。静态的点线面看久了总觉得少点什么,动起来的标注不仅更吸引眼球,在实际项目中也能更好地突出重要信息。 动画实现的核心原理 在Cesium中实现标注动画主要有两种方式…

继续我们的Cesium系列,这次来整点有意思的——给地图上的标注加点动画效果。静态的点线面看久了总觉得少点什么,动起来的标注不仅更吸引眼球,在实际项目中也能更好地突出重要信息。

动画实现的核心原理

在Cesium中实现标注动画主要有两种方式:

  • CallbackProperty方式:通过回调函数动态计算属性值,适合简单的动画效果
  • GPU着色器方式:使用GLSL着色器在GPU上计算,适合复杂的视觉效果,性能更好

基础动画效果

1. 呼吸动画

最经典的动画效果,点的大小按正弦波规律变化。通过Math.sin()函数控制大小的周期性变化,就像呼吸一样有节奏感。

2. 闪烁动画

通过快速改变透明度来实现闪烁效果,特别适合用来标识警告信息或需要紧急关注的位置。使用条件判断让颜色在两个状态间快速切换。

3. 颜色渐变

利用HSL颜色空间,让标注的颜色在整个色环上连续变化,产生彩虹般的渐变效果。这种效果在展示数据变化或状态转换时特别有用。

4. 弹跳动画

控制标签的垂直位置,让文字上下弹跳。使用Math.abs(Math.sin())确保弹跳始终向上,增加趣味性的同时也能有效吸引注意。

5. 旋转动画

对Billboard图标应用旋转变换,适合展示方向性信息。旋转速度可控,可以表示风向、车辆朝向等动态信息。

6. 组合动画

将多种动画效果组合使用,比如同时改变大小、颜色、位置和透明度,创造更丰富的视觉效果。这种方式虽然复杂,但视觉冲击力更强。

7.波纹扩散效果

使用GPU着色器技术实现真正的水波涟漪效果。不同于之前用多个点模拟的方法,这种实现方式性能更好,效果也更自然。

<template><div id="cesiumContainer" style="width: 100%; height: 100vh;"></div>
</template><script setup>
import { onMounted } from 'vue';
import {Ion,Viewer,Cartesian3,Color,PointGraphics,LabelGraphics,BillboardGraphics,CallbackProperty,Math as CesiumMath,JulianDate,ScreenSpaceEventType,defined,HorizontalOrigin,VerticalOrigin,LabelStyle,HeightReference,Material,MaterialAppearance,EllipseGeometry,GeometryInstance,Primitive
} from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";onMounted(() => {// 设置 Cesium Ion 访问令牌Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhNmQ5NDYyNi1lZTdhLTRiYTItODFiZi1mYzNiYWNjNDFjMzgiLCJpZCI6NTk3MTIsImlhdCI6MTY2MDE4MDAyNX0.bDTaHEah0hRjUyJWz0hyxIL0Fg63awPXV26OmQ5MCdM';const viewer = new Viewer('cesiumContainer', {animation: false, // 移除动画控件timeline: false, // 移除时间轴控件geocoder: false, // 移除地理编码控件homeButton: false, // 移除主页按钮sceneModePicker: false, // 移除场景模式选择器selectionIndicator: false, // 移除选择指示器fullscreenButton: false, // 移除全屏按钮vrButton: false // 移除 VR 按钮});// ==================== 动画相关变量 ====================let startTime = performance.now(); // 动画开始时间// ==================== 1. 呼吸动画点标注 ====================// 使用 CallbackProperty 创建动态属性const breathingSize = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000; // 经过的秒数const breathingFactor = Math.sin(elapsed * 2) * 0.5 + 1; // 0.5-1.5之间变化return 15 * breathingFactor; // 基础大小15,动态变化}, false);viewer.entities.add({id: 'breathing-point',name: '呼吸动画点',position: Cartesian3.fromDegrees(114.0579, 22.5431),point: new PointGraphics({pixelSize: breathingSize, // 动态大小color: Color.RED,outlineColor: Color.WHITE,outlineWidth: 2,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '呼吸动画点',font: '16pt Arial',fillColor: Color.WHITE,outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cartesian3(0, -50, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 2. 闪烁动画点标注 ====================const blinkingAlpha = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const blinkFactor = Math.sin(elapsed * 4) > 0 ? 1.0 : 0.3; // 快速闪烁return blinkFactor;}, false);viewer.entities.add({id: 'blinking-point',name: '闪烁动画点',position: Cartesian3.fromDegrees(113.2278, 23.1291),point: new PointGraphics({pixelSize: 20,color: new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const alpha = Math.sin(elapsed * 4) > 0 ? 1.0 : 0.3;return Color.BLUE.withAlpha(alpha);}, false),outlineColor: Color.YELLOW,outlineWidth: 3,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '闪烁动画点',font: '16pt Arial',fillColor: Color.YELLOW,outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cartesian3(0, -50, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 3. 颜色渐变动画点标注 ====================const gradientColor = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const hue = (elapsed * 50) % 360; // 色相循环变化return Color.fromHsl(hue / 360, 1.0, 0.5); // HSL颜色空间}, false);viewer.entities.add({id: 'gradient-point',name: '颜色渐变点',position: Cartesian3.fromDegrees(108.9478, 34.2317),point: new PointGraphics({pixelSize: 25,color: gradientColor,outlineColor: Color.WHITE,outlineWidth: 2,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '颜色渐变点',font: '16pt Arial',fillColor: gradientColor, // 标签颜色也跟着变化outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cartesian3(0, -50, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 4. 弹跳动画点标注 ====================const bounceOffset = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const bounce = Math.abs(Math.sin(elapsed * 3)) * 80; // 弹跳高度0-80像素return new Cartesian3(0, -50 - bounce, 0);}, false);viewer.entities.add({id: 'bounce-point',name: '弹跳动画点',position: Cartesian3.fromDegrees(104.0614, 30.6515), // 成都point: new PointGraphics({pixelSize: 18,color: Color.GREEN,outlineColor: Color.DARKGREEN,outlineWidth: 3,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '弹跳动画点',font: '16pt Arial',fillColor: Color.GREEN,outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: bounceOffset, // 动态偏移horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 5. 旋转动画Billboard标注 ====================// 创建一个简单的箭头图标SVGconst arrowSvg = `<svg width="40" height="40" xmlns="http://www.w3.org/2000/svg"><polygon points="20,5 35,25 25,25 25,35 15,35 15,25 5,25" fill="orange" stroke="black" stroke-width="1"/></svg>`;const arrowDataUri = 'data:image/svg+xml;base64,' + btoa(arrowSvg);const rotationAngle = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;return elapsed * CesiumMath.PI_OVER_TWO; // 每2秒旋转90度}, false);viewer.entities.add({id: 'rotation-billboard',name: '旋转Billboard',position: Cartesian3.fromDegrees(87.6177, 43.7928),billboard: new BillboardGraphics({image: arrowDataUri,scale: 1.0,rotation: rotationAngle, // 动态旋转角度pixelOffset: new Cartesian3(0, -20, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '旋转动画标注',font: '16pt Arial',fillColor: Color.ORANGE,outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cartesian3(0, -80, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 6. 组合动画标注 ====================// 综合多种动画效果的复杂标注const complexSize = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const sizeFactor = Math.sin(elapsed * 1.5) * 0.3 + 1; // 缓慢的呼吸return 20 * sizeFactor;}, false);const complexColor = new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const alpha = Math.sin(elapsed * 2) * 0.3 + 0.7; // 透明度变化return Color.PURPLE.withAlpha(alpha);}, false);viewer.entities.add({id: 'complex-animation',name: '组合动画标注',position: Cartesian3.fromDegrees(91.1406, 29.6522),point: new PointGraphics({pixelSize: complexSize,color: complexColor,outlineColor: Color.WHITE,outlineWidth: 2,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '组合动画',font: '18pt Arial',fillColor: new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const hue = (elapsed * 30) % 360;return Color.fromHsl(hue / 360, 0.8, 0.6);}, false),outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new CallbackProperty(function(time, result) {const elapsed = (performance.now() - startTime) / 1000;const wobble = Math.sin(elapsed * 4) * 10; // 左右摆动return new Cartesian3(wobble, -60, 0);}, false),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 7. 波纹扩散效果====================// 创建波纹扩散函数function createRippleEffect(viewer, longitude, latitude, radius, color, speed) {const instance = new GeometryInstance({geometry: new EllipseGeometry({center: Cartesian3.fromDegrees(longitude, latitude, 0),semiMinorAxis: radius,semiMajorAxis: radius,}),});const appearance = new MaterialAppearance({material: new Material({fabric: {uniforms: {color: Color.fromCssColorString(color),speed: speed,},source: `czm_material czm_getMaterial(czm_materialInput materialInput) {czm_material material = czm_getDefaultMaterial(materialInput);material.diffuse = 1.5 * color.rgb;vec2 st = materialInput.st;float dis = distance(st, vec2(0.5, 0.5));// 创建三道波纹,每道间隔0.3的时间float per1 = fract(czm_frameNumber * 0.032 * speed);float per2 = fract((czm_frameNumber * 0.032 * speed) - 0.3);float per3 = fract((czm_frameNumber * 0.032 * speed) - 0.6);// 计算每道波纹的透明度float pass1 = step(per1 * 0.3, dis) == 0.0? color.a * dis / per1: 0.0;float pass2 = step(per2 * 0.3, dis) == 0.0? color.a * dis / per2: 0.0;float pass3 = step(per3 * 0.3, dis) == 0.0? color.a * dis / per3: 0.0;// 实现渐变消失效果pass1 = pass1 * (1.0 - per1) * 2.0;pass2 = pass2 * (1.0 - per2) * 2.0;pass3 = pass3 * (1.0 - per3) * 2.0;// 取最大值作为最终透明度material.alpha = max(max(pass1, pass2), pass3);return material;}`,}}),});return viewer.scene.primitives.add(new Primitive({geometryInstances: instance,appearance: appearance}));}// 添加波纹效果// 波纹 - 哈尔滨 - 青色createRippleEffect(viewer, 126.5382, 45.8036, 100000, 'rgba(0, 255, 255, 0.8)', 0.2);// 为波纹中心添加标注点和标签viewer.entities.add({id: 'ripple-center-1',name: '哈尔滨波纹中心',position: Cartesian3.fromDegrees(126.5382, 45.8036),point: new PointGraphics({pixelSize: 8,color: Color.CYAN,outlineColor: Color.WHITE,outlineWidth: 2,heightReference: HeightReference.CLAMP_TO_GROUND}),label: new LabelGraphics({text: '哈尔滨-波纹扩散',font: '14pt Arial',fillColor: Color.CYAN,outlineColor: Color.BLACK,outlineWidth: 2,style: LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cartesian3(0, -60, 0),horizontalOrigin: HorizontalOrigin.CENTER,verticalOrigin: VerticalOrigin.BOTTOM})});// ==================== 设置相机视角 ====================/*viewer.camera.setView({destination: Cartesian3.fromDegrees(116, 30, 3000000),orientation: {heading: 0.0,pitch: -0.99,roll: 0.0}});*/// 使用 flyTo 方法,自动计算最佳视角viewer.flyTo(viewer.entities);// ==================== 点击事件处理 ====================viewer.cesiumWidget.screenSpaceEventHandler.setInputAction(function onLeftClick(event) {const pickedObject = viewer.scene.pick(event.position);if (defined(pickedObject) && defined(pickedObject.id)) {console.log('点击的动画标注:', pickedObject.id.name || pickedObject.id.id);// 可以在这里添加点击后的交互效果if (pickedObject.id.name) {alert(`点击了: ${pickedObject.id.name}`);}}}, ScreenSpaceEventType.LEFT_CLICK);// ==================== 动画控制函数 ====================// 可以添加暂停/恢复动画的功能window.pauseAnimations = function() {startTime = performance.now() - (performance.now() - startTime);};window.resumeAnimations = function() {startTime = performance.now();};// 在控制台输出提示信息console.log('标注动画示例已加载!');console.log('可以使用 pauseAnimations() 和 resumeAnimations() 来控制动画');
});
</script><style>
/* 隐藏页面底部的 Cesium logo 和数据归属 */
.cesium-viewer .cesium-widget-credits {display: none !important;
}/* 隐藏右上角的 Imagery 和 Navigation instructions */
.cesium-viewer .cesium-viewer-toolbar {display: none !important;
}
</style>

源码


文章转载自:

http://SFUWzf7T.zhnyj.cn
http://93oHdnEf.zhnyj.cn
http://MNyYeMpT.zhnyj.cn
http://jvDybnDo.zhnyj.cn
http://MzFGsJ2w.zhnyj.cn
http://t2wFsrKi.zhnyj.cn
http://W8dCt4oa.zhnyj.cn
http://LuVWzXQf.zhnyj.cn
http://SQRr5kpz.zhnyj.cn
http://KueTOqx9.zhnyj.cn
http://i5xeHRrl.zhnyj.cn
http://tMYBsZal.zhnyj.cn
http://se3LRTn3.zhnyj.cn
http://jxdvrm9I.zhnyj.cn
http://o9ur5MTZ.zhnyj.cn
http://eGXY8GbF.zhnyj.cn
http://dlEijF7X.zhnyj.cn
http://J2UKWAoh.zhnyj.cn
http://2oWjneiZ.zhnyj.cn
http://w35Zdb7c.zhnyj.cn
http://6bU9wXKo.zhnyj.cn
http://OzYlSsSb.zhnyj.cn
http://Jo7c4bjZ.zhnyj.cn
http://2rpDYP7N.zhnyj.cn
http://ZoMbwKYw.zhnyj.cn
http://gbNv8b83.zhnyj.cn
http://FZHuZ5Zs.zhnyj.cn
http://1LVTzaq8.zhnyj.cn
http://TM6OmQrl.zhnyj.cn
http://K6K8VW0o.zhnyj.cn
http://www.dtcms.com/wzjs/722323.html

相关文章:

  • 做网站是自己公司做好还是外包好html教程网
  • 成都建设网站的公司有哪些哪个推客平台最好
  • 展示网站如何做二级网站建设管理制度
  • 网站建设加推广优化中英文企业网站制作
  • seo网站建设接单百度搜索引擎优化指南最新版
  • 昌邑建设网站wordpress google 慢
  • 网站建设费账务处理商品推广软文范例200字
  • 做简单网站后端需要学什么开发网站
  • html5 网站开发定制销售手机网站
  • 给公司做个网站多少钱四川省城乡和住房建设厅网站
  • 网站已改版网站推广软文代发
  • 基于html5的旅游网站的设计优秀国内个人网站网址
  • 住房和城建设网站wordpress修改访问量
  • 做啥网站桥头网站建设
  • 网站开发一般要哪些开发工具国家企业信息信用信息公示网山东
  • 如何创建一个自己公司网站房子装修设计图片大全
  • 传统媒体网站建设响应式网站 框架
  • 赣州门户网站外贸跨境电商平台有哪些
  • 做网站滨州市公司做网站的费用记什么科目
  • 网站开发企业标准电子网站模板
  • 企业网站建设公司注意哪些问题综合搜索引擎
  • 二级学院网站建设自评报告网站怎么做关键词研究
  • 英文建站网站手机非法网站怎么解决方案
  • 沧州网站的公众号织梦怎么关闭网站
  • 阅读网站模板做网站要用那些软件
  • .net 接单网站世界政务网站绩效评估指标体系建设
  • 东莞有什么比较好的网站公司天长企业网站制作
  • 网站猜你喜欢代码请人用wordpress建站假期
  • 网站建设 部署与发布视频教程电子商务网站建设课
  • 网站seo设置wordpress添加标签