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

使用Three.js库创建的简单WebGL应用程序,主要用于展示具有不同透明度和缩放比例的圆环列

上述HTML文档是一个使用Three.js库创建的简单WebGL应用程序,主要用于展示具有不同透明度和缩放比例的圆环列。以下是代码的详细解释:

  1. HTML结构:
    • 文档类型声明为HTML5。
    • <html>标签设置了语言属性为英语(lang="en")。
    • <head>部分包含了文档的标题、字符集设置和视口设置。视口设置确保页面在移动设备上以适当的比例显示,不允许用户缩放。
    • <style>标签内定义了一些基本的CSS样式,主要是去除body的默认边距,并设置canvas元素为块级显示。
  2. JavaScript部分(使用ES6模块):
    • 通过import语句导入了Three.js库及其相关模块,包括OrbitControls用于相机交互。
    • 初始化Three.js的核心组件:
      • 创建一个场景(Scene)。
      • 创建一个透视相机(PerspectiveCamera),其视场角为75度,宽高比根据窗口大小动态计算,近剪裁面为0.1,远剪裁面为1000。
      • 创建一个WebGL渲染器(WebGLRenderer),并设置其大小与窗口大小相匹配,然后将渲染器的DOM元素添加到body中。
    • 创建一个包含四个圆环的数组meshes
      • 每个圆环使用RingGeometry定义,具有不同的透明度和缩放比例。
      • 圆环的材质使用MeshBasicMaterial,并设置颜色、透明度、是否透明以及双面渲染。
      • 将每个创建好的圆环网格对象(Mesh)添加到meshes数组中。
    • 遍历meshes数组,并将每个圆环添加到场景中。
    • 添加光照:
      • 一个环境光(AmbientLight)用于基础照明。
      • 一个聚光灯(SpotLight)用于强调照明效果,位置设置为(10, 10, 10)。
    • 设置相机位置,z轴为50,以便观察场景。
    • 添加OrbitControls以允许用户通过鼠标和键盘交互地移动相机。
    • 定义一个render函数,用于动态改变圆环的透明度和缩放比例。这里有一个逻辑判断,如果透明度降至0以下,则重置为1,并缩放比例重置为(1, 1, 1);否则,逐渐减小透明度和增大缩放比例。
    • 创建一个动画循环animate,使用requestAnimationFrame确保动画平滑,每次循环调用render函数、更新OrbitControls并渲染场景。
    • 添加一个事件监听器,用于处理窗口大小变化时更新相机的宽高比和渲染器的大小。
    • 最后,启动动画循环。
  3. 功能概述:
    • 页面加载时,用户将看到一个包含四个圆环的场景,每个圆环具有不同的透明度和动态变化的缩放比例。
    • 用户可以通过鼠标和键盘使用OrbitControls来旋转、平移和缩放相机,以不同角度观察场景。
    • 随着动画的进行,圆环的透明度和缩放比例将不断变化,创造一种动态效果。

总之,这段代码展示了一个基本的Three.js应用,通过动态改变对象的属性和使用简单的光照来创建一个有趣的视觉效果。

<!DOCTYPE html>
<html lang="en">

<head>
    <title>three.js webgl - particles - columns</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            margin: 0;
        }

        canvas {
            display: block;
        }
    </style>
</head>

<body>

    <script type="module">

        import * as THREE from 'three';
        import { Scene, PerspectiveCamera, WebGLRenderer, AmbientLight, Color, SpotLight } from "three";
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        // 初始化场景、相机和渲染器  
        const scene = new Scene();
        const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        const meshes = [];
        for (let i = 0; i < 4; i++) {
            const geometry = new THREE.RingGeometry(0.9, 1, 64);
            const opacity = 1 - i / 4; // 计算透明度  
            const scale = (16 * i) / 4 + 1; // 计算缩放比例  
            const material = new THREE.MeshBasicMaterial({
                color: 0x3184ae,
                transparent: true,
                opacity: opacity, // 使用计算的透明度  
                side: THREE.DoubleSide
            });
            const mesh = new THREE.Mesh(geometry, material);
            mesh.scale.set(scale, scale, 1);
            meshes.push(mesh);
        }

        // 遍历 meshes 数组,并将每个 mesh 添加到场景中  
        meshes.forEach(mesh => {
            scene.add(mesh);
        });
        //
        // 添加环境光和聚光灯  
        const ambientLight = new AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);

        const spotLight = new SpotLight(0xffffff, 1);
        spotLight.position.set(10, 10, 10);
        scene.add(spotLight);
        /
        // 设置相机位置  
        camera.position.z = 50;

        // 添加OrbitControls以便交互  
        const controls = new OrbitControls(camera, renderer.domElement);

        const render = () => {
            meshes.forEach((mesh, index) => {
                const meterial = mesh.material;
                if (meterial.opacity <= 0) {
                    meterial.opacity = 1;
                    mesh.scale.set(1, 1, 1);
                } else { meterial.opacity -= 0.002; mesh.scale.set(mesh.scale.x + 0.038, mesh.scale.y + 0.038, 1); }
            });
        };

        // 创建动画循环  
        const animate = function () {
            requestAnimationFrame(animate);
            render();
            controls.update(); // 更新OrbitControls  
            renderer.render(scene, camera);
        };

        // 处理窗口大小调整  
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        // 开始动画循环  
        animate();

    </script>
</body>

</html>


http://www.kler.cn/news/337668.html

相关文章:

  • 香橙派如何连接网络,及wiringOP库
  • 如何利用免费工具轻松设计出专业Logo?
  • Python数据分析工具:Statsmodels的用法示例
  • (九)Shell 脚本(四):正则表达式、sed 和 awk 详解
  • 极显然:百年极限论是模糊不清的理论
  • 使用Spring Security实现用户-权限-资源的精细化控制
  • 个人如何申请书号?
  • 第38讲:Ceph分布式存储集群部署
  • Linux 文件管理
  • 大数据新视界 --大数据大厂之 Kafka 性能优化的进阶之道:应对海量数据的高效传输
  • HTTPS介绍 --- 超详细保姆级知识讲解
  • 每日新闻掌握【2024年9月21日 星期六】
  • MyBatis 操作数据库入门
  • 鸿蒙--知乎评论
  • imx6q 的 header.s的理解
  • Redis list 类型
  • 【JVM调优】JVM高频参数和最优实践
  • 超好用的数据库连接工具-DBeaver连接ClickHouse后找不到系统表?
  • agent实现:通过prompt方式实现agent自定义使用
  • Vue3小兔鲜——订单页