В моем проекте я использую https://github.com/vasturiano/react-globe.gl для рендеринга 3D-глобуса. Глобус - это сфера, где:
radius = 100
position = (0, 0, 0)
Камера использует OrbitControls с:
OrbitControls.target = (0, 0, 0)
Это означает, что по умолчанию сфера находится в центре холста. На поверхности земного шара присутствуют маркеры.
Цель
Когда пользователь нажимает на маркер, камера должна приближаться к поверхности земного шара, глядя в позиции маркера (вместо центра земного шара). В результате внизу холста будет видна только небольшая часть земного шара. Я нашел рабочую демонстрацию, которая точно показывает эту концепцию здесь https://www.fonterra.com/nz/en/campaign/from-here-to-everywhere.html# / home (если вы нажмете на зеленый маркер). Может ли кто-нибудь указать мне направление, в котором я могу этого добиться?
Текущая реализация
Постепенно установите OrbitControl.target на marker.position
new TWEEN.Tween({ x: controls.target.x, y: controls.target.y, z: controls.target.z })
.to({ x: c1.x, y: c1.y, z: c1.z}, duration)
.onUpdate(d => {
controls.target.set(d.x, d.y, d.z)
})
.start()
Постепенно переместите камеру в определенное c положение, которое я обнаружил
// TODO: Find a way to calculate this position?
new TWEEN.Tween({ x: camera.position.x, y: camera.position.y, z: camera.position.z })
.to(pointIFoundMyself, duration)
.onUpdate(d => {
camera.position.set(d.x, d.y, d.z)
})
.start()
Переместите глобус немного дальше в нижнюю часть холста (-y)
new TWEEN.Tween({ x: world.position.x, y: world.position.y, z: world.pos})
.to({x: world.position.x, y: -25, z: world.position.z}, duration)
.onUpdate(d => {
world.position.set(d.x, d.y, d.z)
})
.start()
Проблема
Найти точку для каждого маркера на карте самостоятельно нереально. Видимая часть земного шара также сильно различается в зависимости от маркера (местоположения), хотя на веб-сайте, на который я ссылался выше, это очень похоже. Я хотел бы знать, есть ли лучший способ добиться этой анимации. Мы будем очень признательны за пу sh в правильном направлении.
Изменить (ответ jscastro)
Прежде всего, спасибо за быстрый ответ - похоже, мы приближаемся! Однако у меня возникли проблемы с построением правильной кривой. В настоящее время кривая генерируется с помощью camera.position
(начало) и marker.position
(конец), например:
// converts (lat, lng) to world position
const coords = curr.getCoords(marker.node.location.lat, marker.node.location.lng, 0.20)
const curve = new THREE.CatmullRomCurve3( [
new THREE.Vector3( camera.position.x, camera.position.y, camera.position.z ),
new THREE.Vector3( coords.x, coords.y, coords.z ),
]);
Это (очевидно) создает прямую линию. Когда камера находится в конце кривой, глобус неправильно расположен на холсте. Как на этом скриншоте для маркера:
But I'd like the globe to be positioned like this for all markers:
введите описание изображения здесь
Возможно, вы знаете, как я могу динамически создавать такие кривые, чтобы в конце кривой глобус отображался так же, как на скриншоте выше (для любого маркера на глобусе)? Спасибо.