从集合中获取纹理

问题描述 投票:0回答:1

各位正在阅读的朋友大家好。

我正在尝试创建一个网站,在其中我可以用鼠标滚动浏览“卡片”,这些“卡片”都在一行中,从侧面以 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 相当陌生,不知道从哪里开始这样做。

javascript collections three.js textures
1个回答
0
投票

为什么不创建图像 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('路径/to/newImage.jpg');

//渲染场景

函数 animate() {

请求动画帧(动画);

renderer.render(场景,相机);

}

请求动画帧(动画);

© www.soinside.com 2019 - 2024. All rights reserved.