数字孪生下的孪生风机,前端技术介绍

数字孪生技术(前端实现) 而 three.js 作为使用WebGL技术开发的三维引擎,较好的封装了WebGL提供的接口,隐藏了WebGL的基本图像渲染细节,极大的节省了学习成本,使用者可以简单快捷的操作使用。LOD(Level of Detail)是Charknl为了提高图像实时绘制的速度提出[⒅,LOD是通过对层次化细节的处理,来补偿损失的硬件性能,在用户察觉不到效果损失的前提下,可以提高实时显示系统的帧率。模拟不同产品细节部件,不同部件参数,在不同条件下的生产活动过程,避免错误选择,提高产品参数配置的准确性; 阅读详情

 

上一篇文章我们介绍了数字孪生,和该技术下孪生风机的诸多优点。本篇文章向大家介绍下孪生风机用了哪些前端技术?前端效果是如何实现的?

一、Canvas
简介
在web中,实现2D基本图形及动画效果,首先会想到使用canvas。例如上图,实现一个可以实时显示风向角变化的效果图。canvas非常灵活,能够很好地融合JavaScript代码并在浏览器内绘制华丽的图形,拥有多种绘制路径、形状、字符以及添加图像等方法。
面对各种复杂的图形及效果,我们可以采用canvas框架,例如Konva,它可以轻松的实现桌面应用和移动应用中的图形交互交互效果,可以高效的实现动画,变换, 节点嵌套, 局部操作,滤镜,缓存,事件等功能,不仅仅适用于桌面与移动开发, 还有更为广泛的应用。

实现
在实现动画实时变化效果时,如果每次风向发生改变,都需要重绘图形,效果显示难免有些单调。重新绘图的变化过程称为突变动画。

 


我们需要的是平滑的过渡效果,例如,风向角在上一时刻是36.89度,下一时刻是76.84度。动画效果由36.89度渐变到76.84度的平滑效果。


为避免突变动画的情况,我们需要在componentWillUpdate中监听角度参数rotation的变化,当有新的角度参数传入的时候,需要重新绘制图形并将新的参数传入。

代码如下:

componentWillUpdate(nextProps) {
    if (nextProps.rotation !== this.props.rotation) {
      this.layer.destroy()
      this.tween.destroy()
      this.drawWind(nextProps)
    }
  }
//旋转部分初始角度赋值为当前rotation。
 let lineGroup = new Konva.Group({
      x:radius,
      y:radius,
      rotation: this.props.rotation,
      //未变化时采用this.props值。动画处用nextProps
    })

//动画部分旋转角度赋值为新的rotation。
    this.tween = new Konva.Tween({
      node: lineGroup,
      easing: Konva.Easings.Linear,
      duration: 0.5,
      rotation: nextProps.rotation ? nextProps.rotation : nextProps.rotation === 0 ? 0 : this.props.rotation,
      onFinish: () => {
        this.tween.destroy()
      }
    });``

实现
风机模型加载完毕后,当鼠标移动到风机各个零部件时,所选部件增加线框以表示为选中状态。如果在此之前有选中其它部件,需移除其它部件的选中状态。当鼠标移出该部件的时候,将其线框移除。

 

代码如下:监听鼠标事件的onMouseMove。

// 鼠标移入事件
    this.mouseMove = (event) => {
      //点击射线
      let raycaster = new THREE.Raycaster();
      // ⚠️⚠️⚠️ 注意此处的mouse必须设置,这样下面才能判断当前选中模型Group的单个组员
      let mouse = new THREE.Vector2();
      //将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,具体解释见代码释义
      mouse.x = (event.offsetX / width) * 2 - 1;
      mouse.y = -(event.offsetY / height) * 2 + 1;
      //新建一个三维单位向量 假设z方向就是1 
      //根据照相机,把这个向量转换到视点坐标系
      let vector = new THREE.Vector3(mouse.x, mouse.y, 1).unproject(camera)
      //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
      raycaster.setFromCamera(mouse, camera);
      //在视点坐标系中形成射线,射线的起点向量是照相机, 射线的方向向量是照相机到点击的点,这个向量应该归一标准化。
      raycaster.set(camera.position, vector.sub(camera.position).normalize())
      //射线和模型求交,选中一系列直线
      // 存放旋转部分点击
      let intersectsFlabellum = raycaster.intersectObjects(flabellum.children, true)
      // 存放旋转部分之外的点击
      let intersectsObject = raycaster.intersectObjects(this.object.children, true)
      if (intersectsFlabellum.length && !intersectsObject.length) {
        if (intersectsFlabellum[0].object.name === '扇叶' && intersectsFlabellum.length < 3) {
          if (this.state.mouseOver !== '扇叶') {
            this.setState({ mouseOver: '扇叶' })
            this.scene.remove(hubLineGroup)
          }
        } else if (intersectsFlabellum[0].object.name === '轮毂') {
          if (this.state.mouseOver !== '轮毂') {
            this.setState({ mouseOver: '轮毂' })
            this.scene.add(hubLineGroup)
          }
        } else {
          this.scene.remove(hubLineGroup)
          if (!this.state.mouseSelect) {
            this.setState({ mouseOver: '', control: true })
          } else {
            this.setState({ mouseOver: '' })
          }
        }
      } else {
        this.scene.remove(hubLineGroup)
      }
      
       if (intersectsObject.length) {
        this.scene.remove(pitchGroup)
        this.scene.remove(hubLineGroup)
        if (intersectsObject[0].object.name === '主轴') {
          if (this.state.mouseOver !== '主轴') {
            this.setState({ mouseOver: '主轴' })
            this.scene.add(mainAxleGroup)
            this.scene.remove(gearGroup)
            this.scene.remove(powerGroup)
          }
        } else if (intersectsObject[0].object.name === '齿轮结构') {
          if (this.state.mouseOver !== '齿轮结构') {
            this.setState({ mouseOver: '齿轮结构' })
            this.scene.add(gearGroup)
            this.scene.remove(mainAxleGroup)
            this.scene.remove(powerGroup)
          }
        } else if (intersectsObject[0].object.name === '发电机箱') {
          if (this.state.mouseOver !== '发电机箱') {
            this.setState({ mouseOver: '发电机箱' })
            this.scene.add(powerGroup)
            this.scene.remove(mainAxleGroup)
            this.scene.remove(gearGroup)
          }
        } else {
          if (!this.state.mouseSelect) {
            this.setState({ mouseOver: '', control: true })
          } else {
            this.setState({ mouseOver: '' })
          }
          this.scene.remove(mainAxleGroup)
          this.scene.remove(gearGroup)
          this.scene.remove(powerGroup)
        }
      } else {
        this.scene.remove(mainAxleGroup)
        this.scene.remove(gearGroup)
        this.scene.remove(powerGroup)
      }
      
            if (!intersectsObject.length && !intersectsFlabellum.length) {
        if (!this.state.mouseSelect) {
          this.setState({ mouseOver: '', control: true })
        } else {
          this.setState({ mouseOver: '' })
        }
      }
    }

 

代码如下:监听鼠标事件onClick。

 // 点击事件  
    this.clickEvent = (event) => {
      // 点击扇叶停止动画。点击扇叶并且下一次不点击扇叶开始动画。
      if (this.state.isClickLeaf) {
        this.setState({ isClickLeaf: false })
        this.animate()
      }
      if (this.state.mouseOver) {
        if (this.state.mouseOver === '扇叶') {
          cancelAnimationFrame(this.animateId)
          $('.popup').css({
            left: event.offsetX,
            top: event.offsetY - $('.popup').height(),
          })
        } else if (this.state.mouseOver === '轮毂') {
          $('.popup').css({
            left: event.offsetX,
            top: event.offsetY - $('.popup').height(),
          })
        } else if (this.state.mouseOver === '主轴') {
          $('.popup').css({
            left: event.offsetX,
            top: event.offsetY - $('.popup').height(),
          })
        } else if (this.state.mouseOver === '齿轮结构') {
          this.setState({ mouseSelect: '齿轮结构', control: true })
        } else if (this.state.mouseOver === '发电机箱') {
          this.setState({ mouseSelect: '发电机', control: true })
        } else if (this.state.mouseOver === '偏航系统') {
          this.setState({ mouseSelect: '偏航系统', control: true })
        }
      } else {
        if (this.state.mouseSelect !== '齿轮结构' && this.state.mouseSelect !== '偏航系统' && this.state.mouseSelect !== '发电机') {
          this.setState({ mouseSelect: '', control: true })
        }
      }
    }
 

 结束语
web页面因Canvas和Three.js在2D和3D方面的支持变得丰富多彩,妙趣横生。生动丰富的数据展示,方便了我们对风机的数据的实时监测。
至此,本文和本系列文章已经告一段落了,希望可以帮助读者更加了解我们的孪生风机。有任何问题,欢迎联系我们!关注一下,下次找我不迷路!如果觉得文章有可取之处,还请多多点赞!
 

web版的数字孪生,选择three.js、unity3D、还是UE4 在上述对比中,我们提到了three.js适合轻量级的数字孪生开发。资源消耗低:轻量级的数字孪生开发意味着使用的库或框架的资源消耗较低,不会占用过多的内存和计算资源。对于数字孪生应用来说,保持较低的资源消耗可以提高应用的性能和响应速度。易于学习和使用:轻量级的数字孪生开发工具应该具备简单易学的API和文档,降低学习和上手的门槛。对于前端开发者来说,能够快速上手并迅速实现数字孪生效果是一个重要的考虑因素。灵活性和可扩展性:轻量级的数字孪生开发工具应该具备灵活性,允许开发者根据项目需求进行定制和扩展。 阅读详情

相关推荐

关于数字孪生,你了解多少?成品孪生风机的酷炫,欣赏一下~

一、数字孪生 背景 在2002年,密歇根大学的Dr. Michael Grieves教授首次提出Digital Twin(数字孪生)技术概念,就是通过一个数字模型来监控物体的实时状态。由于当时的数字化技术水平比较低,该技术没有深入发展。随着3D建模技术、大数据技术等技术的提升,2014年Digital Twin这个概念又重新回到了人们的视线里。 简单来说,数字孪生就是对真实存在的物理系统的一个虚拟...

weixin_46452233的博客 2602

数字孪生——thing.js和three.js

本文讲了thing.js和three.js的对比及它们的应用

smile_hahahaxixi的博客 7393

数字孪生与智能体融合:智慧电力从可视化到自主决策的演进与实践

数字孪生技术通过构建物理实体的虚拟映射,实现了对复杂系统状态的高保真刻画与实时监控,其核心价值在于为数据驱动决策提供了直观的“战场沙盘”。随着人工智能技术的演进,智能体(Agent)作为具备感知、决策与执行能力的自治程序,为数字孪生注入了“大脑”,使其从静态呈现跃升至动态分析与自主干预。这种融合技术在工程实践中,通过集成规则引擎、机器学习模型与大语言模型(LLM),能够有效应对电网调度、设备运维等场景中海量、多源数据的处理与复杂决策挑战。其最终技术价值体现在推动电力系统从被动响应转向主动预警与优化,实现源网

weixin_34293141的博客 1858

【白话前端】数字孪生(桌面端)的常用技术栈和软件:极简版

声明:配图大部分为web端,你可以想象为桌面端,桌面端配图不好找,请谅解。游戏行业和非公开的行业,桌面端应用的非常多,性能比web端有优越很多。数字孪生不是一个人可以搞定的,再牛逼的人也不行。

2401_82881178的博客 1290

智慧交通|视频孪生智慧隧道解决方案

视频孪生智慧隧道综合管控平台,以三维孪生技术为基础,融合隧道车辆对象级感知数据、基础设施设备数据、环境等动静态数据,打造智慧隧道驾驶舱,支持隧道态势实时感知

数字孪生之视频孪生 1091

数字孪生实战:如何用Unity3D为工厂设备快速搭建可视化孪生体(附GitHub源码)

本文详细介绍了如何利用Unity3D游戏引擎为工厂设备快速构建可视化数字孪生体。通过实战案例,阐述了从3D模型导入、MQTT实时数据接入,到振动、温度等关键参数可视化呈现的完整流程。文章旨在为智能制造和工业物联网开发者提供一套灵活、低成本的技术方案,并附有完整的GitHub源码,助力实现设备状态的直观监控与预测性维护。

weixin_29184075的博客 471

canvas绘制竖排的数字_数字孪生下的孪生风机,前端技术介绍

孪生风机上一篇文章我们介绍了数字孪生,和该技术下孪生风机的诸多优点。本篇文章向大家介绍下孪生风机用了哪些前端技术?前端效果是如何实现的?一、Canvas简介在web中,实现2D基本图形及动画效果,首先会想到使用canvas。例如上图,实现一个可以实时显示风向角变化的效果图。canvas非常灵活,能够很好地融合JavaScript代码并在浏览器内绘制华丽的图形,拥有多种绘制路径、形状、字符以及添加图...

weixin_36109676的博客 392

Babylon.js与Unity3D在数字孪生中的技术选型深度对比

在Web3D和实时渲染领域,技术选型是项目成功的关键。WebGL和WebGPU等现代Web API为浏览器带来了强大的3D图形能力,而成熟的游戏引擎则为复杂仿真提供了坚实基础。从技术原理上看,Web原生框架通过JavaScript/TypeScript直接驱动浏览器渲染,实现了极致的可访问性和部署便捷性;而全平台引擎则通过底层编译和优化,提供了更高的性能上限和视觉保真度。在数字孪生应用中,这两种技术路线的价值体现在不同的场景:轻量级、需要广泛传播和快速迭代的可视化项目,往往更适合采用Babylon.js这类

weixin_28683391的博客 247

数字孪生在UI前端的应用:从理论到实践

数字孪生不是炫技,而是通过可视化将复杂世界简化为可操作的决策界面。随着WebGPU、WebAssembly等技术的成熟,前端开发者正站在物理与数字世界融合的最前沿——这不仅是技术的进化,更是人类认知世界的革命性跃迁。当物理世界的设备在屏幕中实时“呼吸”,当城市脉搏以前所未有的方式在浏览器中跳动——数字孪生正在重塑UI前端的边界。本文揭秘如何将工业级数字孪生技术落地前端界面,实现物理与数字世界的无缝对话。二、前端技术栈革命:数字孪生专用架构。一、数字孪生:物理世界的数字镜像。动态三维模型:高保真可交互对象。

assj666的博客 508

数字孪生落地核心:数据契约、三层架构与时间同步

数字孪生并非简单的3D可视化或IoT数据看板,而是一种具备实时感知、动态建模与闭环反馈能力的虚拟-物理融合系统。其技术本质在于高保真数据流驱动下的机理模型演化,关键支撑包括毫秒级时间同步、可验证的数据契约机制,以及从影子孪生到替身孪生的递进式能力跃迁。在制造业设备预测性维护、能源系统仿真优化、智慧城市多源协同等场景中,真正决定成败的不是渲染效果,而是传感器原始采样精度、边缘时序对齐能力与灰箱建模水平。本文聚焦数字孪生工程化落地中最易被忽视的底层逻辑——数据源头定义、时间基准统一与模型可解释性设计。

diejiankuai3444的博客 425

UE5数字孪生项目实战:集成WebUI插件与Vue/React前端框架

在现代软件开发中,前后端分离与模块化是提升开发效率和系统可维护性的核心架构思想。其原理在于将用户界面(UI)逻辑与业务逻辑、数据逻辑解耦,通过定义清晰的接口进行通信。这种分工协作模式的技术价值在于,允许前端与后端团队使用各自最擅长的技术栈并行开发,并能独立迭代与优化。在游戏开发与3D可视化领域,Unreal Engine 5(UE5)以其强大的实时渲染和物理仿真能力,成为构建高保真数字孪生场景的首选。然而,当项目需求扩展到复杂的业务数据展示、动态图表和表单交互时,传统的蓝图和UMG系统在开发效率和样式定制上

weixin_34253126的博客 533

数字孪生-数字孪生在预测性维护方面的应用

设备的稳定运行是企业保持高效生产和确保产品质量的关键。传统的应急维修和计划性维护式的设备维护方式,已难以适应复杂多变的生产需求。应急维修是设备突发故障时进行响应,造成长时间停机和高昂的维修费用;计划性维护通过固定周期的维护策略能预防部分故障,但容易造成资源浪费或维护不足。预测性维护通过实时监测和数据分析的应用,提前了解设备健康状态,精准定位潜在故障,从而实现在设备发生故障前进行精准修复。预测性维护最大限度减少对设备对生产的影响,实现设备维护成本与效益的平衡。

qq_40821260的博客 1329

从AAAI 2025被拒到ACM MM 2025录用:我的论文投稿经验与教训总结

本文分享了作者从AAAI 2025被拒到ACM MM 2025录用的论文投稿经验与教训。详细解析了格式要求、可复现性清单等关键细节,提供了精准转投策略和提升录用概率的实用技巧,帮助研究者避免常见错误并优化投稿策略。

weixin_29207533的博客 502

数字孪生对于新基建的价值浅析,算是抛砖引玉。

数字孪生(Digital Twin)作为一项融合物理世界与数字世界的关键技术,在新基建中扮演着的核心角色,其价值贯穿于基础设施的设计、建设、运维到优化全流程。

2401_87844866的博客 1365

Zynq7020实战:ARM Cortex-A9降频避坑指南(附温度对比测试)

本文详细介绍了如何在Zynq7020平台上对ARM Cortex-A9处理器进行降频优化,以降低功耗并提升系统稳定性。通过分析时钟架构、提供实战操作步骤和温度对比测试数据,帮助开发者有效避免降频过程中的常见问题,实现嵌入式系统的高效能耗管理。

root9的博客 205

ROS-Industrial :simple_message

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录1. 概述2. 协议(Protocol)3. HEADER解析3.1 MSG_TYPE3.2 COMM_TYPE3.3 REPLY CODE 1. 概述 Simple_Message是ROS-Industrial的一部分,定义了用于与工业机器人控制器通信的简单消息连接协议。另外还包括处理连接受限系统的处理器和管理器类。 2. 协议(Protocol) 简单消息(simplemessage)协议定义了ROS的驱动层和机器人控制器之.

flsxyw的博客 780

数字孪生IOC开发:端渲染与流渲染融合的场景适配论

在数字孪生与智慧城市领域,智能运营中心(IOC)大屏的可视化呈现是核心需求,它直接关系到决策效率与用户体验。其背后的关键技术路径,主要围绕**端渲染**与**流渲染**两大范式展开。端渲染在本地客户端完成全部计算,能提供极致的视觉保真度与交互响应,常用于对画质和性能要求极高的汇报演示场景;而流渲染则将繁重的渲染任务放在云端,客户端仅接收视频流,实现了轻量化访问与跨平台分发,更适用于需要快速迭代和广泛接入的常态运营。这两种技术各有优劣,其融合的价值在于,能够根据不同的业务场景灵活调配资源,实现效果与效率的平衡

weixin_34101229的博客 309

【JESD79-5之】8 AC & DC 输入测量标准(AC & DC Input Measurement Levels)

时钟被驱动到DRAM,可以通过L/RDIMM模块的RCD来实现,也可以通过U/SODIMM模块的主机来实现(图184)。接收机DQS(脉冲)输入电压灵敏度测试提供了在没有码间干扰(ISI),抖动(Rj, Dj, DCD)和串扰噪声的情况下测试接收机对不同输入电压的灵敏度的方法。接收机数据输入电压灵敏度测试提供了在没有符号间干扰(ISI),抖动(Rj, Dj, DCD)和串扰噪声的情况下测试接收机对不同输入电压的灵敏度的方法。

m0_61126667的博客 1703

数字孪生与智慧检测技术如何革新建筑门窗实训教学

数字孪生技术通过构建物理实体的虚拟映射,实现了对复杂系统的实时监控、仿真与预测。其核心原理在于数据驱动与模型融合,通过物联网、三维建模与仿真算法,将物理世界的状态、行为和规则在数字空间中复现。这项技术在工业制造、智慧城市等领域展现出巨大价值,能够优化流程、预测风险并降低实体操作成本。在工程教育领域,数字孪生与智慧检测技术相结合,为解决传统实训中设备昂贵、操作危险、过程抽象等痛点提供了创新方案。例如,在建筑门窗物理性能检测教学中,平台通过虚实结合的方式,让学生能在安全的虚拟环境中深入理解气密性、水密性等检测原

392

Leads、SDR、MQL、SQL、L2C术语概念,线索创建与清洗、线索分级模型、线索流转策略、线索的统计与分析

CRM中的“Leads”是什么?笔者在文中不仅较为全面地介绍了相关术语概念,还分析了线索的创建与清洗、线索的分级模型、线索流转策略以及线索的统计与分析。

盼盼学士 5954

YOLOv13涨点改进| CVPR 2026 |独家创新首发、主干改进篇 |利用RIS-PiDiNet主干让YOLOv13更加强大!适合遥感目标检测、小目标检测、旋转目标检测,变化检测,图像分割涨点

🔥本文提出了一种改进的RIS-PiDiNet主干网络,通过引入几何先验构建几何一致性检测器,显著提升了模型在任意方向、结构规则目标场景下的检测性能。包含两个核心模块:S-PDC利用极谐变换的谐波核建模目标结构对称性,RIS-PDC通过SO(2)群平均实现旋转不变性。网络采用基于RIS-block的主干结构并融合轻量级LBP特征,增强了细粒度结构表达能力。实验表明,该方法特别适用于遥感和复杂几何分布场景,能有效提升目标检测的鲁棒性和精度。文章还详细介绍了如何将RIS-PiDiNet集成到YOLOv13框架

Ai缝合怪、助力小伙伴高效发论文 90

全开源数字孪生系统搭建方案:全套技术文档

本文介绍了一套全开源、零商用授权的数字孪生系统搭建方案,覆盖从三维建模到Web端渲染的全流程技术栈。方案包含七大核心模块:三维建模(Blender、QGIS、IfcOpenShell)、数据传输、数据存储与仿真、Web3D渲染引擎、前端可视化及容器化部署。重点推荐Blender作为通用建模工具,QGIS处理地理信息数据,IfcOpenShell解析BIM模型。整套方案采用Vue3、Three.js、ECharts等技术,支持MQTT物联网协议和Docker部署,适用于智慧园区、工业产线等场景,具有零成本、可

深耕 Java 后端与企业级软件架构设计,专注微服务、分布式系统、大模型 AI 应用架构落地。 1177

踩遍Windows所有坑:Codex CLI桌面端+命令行双环境安装避坑实战

Windows下装Codex CLI的坑,本质上都是Windows本身的路径、环境变量、权限、编码这些历史遗留问题,和工具本身关系不大。只要避开中文路径、正确配置PATH、注意终端环境差异,其实安装非常简单。这套双环境方案配好之后,桌面端适合可视化调试、多会话管理,终端适合嵌入编辑器、脚本调用,一套配置两边通用,体验还是很流畅的。按照上面的流程走,基本不会出大问题,就算出问题也能在排查表里找到对应解法。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 297
上一篇: 数字孪生技术(前端实现)
下一篇: 数字孪生技术栈:不可不说的传感器知识(干货)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端开发程序员2010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值