#reactjs #three.js #react-three-fiber #orthographic
Вопрос:
Я хочу расположить орфографическую камеру так, чтобы она была сосредоточена на черном квадрате.
Но по какой-то странной причине он автоматически поворачивается и вместо этого показывает вид сверху черного квадрата, и мы видим только тонкую черную линию.
Бывают случаи, когда скрипка меняется, вид автоматически обновляется и снова отображается правильная сторона черного квадрата.
В моей центральной функции мне нужно обновить камеру? Или я должен просто манипулировать элементами управления? Я пробовал и то, и другое, но безрезультатно.
Функция центральной камеры:
const centerCamera = (controls, camera) => {
const point = new THREE.Vector3(0, 500, 1);
camera.position.copy(point);
camera.lookAt(point.x, point.y, 10);
controls.target.copy(point);
controls.update();
camera.updateProjectionMatrix();
camera.updateMatrix();
};
Сцена:
import "./styles.css";
import * as THREE from "three";
import React from "react";
import { Canvas } from "@react-three/fiber";
import { MapControls, OrthographicCamera } from "@react-three/drei";
const CONTENT_GEOMETRY = roundedRect(-350, -50, 700, 100, 100 / 3.7);
function roundedRect(x = 0, y = 0, width = 50, height = 50, radius = 5) {
const ctx = new THREE.Shape();
ctx.moveTo(x, y radius);
ctx.lineTo(x, y height - radius);
ctx.quadraticCurveTo(x, y height, x radius, y height);
ctx.lineTo(x width - radius, y height);
ctx.quadraticCurveTo(x width, y height, x width, y height - radius);
ctx.lineTo(x width, y radius);
ctx.quadraticCurveTo(x width, y, x width - radius, y);
ctx.lineTo(x radius, y);
ctx.quadraticCurveTo(x, y, x, y radius);
ctx.closePath();
return ctx;
}
const centerCamera = (controls, camera) => {
const point = new THREE.Vector3(0, 500, 1);
camera.position.copy(point);
camera.lookAt(point.x, point.y, point.z);
controls.target.copy(point);
controls.update();
camera.updateProjectionMatrix();
camera.updateMatrix();
};
export default function App() {
const dpr = typeof window !== "undefined" ? window?.devicePixelRatio ?? 0 : 0;
return (
<div className="App">
<Canvas
frameloop="always"
style={{ height: "100vh" }}
linear
dpr={Math.max(dpr, 2)}
>
<Content
onMount={(controls, camera) => {
centerCamera(controls, camera);
}}
/>
</Canvas>
</div>
);
}
const Content = ({ onMount }) => {
const controls = React.useRef(null);
const camera = React.useRef();
React.useEffect(() => {
if (controls.current amp;amp; camera.current) {
onMount(controls.current, camera.current);
}
}, [onMount]);
return (
<>
<MapControls
ref={controls}
screenSpacePanning
dampingFactor={1}
enableRotate={false}
/>
<OrthographicCamera ref={camera} makeDefault position={[0, 0, 2]} />
<mesh position={[0, 500, 1]}>
<shapeBufferGeometry args={[CONTENT_GEOMETRY]} />
<meshBasicMaterial color="#000000" />
</mesh>
</>
);
};
https://codesandbox.io/s/sleepy-dewdney-zuvyx?file=/src/App.js
Ответ №1:
Я думаю, что ваша проблема в том, что
camera.position.copy(point);
camera.lookAt(point.x, point.y, point.z);
Вы говорите камере перейти в определенное положение, а затем посмотреть в то же самое положение, что дает вам нежелательные результаты: в каком направлении вы смотрите, когда пункт назначения находится в том же месте, где вы находитесь? Попробуйте lookAt()
занять другую позицию. Например: point.y - 1
посмотрел бы вниз, point.x 1
посмотрел бы вправо.
Комментарии:
1. Спасибо за ваш ответ @marquizzo. Вы правы, когда указываете, что 2 пункта одинаковы, это была глупая ошибка с моей стороны. Однако, если я переключусь на camera.LookAt(точка.x, точка.y, 10); проблема останется прежней. Есть какие-нибудь мысли по этому поводу?