Three.js搭建小米SU7三维汽车实战(6)颜色切换

news2025/7/22 22:11:21

颜色切换
接下来我们来实现懂车帝的颜色切换效果
可以让ai帮我们生成页面结构以及样式,注意changeCarBodyColor这个函数需要我们自己来写

// 创建颜色选择器UI
function createColorSelector() {
  const colors = [
    { name: "深海蓝", hex: "#1A9CB0" },
    { name: "玛瑙红", hex: "#A00039" },
    { name: "橄榄绿", hex: "#6E7555" },
    { name: "雅灰", hex: "#D6D7D9" },
    { name: "紫檀", hex: "#614C63" }
  ];

  const container = document.createElement("div");
  container.className = "color-selector";

  colors.forEach((color, index) => {
    const colorBtn = document.createElement("div");
    colorBtn.className = "color-btn";
    colorBtn.setAttribute("data-color", color.hex);
    colorBtn.style.backgroundColor = color.hex;
    
    // 默认选中第一个
    if (index === 0) {
      colorBtn.classList.add('active');
    }

    // 颜色名称标签
    const colorLabel = document.createElement("div");
    colorLabel.className = "color-label";
    colorLabel.textContent = color.name;
    colorBtn.appendChild(colorLabel);

    container.appendChild(colorBtn);
  });

  // 使用事件委托添加点击事件
  container.addEventListener('click', function(event) {
    // 查找被点击的按钮元素
    let targetBtn = event.target;
    
    // 如果点击的是标签元素,则获取其父元素(按钮)
    if (targetBtn.classList.contains('color-label')) {
      targetBtn = targetBtn.parentElement;
    }
    
    // 确认点击的是按钮元素
    if (targetBtn.classList.contains('color-btn')) {
      // 移除所有按钮的active类
      document.querySelectorAll('.color-btn').forEach(btn => {
        btn.classList.remove('active');
      });
      
      // 为当前按钮添加active类
      targetBtn.classList.add('active');
      
      // 获取颜色值,用于外部实现的功能
      const colorValue = targetBtn.getAttribute('data-color');
      console.log('选中颜色:', colorValue);
      
      // 这里不实现具体功能,由用户自行实现
      changeCarBodyColor(colorValue)
    }
  });

  document.body.appendChild(container);
}
/* 颜色选择器样式 */
.color-selector {
    position: fixed;
    bottom: 60px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 20px;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 500px;
    padding: 0 10px;
    box-sizing: border-box;
}

.color-btn {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    cursor: pointer;
    position: relative;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    flex: 0 0 auto;
}

.color-btn.active {
    transform: scale(1.1);
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    border: 2px solid white;
}

.color-label {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 8px;
    font-size: 12px;
    color: #333;
    white-space: nowrap;
}

接下来我们来实现切换功能,步骤如下
1收集汽车的材质信息
2找到汽车的车身材质,并进行颜色修改
3可以使用tween将颜色的过渡效果实现出来
在加载汽车的时候,就收集到所有的材质信息,并存储到数组中
materials结构,Car_body.004是核心属性

在点击到按钮之后,得到对应的颜色,然后修改材质,我们的车身材质名称为Car_body.004

const changeCarBodyColor=(colorString)=>{
    console.log(materials);
    if(materials.length){
        materials.forEach(m=>{
            if(m.name.includes('Car_body')){
                m.color=new THREE.Color(colorString)
            }
        })
    }
}

我们还可以通过Tweenjs来实现动画效果

import * as TWEEN from '@tweenjs/tween.js'

let tween
const TweenColorChange=(primColor,color)=>{
    return new TWEEN.Tween(primColor)
      .to(color, 600)
      .easing(TWEEN.Easing.Linear.None)
      .start()
}

将changeCarBodyColor修改一下

const changeCarBodyColor=(colorString)=>{
    if(materials.length){
        materials.forEach(m=>{
            if(m.name.includes('Car_body')){
                tween=TweenColorChange(m.color,new THREE.Color(colorString))
                //m.color=new THREE.Color(colorString)
            }
        })
    }
}

在渲染器中进行更新

renderer.setAnimationLoop(() => {
  if(tween){
      tween.update()
  }
  camera.lookAt(0,0,0)
  camera.updateProjectionMatrix();
  renderer.render(scene, camera);
});

** 4.其他优化细节**
我们仔细观察懂车帝的效果,发现其操作方式只能左右旋转小车,并不能上下偏移
我们可以通过设置轨道控制器的属性达成这一点,并且还可以把相机设置到一个合适的位置

camera.position.set(6.031,  1.39,  -5.08);
orbitControl.enablePan = false;
orbitControl.enableZoom = false;
orbitControl.minPolarAngle = (80 * Math.PI) / 180;
orbitControl.maxPolarAngle = (80 * Math.PI) / 180;

最终效果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql慢sql的实际处理方案之一

复习mysql架构图 当大批量慢sql过来,显然就是占用了线程池的链接,然后长久不释放,所以会出现线程池满的问题,致使正常业务sql也全部阻塞,影响整个业务。 AI搜索如下: 可以考虑一种方案: 将线…

4.2.3 Spark SQL 手动指定数据源

在本节实战中,我们学习了如何在Spark SQL中手动指定数据源以及如何使用format()和option()方法。通过案例演示,我们读取了不同格式的数据文件,包括CSV、JSON,并从JDBC数据源读取数据,展示了如何将这些数据转换为DataFr…

【论文解读】CVPR2023 PoseFormerV2:3D人体姿态估计(附论文地址)

论文链接:https://arxiv.org/pdf/2303.17472 源码链接:https://github.com/QitaoZhao/PoseFormerV2 Abstract 本文提出了 PoseFormerV2,通过探索频率域来提高 3D 人体姿态估计的效率和鲁棒性。PoseFormerV2 利用离散余弦变换(DC…

Maven工程演示

软件:idea 一、项目创建 操作截图file -> New -> Projectnextnext -> Name:工程名称;Location:项目路径;项目创建完成;文件夹基本样例:(如果不完整自己创建即可)MANIFEST.MF内容 二、导入依赖 …

uniapp分包配置,uniapp设置subPackages

在使用uniapp开发过程中,由于项目比较大,无法直接上传,需要分包后才可以上传。 步骤: 1、在pages同级目录下创建分包的目录(pages_second),把要分包的文件放到该目录下; 2、在pag…

C++八股 —— 手撕线程池

文章目录 一、背景二、线程池实现1. 任务队列和工作线程2. 构造和析构函数3. 添加任务函数4. 完整代码 三、阻塞队列实现1. 基础队列2. 升级版队列 四、测试代码五、相关问题六、其他实现方式 来自:华为C一面:手撕线程池_哔哩哔哩_bilibili 华为海思&am…

RPA如何支持跨平台和跨浏览器的自动化

RPA,即机器人流程自动化(Robotic Process Automation),正日益成为企业实现业务流程高效自动化的关键技术。在复杂的数字化环境中,跨平台和跨浏览器的自动化需求极为迫切,RPA 通过多种技术手段和策略来满足这…

【笔记】Windows 成功部署 Suna 开源的通用人工智能代理项目部署日志

#工作记录 本地部署运行截图 kortix-ai/suna: Suna - 开源通用 AI 代理 项目概述 Suna 是一个完全开源的 AI 助手,通过自然对话帮助用户轻松完成研究、数据分析等日常任务。它结合了强大的功能和直观的界面,能够理解用户需求并提供结果。其强…

Linux531rsync定时同步 再回忆

rsync定时同步 环境配置 关闭防火墙,selinux systemctl stop firewalld systemctl disable firewall setenforce 0 cat /etc/selinux/configpei SELINUXdisable设置主机名 systemctl set-hostname code systemctl set-hostname backup设置静态IP rsync由于要设…

【KWDB 创作者计划】_探秘浪潮KWDB数据库:从时间索引到前沿技术

探秘浪潮KWDB数据库:从时间索引到前沿技术 文章目录 探秘浪潮KWDB数据库:从时间索引到前沿技术引言1.浪潮KWDB数据库时间索引深度解析1.1时间索引工作原理1.2时间索引创建与管理实践 2.浪潮KWDB数据库前沿产品技术纵览2.1多模融合存储引擎2.2就地计算技术…

安卓逆向篇LSP 模块HOOK 添加技术绕过检测算法解密逻辑验证

前置解释: 0 、 Magisk : 是当前 Android 社区用来获取 root 权限的主流方式开源工具 1 、 LSP 框架: XPosed 框架因只支持安卓 8 及以下,故高版本应使用 MagiskLSPosed 2 、 HOOK 技术: 钩子技术&…

第一节 51单片机概述

目录 一、单片机系统组成 (一)、单片机硬件系统 (二)单片机的软件系统 二、STC89C52单片机 (1)、基本信息 (2)、命名规则 (3)、单片机内部结构图 &am…

Google car key:安全、便捷的汽车解锁新选择

有了兼容的汽车和 Android 手机,Google car key可让您将Android 手机用作车钥匙。您可以通过兼容的 Android 手机锁定、解锁、启动汽车并执行更多功能。但是,Google car key安全吗?它是如何工作的?如果我的手机电池没电了怎么办&a…

720全景展示:VR全景的技术原理及应用

VR720全景展示:技术原理及应用探索 720全景技术,作为当前全球范围内迅速崛起流行的视觉新技术,为用户带来了全新的真实现场感和交互式的体验。凭借全方位、无死角的视觉展示特性,在VR(虚拟现实)领域中得到…

定制一款国密浏览器(13):预置国密根证书到浏览器

由于国密算法没有得到国外的认可,所以 Chromium、Firefox 等浏览器均不支持国密算法。即使我们修改了 Chromium 的源码,增加了国密算法的支持,但还不能在浏览器中正常使用。因为这涉及到证书的信任问题,国密证书都是国内厂商签发的,国密根证书并没有集成到系统和浏览器中。…

PowerBI企业运营分析——线性回归销售预测

PowerBI企业运营分析——线性回归销售预测 欢迎来到Powerbi小课堂,在竞争激烈的市场环境中,企业运营分析平台成为提升竞争力的核心工具。 该平台通过整合多源数据,实现关键指标的实时监控,从而迅速洞察业务动态,精准…

LangFuse:开源LLM工程平台的革新实践

文章目录 一 架构设计与技术栈二 增强型监控能力三 提示词工程支持(新增)四 性能优化实践五 LangFuse部署(docker)和代码集成5.1 LangFuse平台部署5.2 LangFuse代码集成和检测体验 一 架构设计与技术栈 LangFuse采用模块化架构设…

新视角!经济学顶刊QJE用文本分析探究新技术扩散

美国圣路易斯联邦储备银行Aakash Kalyani、美国斯坦福大学与国家经济研究局Nicholas Bloom、英国伦敦商学院Marcela Carvalho和其合作者们共同研究的“The Diffusion of New Technologies(新技术的扩散)”在顶刊The Quarterly Journal of Economics中发表…

5月31日day41打卡

简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化:调整一个批次的分布,常用与图像数据特征图:只有卷积操作输出的才叫特征图调度器:直接修改基础学习率 卷积操作常见流程如下: 1. 输入 → 卷积层 → Batch…

STM32G4 电机外设篇(一) GPIO+UART

目录 一、STM32G4 电机外设篇(一) GPIOUART1 GPIO1.1 STM32CUBEMX 配置以及Keil代码1.2 代码和实验现象 2 UART2.1 STM32CUBEMX 配置以及Keil代码2.2 代码和实验现象 附学习参考网址欢迎大家有问题评论交流 (* ^ ω ^) 一、STM32G4 电机外设篇&#xff0…