首页 > 其他分享 >Threejs 实现3D 地图(05)3d 地图进场动画和地图边缘动画

Threejs 实现3D 地图(05)3d 地图进场动画和地图边缘动画

时间:2024-10-24 15:45:34浏览次数:8  
标签:动画 Threejs const currentPos XYZ 地图 camera

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="i13IKzQd-1729650077245" src="https://live.csdn.net/v/embed/430617"></iframe>

3d 地图进场特效以及地图边缘动画

代码仓库:

King/threejs-3d-map

地图边缘动画核心代码:

const initBorderPoint = () => {
  // 获取地图边界的左边(通过https://datav.aliyun.com/portal/school/atlas/area_generator#2.51/104.299012/33.447963 获取)
  let borderPoints3Array = borderMap.features[0].geometry.coordinates
  let borderPoints = []
  borderPoints3Array.forEach((coordinate) => {
    coordinate.forEach((rows) => {
      rows.forEach(v => {
        // 将坐标转化为 d3的坐标
        const [x_XYZ, y_XYZ] = d3.geoMercator().center([109, 34.5]).scale(1000).translate([0, 0])(v)
        borderPoints.push({x: x_XYZ, y: -y_XYZ})
        // 将转换后的坐标放入到一个数组存储起来(重点!!!)
        linePoints.push([x_XYZ, -y_XYZ, 32])
      })
    });
  });
  opacityGeometry = new THREE.BufferGeometry();
  // 将数组转化为一维数组
  positions = new Float32Array(linePoints.flat(1));
  // 然后3个一组
  opacityGeometry.setAttribute("position", new BufferAttribute(positions, 3));
  opacity = new Float32Array(positions.length).map(() => 0);
  opacityGeometry.setAttribute("aOpacity", new BufferAttribute(opacity, 1));
  // 控制 颜色和粒子大小
  const params = {
    pointSize: 5.0,
    pointColor: '#37ffff'
  }
  // 看不懂写死
  const vertexShader = `
    attribute float aOpacity;
    uniform float uSize;
    varying float vOpacity;

    void main(){
        gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
        gl_PointSize = uSize;

        vOpacity=aOpacity;
    }
    `
  // 看不懂写死
  const fragmentShader = `
    varying float vOpacity;
    uniform vec3 uColor;

    float invert(float n){
        return 1.-n;
    }

    void main(){
      if(vOpacity <=0.2){
          discard;
      }
      vec2 uv=vec2(gl_PointCoord.x,invert(gl_PointCoord.y));
      vec2 cUv=2.*uv-1.;
      vec4 color=vec4(1./length(cUv));
      color*=vOpacity;
      color.rgb*=uColor;
      gl_FragColor=color;
    }
    `
  // 创建着色器
  const material = new THREE.ShaderMaterial({
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
    transparent: true, // 设置透明
    uniforms: {
      uSize: {
        value: params.pointSize
      },
      uColor: {
        value: new THREE.Color(params.pointColor)
      }
    }
  })
  //  创建一个点
  opacityPoints = new THREE.Points(opacityGeometry, material)
  // 将这个点放入到场景中
  showScene.add(opacityPoints);
}
const render = () => {
  if (activeProvince === '四川省') {
    renderer.render(ScScene, camera)
    let info = document.querySelector('#info')
    info.style.display = 'none'
    showScene = ScScene
  } else {
    renderer.render(showScene, camera)
  }
  if (!activeProvince) {
    showScene = scene
    renderer.render(showScene, camera)
  }
  // 如果有地图边界所有坐标
  if (linePoints && opacity) {
    // 5234怎么来的:linePoints打印出来我这边有7134个  但是我这边有900个边界点我这边不想显示(也就是我视频下面那一坨很杂碎的地方)所以我截取了5234个
    //currentPos 也就是数组下标 只去前面5234个点
    if (currentPos > 5234) {
      // 移除边缘动画线
      // showScene.remove(opacityPoints)
      currentPos = 0;
    }
    // 20  就是运动的速度  值越大 移动越快
    currentPos += 20;
    // 忘记这是干嘛的
    for (let i = 0; i < 10; i++) {
      opacity[(currentPos - i) % linePoints.length] = 0;
    }
    // // 忘记这是干嘛的
    for (let i = 0; i < 100; i++) {
      opacity[(currentPos + i) % linePoints.length] = i / 50 > 2 ? 2 : i / 50;
    }
    // 让点 动起来
    if (opacityGeometry) {
      opacityGeometry.attributes.aOpacity.needsUpdate = true;
    }
  }
  // 渲染下一帧的时候会调用render函数
  requestAnimationFrame(render)
  tween.update()
  controls.update()
}

进场动画核心代码:

const tween = new Tween({x: 1000, y: 1000, z: 2000}) // 起始位置
    .to(camera.position, 2000) // 最终位置
    .easing(Easing.Quadratic.In) // 过度动画
    .onUpdate((object) => { // 改变摄像机位置
      camera.position.x = object.x
      camera.position.y = object.y
      camera.position.z = object.z
    })
    .start();

主要代码解析:

1、获取边缘地图的所有坐标  转换为 d3坐标

DataV.GeoAtlas地理小工具系列

 2、绘制着色器材质(ShaderMaterial)

three.js docs

3、将着色器材质按照地图边界的坐标跑动 

4、使用Tween动画库或者 gsap 动画库实现摄像机进场动画

下一篇:

Threejs 实现3D 地图(06)3d 地图飞线动画-CSDN博客

标签:动画,Threejs,const,currentPos,XYZ,地图,camera
From: https://blog.csdn.net/qq_57952018/article/details/143176468

相关文章

  • 谷歌地图 | 与 Android 版导航 SDK 集成的最佳实践
    谷歌最近宣布了导航SDK,它可以让您将熟悉的Google地图逐向导航体验无缝集成到您的Android和iOS应用程序中。这篇博文概述了一些最佳实践,您可以使用这些实践为您的Android应用程序使用导航SDK构建流畅、一致且可靠的导航体验。 与导航地图交互与NavigationSDK集......
  • WGS84转百度地图坐标
    什么是地图坐标系转换?目前常用的地图坐标系有多种标准,几家主流地图(如百度地图,高德地图和QQ地图等)使用的坐标系标准也各不相同。假如您有GPS坐标,想在百度地图上显示;或者有百度地图的坐标,但想在微信地图上显示,这时就需要使用一些算法或通过官方的API来转换坐标,在目标地图上正确显......
  • HarmonyOS:合理使用动画(2)
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(MaoistLearning)➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/p/......
  • 基于SpringBoot + Vue的G县乡村生活垃圾治理问题中运输地图的设计与实现
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • HarmonyOS:合理使用动画
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(MaoistLearning)➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/p/......
  • css3序列帧动画&图片资源初次加载闪屏处理
    /*定义关键帧*/@keyframesexample{0%{background:url(./ani/1.png)centercenterno-repeat;background-size:cover;}……100%{background:url(./ani/48.png)centercenterno-repeat;background-size:cover;}}.......
  • 【HarmonyOS】取消页面转场动画
    【HarmonyOS】取消页面转场动画问题背景:当A页面切换至B页面时,系统会自带左右进场退场的动画效果。一般来说,该效果是ok的,但是在特殊场景下,例如:A页面跳到B页面,又跳到C页面。C页面直接返回到A页面。正常不处理时,C到A会有两次页面切换的动画,最终才能展示到A页面。此时就需要能将B页面......
  • 地图导航平台怎么标注店铺定位?
    地图导航作为人们日常出行、寻找周边服务的重要工具,其商业价值不可小觑。对于商家而言,如果能够在地图导航平台上标注店铺定位,不仅能够提升顾客的访问便利性,还能有效增加曝光率,吸引更多潜在客户。那么,如何在地图导航平台上标注店铺定位呢?接下来,企小花将详细阐述国内三大主流地图......
  • 腾讯地图web端请求报错113.该功能未授权
    问题描述:请求地址:https://apis.map.qq.com/jsapi?qt=geoc&addr=%2C%2C%2C&key=你的key&output=jsonp&pf=jsapi&ref=jsapi&cb=qq.maps._svcb3.geocoder0报错:qq.maps._svcb3.geocoder0&&qq.maps._svcb3.geocoder0({"status":113,"me......
  • QT离线三维地图插件
    ​QT三维离线地图插件是一款功能强大的离线三维地图插件,支持多图源切换、海量点绘制、星历外推、航迹仿真、模型加载、倾斜数据加载,能够实现真实感的卫星仿真及航迹平滑处理。此外,该插件设计为便于二次开发,允许开发者根据特定需求扩展和定制功能,满足多样化的应用场景。支持Windo......