Within my project, I have integrated https://github.com/vasturiano/react-globe.gl to showcase a visually appealing 3D globe. The current configuration of the globe is as follows:
radius = 100
position = (0, 0, 0)
The camera operates with OrbitControls and its target point is set at:
OrbitControls.target = (0, 0, 0)
This positioning ensures that by default, the sphere remains centered within the canvas. Additionally, there are markers strategically positioned on the globe's surface.
Objective
The desired behavior involves adjusting the camera position dynamically when a user clicks on a marker. Instead of focusing on the center of the globe, the camera should move closer to the surface, aligning itself with the marker's position. This action would result in only a portion of the globe being visible at the lower section of the canvas. I discovered a functional demo illustrating this concept here: (try clicking on a green marker). Could someone provide guidance on how to achieve this effect?
Current Approach
The current method involves gradually updating the OrbitControl target to match the marker's 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()
Similarly, the camera is also moved gradually to a specific position:
// 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()
To further enhance the visual effect, the globe is shifted slightly downwards on the canvas:
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()
Issue
The manual process of identifying positions for each marker is not practical. Moreover, the visibility of the globe varies significantly depending on the marker location, whereas consistency is maintained on the website reference provided earlier. Is there a more efficient approach to achieving this animation? Any guidance would be greatly appreciated.
Edit (jscastro's answer)
Thank you for the prompt response — it seems we are making progress! However, I am encountering difficulties in generating the appropriate curve. Currently, the curve is created based on camera.position
(starting point) and marker.position
(ending point):
// 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 ),
]);
This setup results in a straight line. When the camera reaches the end of the curve, the globe's positioning within the canvas is incorrect, as shown in this screenshot for a specific marker:
https://i.sstatic.net/n0wuL.jpg
However, I aim to represent the globe consistently for all markers, similar to the display illustrated in this screenshot:
https://i.sstatic.net/geQ0C.jpg
Is there a method to generate dynamic curves so that upon reaching the end, the globe appears as intended in the second screenshot (regardless of the marker's position)? Your insights on this matter would be greatly valued. Thank you.