SVGRenderer 是 three.js 中的一个渲染器,用于将 3D 场景渲染到 SVG(可缩放矢量图形)元素中。

demo案例

SVGRendererthree.js 中的一个渲染器,用于将 3D 场景渲染到 SVG(可缩放矢量图形)元素中。虽然 SVG 本身不支持 3D 渲染,但 SVGRenderer 提供了一种将 three.js 的 3D 场景以 2D 形式投影到 SVG 平面的方法。这种渲染方式通常用于创建一些特定的视觉效果或用于支持 SVG 的环境。

属性

SVGRenderer 的一些主要属性可能包括:

  • domElement: 返回一个 SVG DOM 元素,这是渲染器渲染其输出的地方。
  • context: 访问底层的 SVG 渲染上下文。
  • size: 获取或设置渲染器输出的宽度和高度。
  • autoClear: 控制是否在每次渲染前自动清除画布。
  • gammaInput: 控制是否使用 gamma 输入。
  • gammaOutput: 控制是否使用 gamma 输出。

方法

SVGRenderer 的一些主要方法可能包括:

  • render(scene, camera): 渲染场景和相机到 SVG 元素。
    • scene: 要渲染的 three.js 场景对象。
    • camera: 用于渲染场景的相机对象。
  • setSize(width, height): 设置渲染器输出的宽度和高度。
    • width: 新的宽度值。
    • height: 新的高度值。
  • setClearColor(color, opacity): 设置清除画布时使用的颜色和透明度。
    • color: 清除颜色,可以是十六进制值或颜色对象。
    • opacity: 颜色的透明度。
  • clear(): 清除渲染器的输出。

入参与出参

入参(输入参数)和出参(输出参数)通常是针对方法的。例如,在 render 方法中:

  • 入参:scene(要渲染的场景)和 camera(用于渲染的相机)。
  • 出参:此方法通常没有直接的返回值,但它会更新 domElement 中的内容以反映渲染结果。

setSize 方法中:

  • 入参:width(新的宽度值)和 height(新的高度值)。
  • 出参:此方法通常没有直接的返回值,但会更新 domElement 的尺寸。

SVGRenderer 提供了一种将 three.js 的 3D 场景渲染到 SVG 的方式,尽管其功能和性能可能不如 WebGLRenderer(用于将 3D 场景渲染到 WebGL 上下文中)那么强大和高效。

demo 源码

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js svg - lines</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
    <style>
        svg {
            display: block;
        }
    </style>
</head>
<body>

<div id="info">
    <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> svg - lines
</div>

<script type="importmap">
    {
        "imports": {
            "three": "../build/three.module.js",
            "three/addons/": "./jsm/"
        }
    }
</script>

<script type="module">

    import * as THREE from 'three';

    import { SVGRenderer } from 'three/addons/renderers/SVGRenderer.js';

    // 禁用颜色管理
    THREE.ColorManagement.enabled = false;

    let camera, scene, renderer;

    init();
    animate();

    function init() {

        // 初始化相机
        camera = new THREE.PerspectiveCamera( 33, window.innerWidth / window.innerHeight, 0.1, 100 );
        camera.position.z = 10;

        // 初始化场景
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 0, 0, 0 );

        // 创建SVG渲染器
        renderer = new SVGRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );

        //

        // 创建顶点数组
        const vertices = [];
        const divisions = 50;

        // 生成顶点坐标
        for ( let i = 0; i <= divisions; i ++ ) {

            const v = ( i / divisions ) * ( Math.PI * 2 );

            const x = Math.sin( v );
            const z = Math.cos( v );

            vertices.push( x, 0, z );

        }

        // 创建几何体
        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );

        //

        // 创建并添加线条对象
        for ( let i = 1; i <= 3; i ++ ) {

            const material = new THREE.LineBasicMaterial( {
                color: Math.random() * 0xffffff, // 随机颜色
                linewidth: 10
            } );
            const line = new THREE.Line( geometry, material );
            line.scale.setScalar( i / 3 );
            scene.add( line );

        }

        // 创建并添加虚线对象
        const material = new THREE.LineDashedMaterial( {
            color: 'blue', // 蓝色
            linewidth: 1,
            dashSize: 10,
            gapSize: 10
        } );
        const line = new THREE.Line( geometry, material );
        line.scale.setScalar( 2 );
        scene.add( line );

        //

        // 监听窗口大小变化事件
        window.addEventListener( 'resize', onWindowResize );

    }

    function onWindowResize() {

        // 更新相机和渲染器大小
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );

    }

    function animate() {

        let count = 0;
        const time = performance.now() / 1000;

        // 循环遍历场景中的对象,设置旋转
        scene.traverse( function ( child ) {

            child.rotation.x = count + ( time / 3 );
            child.rotation.z = count + ( time / 4 );

            count ++;

        } );

        // 渲染场景
        renderer.render( scene, camera );
        requestAnimationFrame( animate );

    }

</script>
</body>
</html>

本内容来源于小豆包,想要更多内容请跳转小豆包 》

相关推荐
JieE2124 小时前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2125 小时前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
kyriewen8 小时前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
Larcher9 小时前
AI Loop:让AI像人一样自主完成任务的核心机制
javascript·人工智能·设计模式
默_笙9 小时前
🃏 JS 只有 8 种数据类型,但我花了 2 天才搞懂 null 和 undefined 的区别
javascript
jump_jump10 小时前
流式 HTML:从 htmx 片段装配到浏览器原生增量渲染
javascript·性能优化·前端工程化
swipe11 小时前
正则表达式入门到进阶:从表单校验到手写模板引擎
前端·javascript·面试
kyriewen12 小时前
前端错误监控最全指南:捕获 JS 异常、Promise 拒绝、资源加载失败,附上报代码
前端·javascript·监控
大家的林语冰12 小时前
ESLint 近期动态大全,新版本正式发布,antfu 大佬推荐的插件也更新了!
前端·javascript·前端工程化
胡志辉13 小时前
深入浅出 call、apply、bind
前端·javascript·后端