Closed FrissAnalytics closed 4 years ago
hi again!
my bad, I now realize that to use the camera one needs to say: myGlobe.camera()
, instead of myGlobe.camera
!
For those still interested in x
, y
screen coordinates for e.g. a label that gets clicked, you can get the coordinates as follows (assuming we have setup a globe myGlobe
, and have some label data stored in places
, that holds the lat, long data etc.) (see examples in this repo):
// get the globe and setup some label data
myGlobe
.labelsData(places)
.labelLat(d => d.properties.latitude)
.labelLng(d => d.properties.longitude)
.labelText(d => d.properties.name)
.onLabelClick(d => {
// on label click, extract the __threeObj object from `d`, clone it (otherwise the original data gets overwritten!), and get the position
const position = d.__threeObj.__data.__threeObj.clone().position;
// use the project method and pass it the camera to get the device independent coordinates i.e. x,y,z coordinates between -1 and 1;
// note that if the camera position changes, these coordinates change as well!
const coordinates = position.project(myGlobe.camera())
// next, scale these coordinates in relation to the available canvas size
// grab the canvas that holds the globe e.g. using d3
const canvas = d3.select("#globeViz").select("canvas");
// get the width and height
const width = canvas.attr("width");
const height = canvas.attr("height");
// scale the x, y coordinates from range -1,1 to the available width and height
const x = Math.round((0.5 + coordinates.x / 2) * (width / window.devicePixelRatio));
const y = Math.round((0.5 - coordinates.y / 2) * (height / window.devicePixelRatio));
// the actual x,y coordinates in relation to the canvas
// these can be used to e.g. create annotations via an overlay div
// note we need these x,y coordinates to attach the annotation in the overlay div
// to the data point on the globe e.g. via a line (see screenshot above)
console.log("screen coordinates - x:", x, " y:", y);
})
@vasturiano I guess it would still be handy for others to add a method that makes it easier to get these coordinates, assuming some would like to create annotations as I did. Anyways, great library, really loving it! :-)
@FrissAnalytics thanks for your suggestion.
I think it's a nice addition in any case. So I've added a new method that facilitates this: getScreenCoords
.
It receives spherical coordinates (lat, lng, ?alt)
and returns the viewport coordinates of where that location is rendered on the screen.
The method is quite similar to the one you use above. It first converts to cartesian coordinates and then projects them via the camera to retrieve the screen position.
Thanks again for the nice idea. 😉
Dear Vasco,
Hope you are doing well in these challenging times. Thanks again for all your amazing work, really cool stuff!
I was wondering, is there a way to convert lat/long/altitude or x,y,z coordinates used by threejs to convert them to normalized device coordinates or x,y screen coordinates in relation to say a container element?
This would be very helpful to create annotations (say via an overlay div), showing additional information on globe positions, in which the annotation is connected via a line to the globe.
This is sort of what I'm aiming for: (the globe etc is already based on your work :-)
For a cool effect it would be nice that when the camera view changes, the annotation connection line updates as well. I'm aware of the
getCoords
andtoGeoCoords
functions, but I guess they serve a different purpose.There are some references on the web that solve the coordinate conversion in relation to the current camera view, in particular see this three-js-annotations example and this stackoverflow question.
In the spirit of one of your own examples, let's say I set some labels on a globe (myGlobe) via
labelsData
and let's say I want to create an annotation for the first label.In what is suggested in the references above, I hoped something like this would work to get the x,y position information I was looking for:
Unfortunately it doesn't. Somehow at the end it seems to go wrong in this threejs function:
In both references the
applyMatrix3
function errors out saying thatelements
does not exist.Do you have any clue what I can do?
I think the ability to add annotations, be it only by providing a method to get appropriate x,y coordinates in relation to the camera view, could be helpful to others as well, hence this feature request.
Personally I would already be super grateful if I can manually do the conversion, but I seem to lack the knowledge on what to do here. Any help is greatly appreciated.
best wishes and have a great day! Herman