Threejs 实现3D 地图(06)3d 地图飞线动画

3d 地图飞线

代码仓库:

King/threejs-3d-map

核心代码:


import flyLine from "./constant/flyLine.json";

const initFlyLine = () => {
  flyLine.forEach(item => {
    const [from_x, from_y] = d3Function(item.from)
    const [to_x, to_y] = d3Function(item.to)
    const start = new THREE.Vector3(from_x, -from_y, 32);  // 起点坐标

    const v1Point = [item.from[0] + (item.to[0] - item.from[0]) / 4, item.from[1] + (item.to[1] - item.from[1]) / 4]
    const [v1_x, v1_y] = d3Function(v1Point)
    const v1 = new THREE.Vector3(v1_x, -v1_y, 100);
    const v2Point = [item.from[0] + ((item.to[0] - item.from[0]) * 3) / 4, item.from[1] + ((item.to[1] - item.from[1]) * 3) / 4]
    const [v2_x, v2_y] = d3Function(v2Point)
    const v2 = new THREE.Vector3(v2_x, -v2_y, 100);

    const end = new THREE.Vector3(to_x, -to_y, 32);  // 终点坐标

    // 创建三次贝塞尔曲线
    const curve = new THREE.CubicBezierCurve3(start, v1, v2, end);

    // 使用 TubeGeometry 根据贝塞尔曲线绘制管道
    const tubeGeometry = new THREE.TubeGeometry(curve, 256, 2, 8, false); // 曲线256段, 半径2, 20个横截面

    // 创建材质,颜色为白色
    const material = new THREE.MeshBasicMaterial({color: item.color});

    // 创建管道网格
    const tubeMesh = new THREE.Mesh(tubeGeometry, material);

    // 将管道添加到场景中
    showScene.add(tubeMesh);

    const points = curve.getPoints(1000)
    const bufferGeometry = createBufferGeometry(points)
    const shaderMaterial = createShaderMaterial()
    const point = new THREE.Points(bufferGeometry, shaderMaterial)
    showScene.add(point)
    // 设置着色器的动画
    gsap.fromTo(shaderMaterial.uniforms.uTime,
      { value: 0 },
      {
        // 实现飞线钻地效果需要让 动画节段数 = 飞线长度 + 飞线点数量
        value: 80 + 1000,
        duration: 3,
        repeat: -1,
        delay: 0,
        ease: "none",
        onUpdate: () => {},
      }
    );
  })
}

// 创建着色器
function createShaderMaterial() {
  // 起点颜色
  let color1 = "#0c57e3";
  return new THREE.ShaderMaterial({
    depthTest: false,
    uniforms: {
      // 线条颜色
      uColor: {
        value: new THREE.Color(color1),
      },
      // 时间1-1000
      uTime: {
        value: 0,
      },
      // 水滴宽度
      uWidth: {
        value: 200,
      },
      // 水滴长度
      uLength: {
        value: 80,
      },
      vSize: {
        value: 10.0
      },
    },
    vertexShader: /*glsl*/ `
        attribute float aIndex; // 内部属性 浮点 当前序号

        uniform float uTime; // 全局变量 浮点 当前时间

        uniform float uWidth; // 全局变量 浮点 线段宽度

        uniform vec3 uColor; // 全局变量 颜色 设置的颜色

        varying float vSize; // 片元变量(需要传递到片面着色器) 浮点 尺寸

        uniform float uLength; // 全局变量 浮点 线段长度

        void main(){
            vec4 viewPosition = viewMatrix * modelMatrix * vec4(position,1);

            gl_Position = projectionMatrix * viewPosition; // 顶点矩阵变换 设置各个点的位置

            // 当前顶点的位置处于线段长度内 则设置水滴大小
            if(aIndex >= uTime - uLength && aIndex < uTime){
              // 水滴大小根据当前位置慢慢变小
              // p1 uWidth越大水滴越粗
              // vSize = uWidth * ((aIndex - uTime + uLength) / uLength);
              // p2 uWidth越大水滴越细
              vSize = (aIndex + uLength - uTime) / uWidth;
            }
            gl_PointSize = vSize;
        }
      `,
    fragmentShader: /*glsl*/ `
        varying float vSize;
        uniform vec3 uColor;
        void main(){
            // 透明度根据当前大小确定是否展示
            if(vSize<=0.0){
              gl_FragColor = vec4(1,0,0,0);
            }else{
              gl_FragColor = vec4(uColor,1);
            }
        }
      `,
    transparent: true,
    vertexColors: false,
  });
}

// 创建bufferGeometry
function createBufferGeometry(points) {
  const indexList = points.map((_, index) => index);
  const bufferGeometry = new BufferGeometry().setFromPoints(points);
  // 给几何体添加自定义的索引标识 用来后续根据索引设置点的透明度
  bufferGeometry.setAttribute(
      "aIndex",
      new THREE.Float32BufferAttribute(indexList, 1)
  );
  return bufferGeometry;
}
[
  {
    "from": [
      104.065735,
      30.659462
    ],
    "to": [
      116.405285,
      39.904989
    ],
    "color": "#00fbff"
  },
  {
    "from": [
      104.065735,
      30.659462
    ],
    "to": [
      121.472644,
      31.231706
    ],
    "color": "#ff0004"
  },
  {
    "from": [
      104.065735,
      30.659462
    ],
    "to": [
      87.617733,
      43.792818
    ],
    "color": "#d8ff94"
  },
  {
    "from": [
      104.065735,
      30.659462
    ],
    "to": [
      121.509062,
      25.044332
    ],
    "color": "#08c9ff"
  },
  {
    "from": [
      104.065735,
      30.659462
    ],
    "to": [
      112.982279,
      28.19409
    ],
    "color": "#ff00ee"
  }
]

下一篇:

Threejs 实现3D 地图(07)3d 地图 完结-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0softmax和背后的最大熵(极大似然法)

只要无穷阶矩都一样&#xff0c;那么两个分布一定一样。 整理思路&#xff1a;1、设定样本的概率模型与目标概率模型一致&#xff08;两个模型特性函数一致&#xff09;建立服从伯努利分布的变量&#xff08;此处需要理解样本空间及变量的关系&#xff09;对两个模型进行降维&a…

Could not retrieve mirrorlist http://mirrorlist.centos.org错误解决方法

文章目录 背景解决方法 背景 今天在一台新服务器上安装nginx&#xff0c;在这个过程中需要安装相关依赖&#xff0c;在使用yum install命令时&#xff0c;发生了以下报错内容&#xff1a; Could not retrieve mirrorlist http://mirrorlist.centos.org/?release7&archx8…

HarmonyOS 相对布局(RelativeContainer)

1. HarmonyOS 相对布局&#xff08;RelativeContainer&#xff09; 文档中心:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-layout-development-relative-layout-V5   RelativeContainer为采用相对布局的容器&#xff0c;支持容器内部的子元素设…

ssh服务器相关实验

相关命令 下载软件 yum install openssh-server 查看公私钥 ll /etc/ssh/ 查看配置文件 rpm -qf /etc/ssh/sshd_config 修改ssh端口号&#xff08;改成2222&#xff09; vim /etc/ssh/sshd_config 拒绝root用户远程登录 进入配置文件所在文件夹 cd /etc/ssh/sshd_config.d/ 进…

ionic Capacitor 生成 Android 应用

官方文档 https://ionic.nodejs.cn/developing/android/ https://capacitorjs.com/docs/getting-started 1、创建新的 Capacitor 应用程序 空目录下面 npm init capacitor/app2、install Capacitor npm install npm start在这里插入图片描述 3、生成dist目录 npm run buil…

【ArcGIS Pro实操第5期】全局及局部空间插值:GPI、LPI、IDW等

ArcGIS Pro实操第5期&#xff1a;全局及局部空间插值 ArcGIS Pro-用于空间插值的丰富工具箱实操&#xff1a;空间插值方法1&#xff1a;Trend Surface Model for Interpolation-以降水数据为例方法2&#xff1a;Kernel Density Estimation Method-以单位面积鹿的目击数为例方法…

用接地气的例子趣谈 WWDC 24 全新的 Swift Testing 入门(一)

概述 从 WWDC 24 开始&#xff0c;苹果推出了全新的测试机制&#xff1a;Swift Testing。利用它我们可以大幅度简化之前“老态龙钟”的 XCTest 编码范式&#xff0c;并且使得单元测试更加灵动自由&#xff0c;更符合 Swift 语言的优雅品味。 在这里我们会和大家一起初涉并领略…

基于SSM美容院管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;套餐类型管理&#xff0c;美容预约管理&#xff0c;生日提醒管理&#xff0c;管理员管理&#xff0c;系统管理 员工账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#…

普推知产:申请商标名称从4字改成3字下了初审!

近日7月的时候普推知产老杨帮客户申请的水果猕猴桃31类商标&#xff0c;初步审定公告下来了&#xff0c;基本没什么问题三个月公告结束后一个月内就可以拿到商标注册证&#xff0c;客户所在地全国有名猕猴桃之县&#xff0c;同质化竞争还得需要商标才可以。 刚开始了解到这位做…

Three.js遮罩多场景穿梭过渡

仓库 思路&#xff1a; 渲染一个遮罩 亮的区域为需要显示另一个场景的区域 在靠近门时完全渲染一个场景 在穿过门的同时切换场景关系 if (this.Doors.length) {// 材质变为黑色 除了“门”toggleRoughnessMaterial("black");// 设置RenderTarget保存结果renderer.se…

【Linux系统】为什么环境变量具有全局性?共享?写时拷贝优化?

环境变量表具有全局性的原因&#xff1a; 环境变量表之所以具有全局性的特征&#xff0c;主要是因为它们是在进程上下文中维护的&#xff0c;并且在大多数操作系统中&#xff0c;当一个进程创建另一个进程&#xff08;即父进程创建子进程&#xff09;时&#xff0c;子进程会继承…

网站建设前需要搞清楚哪些问题

网站建设前需要搞清楚的问题涉及多个方面&#xff0c;以下是一些关键问题的概述&#xff1a; 明确目标和目的 企业宣传与品牌塑造&#xff1a;网站是企业展示形象、传播品牌的重要窗口。通过精心设计的网站界面和内容布局&#xff0c;可以向潜在客户传递企业的价值观、文化理念…

iOS AVAudioSession 详解【音乐播放器的配置】

前言 在 iOS 音频开发中&#xff0c;AVAudioSession 是至关重要的工具&#xff0c;它控制着应用的音频行为&#xff0c;包括播放、录音、后台支持和音频中断处理等。对于音乐播放器等音频需求强烈的应用&#xff0c;设计一个合理的 AVAudioSession 管理体系不仅能保证音频播放…

[JAVAEE] 多线程的案例(三) - 线程池

目录 一. 什么是线程池 二. 线程池的作用 三. java提供的线程池类 四. ThreadPoolExecutor的构造方法及参数理解 1. int corePoolSize: 核心线程数. 2. int maximumPoolSize: 最大线程数 核心线程数 非核心线程数 3. int keepAliveTime:非核心线程允许空闲的最大时间. …

网络通信与并发编程(六)线程、进程池与线程池

线程、进程池与线程池 文章目录 线程、进程池与线程池一、线程二、线程的相关操作2.1创建线程的两种方式2.2线程的其他操作2.3死锁现象和递归锁2.4条件2.5定时器2.6 队列与堆栈 三、进程池与线程池 一、线程 线程是指cpu上实际执行计算的单位&#xff0c;而进程是将计算所需资…

Leetcode刷题笔记12

HJ1 字符串最后一个单词的长度 字符串最后一个单词的长度_牛客题霸_牛客网 这里可以使用rfind()&#xff0c;rfind()函数从字符串的末尾向前查找第一个空格的位置。这个空格将是最后一个单词和前面的单词的分隔符。首先使用getline读取字符串&#xff0c;然后用rfind找到最后一…

class 36 二叉树高频题目 - 上 (不含有树形dp)

1. BFS 的两种方式 如下图, 是一个二叉树. 我们需要按照层的方式来遍历这棵树. 1.1 使用 JDK 自带的类实现(链表实现, 经典 BFS) 首先我们实现一个队列, 这个队列从头进, 从尾出.然后将根节点放入其中, 然后将放入的节点弹出,然后继续验证弹出的节点有没有左孩子, 若是有, 将…

便捷之选:微信小程序驱动的停车场管理系统

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

跨境支付,哪些国产数据库能接得住?

最近有一个非常重大的事件&#xff0c;那就是10月22日-24日的金砖国家会议。金砖国家领导人第十六次会晤是金砖国家进一步凝聚共识、以实际行动推动“全球南方”共同发展进步的重要机遇。 酝酿已久的金砖跨境支付体系&#xff0c;也在这次峰会中正式推出。金砖国家的支付系统一…

国内大语言模型哪家更好用?

大家好&#xff0c;我是袁庭新。 过去一年&#xff0c;AI大语言模型在爆发式增长&#xff0c;呈现百家争鸣之态。国内外相关厂商积极布局&#xff0c;并相继推出自家研发的智能化产品。 我在工作中已习惯借助AI来辅助完成些编码、创作、文生图等任务&#xff0c;甚至对它们产…