代码之家  ›  专栏  ›  技术社区  ›  jamfury

从集合中获取纹理

  •  0
  • jamfury  · 技术社区  · 11 月前

    大家好,正在阅读的人。

    我正试图创建一个网站,在那里我可以用鼠标滚动浏览所有在一行中的“卡片”,从侧面以iso视图查看。

    我已经在THREE.js中设置了场景,但我不知道如何创建一个自动用作卡片纹理的元素集合。

    为了更好地解释,我想:

    • 创建和使用可更新的元素集合(图像/视频)
    • 让所述系列的每个元素都用作盒子正面的纹理
    • 使方框大小自动适应图像纹理的纵横比
    • 不必手动将每个纹理链接到每个框,而是每次在集合中插入新元素时,都会创建一张新卡或框并将其添加到场景中

    如果有人能帮忙,我们将不胜感激。

    提前感谢!

    这是我现在的代码:

    import './style.css'
    import * as THREE from 'three'
    
    // Set up the scene
    const canvas = document.querySelector('.webgl');
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff); // Set background color to white
    
    // Create box geometry
    const boxGeometry = new THREE.BoxGeometry(1, 1, 0.01);
    //Create box material
    const boxMaterial = new THREE.MeshStandardMaterial({
      transparent: true,
      opacity: 0.7
    
    });
    
    const numBoxes = 10; // Boxes number
    const boxSpacing = 1; // Boxes spacing
    
    // Create boxes mesh
    for (let i = 0; i < 10; i++)
    {
      const box = new THREE.Mesh(boxGeometry, boxMaterial);
        box.position.set(0, 0, -i * boxSpacing)  
        scene.add(box);
    }
    
    // Add ambient light to the scene
    const ambientLight = new THREE.AmbientLight(0xffffff, 1); // Soft white light
    scene.add(ambientLight);
    
    // Set up the renderer
    const renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
    renderer.setSize(window.innerWidth, window.innerHeight);
    
    // Set up the camera
    const zoom = 300; // Adjust this value to control the zoom
    const sizes = {
      width: window.innerWidth,
      height: window.innerHeight
    }; // Declares sizes value as window sizes
    
    const aspect = window.innerWidth / window.innerHeight; // Set aspect ratio to the window's
    const camera = new THREE.OrthographicCamera(
      -sizes.width / zoom,
      sizes.width / zoom,
      sizes.height / zoom,
      -sizes.height / zoom,
      -10,
      1000
    );
    
    // const gridHelper = new THREE.GridHelper(100, 100, 0x444444, 0x444444);
    // scene.add(gridHelper);
    
    // Camera controls
    camera.position.set(2, 2, 5);
    camera.lookAt(0, 0, 0)
    
    // Update camera aspect ratio and renderer size when the window is resized
    window.addEventListener('resize', () => {
      // Update sizes
      sizes.width = window.innerWidth;
      sizes.height = window.innerHeight;
    
      // Update camera
      camera.left = -sizes.width / zoom;
      camera.right = sizes.width / zoom;
      camera.top = sizes.height / zoom;
      camera.bottom = -sizes.height / zoom;
      camera.updateProjectionMatrix();
    
      // Update renderer
      renderer.setSize(sizes.width, sizes.height);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });
    
    // Render the scene
    function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
    }
    requestAnimationFrame(animate);
    
    
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="/vite.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Mirko Pratofiorito</title>
      </head>
      <body>
        <div id="app"></div>
        <canvas class="webgl"></canvas>
        <script type="module" src="/main.js"></script>
      </body>
    </html>
    

    我本想尝试一些方法,但不幸的是,我对JS相当陌生,不知道从哪里开始。

    1 回复  |  直到 11 月前
        1
  •  0
  •   GifftyCode    11 月前

    为什么不创建一组图像URL,然后加载纹理,为每个图像创建具有正确纵横比的框,并可能通过定义一个函数来添加新的图像URL和创建具有该纹理的新框,从而添加新元素。该函数加载新纹理,用它创建一个新框,并将URL添加到 imageUrls 收集如下:

    import './style.css';
    import * as THREE from 'three';
    const canvas = document.querySelector('.webgl');
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff); 
    const ambientLight = new THREE.AmbientLight(0xffffff, 1);
    scene.add(ambientLight);
    
    
    const renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    
    const zoom = 300; // Adjust this value to control the zoom
    const sizes = {
      width: window.innerWidth,
      height: window.innerHeight
    }; 
    const aspect = window.innerWidth / window.innerHeight; 
    const camera = new THREE.OrthographicCamera(
      -sizes.width / zoom,
      sizes.width / zoom,
      sizes.height / zoom,
      -sizes.height / zoom,
      -10,
      1000
    );
    
    
    camera.position.set(2, 2, 5);
    camera.lookAt(0, 0, 0);
    
    
    window.addEventListener('resize', () => {
    
      sizes.width = window.innerWidth;
      sizes.height = window.innerHeight;
    
    
      camera.left = -sizes.width / zoom;
      camera.right = sizes.width / zoom;
      camera.top = sizes.height / zoom;
      camera.bottom = -sizes.height / zoom;
      camera.updateProjectionMatrix();
    
    
      renderer.setSize(sizes.width, sizes.height);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    });
    
    
    function createBoxWithTexture(texture, positionZ) {
      const aspect = texture.image.width / texture.image.height;
      const boxGeometry = new THREE.BoxGeometry(1 * aspect, 1, 0.01);
      const boxMaterial = new THREE.MeshStandardMaterial({
        map: texture,
        transparent: true,
        opacity: 0.7
     });
      const box = new THREE.Mesh(boxGeometry, boxMaterial);
      box.position.set(0, 0, -positionZ);
      scene.add(box);
    }
    
    
    const loader = new THREE.TextureLoader();
    const imageUrls = [
      'path/to/image1.jpg',
      'path/to/image2.jpg',
      'path/to/image3.jpg',
    
    ];
    imageUrls.forEach((url, index) => {
      loader.load(url, (texture) => {
        createBoxWithTexture(texture, index * 1.5); 
      });
    });
    
    
    function addNewImage(url) {
      loader.load(url, (texture) => {
        createBoxWithTexture(texture, imageUrls.length * 1.5); 
        imageUrls.push(url); // Add the URL to the collection
      });
    }
    

    //示例用法:

    addNewImage('path/to/newImage.jpg');

    //渲染场景

    函数animate(){

    requestAnimationFrame(动画);

    渲染器。渲染(场景、相机);

    }

    requestAnimationFrame(动画);