#javascript #three.js
#javascript #three.js
Вопрос:
Я пытаюсь «подгонять к масштабированию» отображенную текстуру изображения на одной плоскости. своего рода имитация поведения object-fit:cover
.
Таким образом, карта изображения должна увеличиваться или уменьшаться пропорционально, чтобы полностью покрыть всю плоскость.
Я попытался поиграть с повторением и смещением текстуры, но безуспешно. (прокомментировано в моем коде)
Как вы можете видеть, что у меня есть до сих пор в приведенном ниже фрагменте, изображение все еще растягивается для подгонки. Любая помощь приветствуется!
var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas'), antialias:true});
renderer.setClearColor(0x7b7b7b);
// use device aspect ratio //
renderer.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window
renderer.setSize(window.innerWidth, window.innerHeight);
// SCENE
var scene = new THREE.Scene();
// CAMERA
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
// MESH 0
// texture
var texture_0 = new THREE. TextureLoader().load("https://i.imgur.com/YO0ygMx.jpg");
texture_0.wrapS = THREE.ClampToEdgeWrapping;
texture_0.wrapT = THREE.RepeatWrapping;
// var tileWidth = 2;
// var tileHeight = 1;
// repeatX = tileWidth * 1024 / (tileHeight * 2048);
// repeatY = 1;
// texture_0.repeat.set(repeatX, repeatY);
var geometry_0 = new THREE.PlaneGeometry(1.3,1,32);
var material_0 = new THREE.MeshBasicMaterial({
color: 0xd8d0d1,
side: THREE.DoubleSide,
map: texture_0
});
var mesh_0 = new THREE.Mesh(geometry_0, material_0);
scene.add(mesh_0);
mesh_0.position.x = -0.7
// MESH 1
var texture_1 = new THREE.TextureLoader().load("https://i.imgur.com/YO0ygMx.jpg");
texture_1.wrapS = THREE.ClampToEdgeWrapping;
texture_1.wrapT = THREE.RepeatWrapping;
var geometry_1 = new THREE.PlaneGeometry(1,3,32);
var material_1 = new THREE.MeshBasicMaterial({
color: 0xd8d0d1,
side: THREE.DoubleSide,
map: texture_1
});
var mesh_1 = new THREE.Mesh(geometry_1, material_1);
scene.add(mesh_1);
mesh_1.position.x = 0.7
// RENDER ANIMATE
function animate() {
/* render scene and camera */
renderer.render(scene,camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// RESIZE EVENTS
window.addEventListener('resize', onResize);
function onResize() {
width = window.innerWidth;
height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<canvas id="canvas"></canvas>
Ответ №1:
Существует множество возможных аспектов. Есть аспект самой текстуры, размер плоскости, размер отображаемой плоскости (например, если вы ее масштабировали) и т. Д..
В любом случае, как минимум, вам нужно знать аспект изображения и аспект плоскости. Если вы не будете жестко кодировать размер изображения в своем приложении, вы не будете знать аспект изображения до тех пор, пока оно не будет загружено. На этом этапе вы можете вычислить правильное смещение и повторить настройки, как подробно описано в этой статье
// Set the repeat and offset properties of the background texture
// to keep the image's aspect correct.
const planeAspect = planeWidth / planeHeight;
const imageAspect = texture.image.width / texture.image.height;
const aspect = imageAspect / planeAspect;
texture.offset.x = aspect > 1 ? (1 - 1 / aspect) / 2 : 0;
texture.repeat.x = aspect > 1 ? 1 / aspect : 1;
texture.offset.y = aspect > 1 ? 0 : (1 - aspect) / 2;
texture.repeat.y = aspect > 1 ? 1 : aspect;
var renderer = new THREE.WebGLRenderer({ canvas : document.getElementById('canvas'), antialias:true});
renderer.setClearColor(0x7b7b7b);
// use device aspect ratio //
renderer.setPixelRatio(window.devicePixelRatio);
// set size of canvas within window
renderer.setSize(window.innerWidth, window.innerHeight);
// SCENE
var scene = new THREE.Scene();
// CAMERA
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
// Set the repeat and offset properties of the background texture
// to keep the image's aspect correct.
function fixTexture(planeWidth, planeHeight) {
return function(texture) {
const planeAspect = planeWidth / planeHeight;
const imageAspect = texture.image.width / texture.image.height;
const aspect = imageAspect / planeAspect;
texture.offset.x = aspect > 1 ? (1 - 1 / aspect) / 2 : 0;
texture.repeat.x = aspect > 1 ? 1 / aspect : 1;
texture.offset.y = aspect > 1 ? 0 : (1 - aspect) / 2;
texture.repeat.y = aspect > 1 ? 1 : aspect;
}
}
// MESH 0
// texture
var texture_0 = new THREE. TextureLoader().load("https://i.imgur.com/YO0ygMx.jpg", fixTexture(1.3, 1));
texture_0.wrapS = THREE.ClampToEdgeWrapping;
texture_0.wrapT = THREE.RepeatWrapping;
// var tileWidth = 2;
// var tileHeight = 1;
// repeatX = tileWidth * 1024 / (tileHeight * 2048);
// repeatY = 1;
// texture_0.repeat.set(repeatX, repeatY);
var geometry_0 = new THREE.PlaneGeometry(1.3,1,32);
var material_0 = new THREE.MeshBasicMaterial({
color: 0xd8d0d1,
side: THREE.DoubleSide,
map: texture_0
});
var mesh_0 = new THREE.Mesh(geometry_0, material_0);
scene.add(mesh_0);
mesh_0.position.x = -0.7
// MESH 1
var texture_1 = new THREE.TextureLoader().load("https://i.imgur.com/YO0ygMx.jpg", fixTexture(1,3));
texture_1.wrapS = THREE.ClampToEdgeWrapping;
texture_1.wrapT = THREE.RepeatWrapping;
var geometry_1 = new THREE.PlaneGeometry(1,3,32);
var material_1 = new THREE.MeshBasicMaterial({
color: 0xd8d0d1,
side: THREE.DoubleSide,
map: texture_1
});
var mesh_1 = new THREE.Mesh(geometry_1, material_1);
scene.add(mesh_1);
mesh_1.position.x = 0.7
// RENDER ANIMATE
function animate() {
/* render scene and camera */
renderer.render(scene,camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// RESIZE EVENTS
window.addEventListener('resize', onResize);
function onResize() {
width = window.innerWidth;
height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<canvas id="canvas"></canvas>
Комментарии:
1. Спасибо! я думаю, что смогу работать с этим и сделать его динамичным в зависимости от размера изображения!