One idea is to create a curated collection of image URLs and dynamically load textures to generate boxes with accurate aspect ratios for each image. You could even extend this functionality by implementing a function to introduce new elements - simply by specifying a new image URL and generating a corresponding box with the texture. The function would handle loading the new texture, creating a new box, and appending the URL to the imageUrls
collection as shown below:
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
});
}
// Demonstrative usage:
addNewImage('path/to/newImage.jpg');
// Render the scene
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
requestAnimationFrame(animate);