vasturiano / globe.gl

UI component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/globe.gl/example/world-population/
MIT License
2.06k stars 304 forks source link

How to set globe.controls().maxDistance? #79

Closed ian-whitestone closed 2 years ago

ian-whitestone commented 2 years ago

Is your feature request related to a problem? Please describe.

In order to limit how much a user can zoom out, I am trying to set globe.controls().maxDistance to something smaller than the default 10,000.

If I simply do globe.controls().maxDistance = 500, that has no effect because (i think) this line of code is overriding it back to 10000.

As a workaround, I am doing this in my code:

setTimeout(() => globe.controls().maxDistance = 500, 500);

which works, but feels incredibly hacky.

Is there a better way to do this?

Thanks!

vasturiano commented 2 years ago

@ian-whitestone I know it doesn't look ideal, but that's the way I would also do it. Waiting for a short period after component init and all the defaults have been applied, before customizing controls.

ian-whitestone commented 2 years ago

thanks for the quick response @vasturiano!

fine with keeping this, i guess my only concern was: what if the component initialization somehow takes longer than 500ms? i'm guessing that's extremely unlikely, but you get where i'm going? (note: 500ms was arbitrary, ideally i'd pick a smaller value, but i have no idea what the minimum is i could safely put)

vasturiano commented 2 years ago

Perhaps an alternative way you can try, do it on .onGlobeReady(() => ...). That might be a less hacky way to do it.

ian-whitestone commented 2 years ago

Perhaps an alternative way you can try, do it on .onGlobeReady(() => ...). That might be a less hacky way to do it.

i actually tried this, but it didn't work.

i'll try again tonight to confirm

ian-whitestone commented 2 years ago

Here's an example that shows maxDistance getting set back to the default 10000:

<head>
    <style> body { margin: 0; } </style>

    <script src="//unpkg.com/globe.gl"></script>
  </head>

  <body>
    <div id="globeViz"></div>

    <script>

      let globe = Globe()
        .onGlobeReady(afterGlobeReady)
      (document.getElementById('globeViz'))

      function afterGlobeReady() {
          globe.controls().maxDistance = 444
          console.log(`Max distance is now: ${globe.controls().maxDistance}`)
          setTimeout(() => console.log(`500ms later, max distance is now: ${globe.controls().maxDistance}`), 500);
      }
    </script>
  </body>
CleanShot 2022-01-12 at 08 12 20@2x
vasturiano commented 2 years ago

Yes I see, it's a race condition. I recommend setting inside a setTimeout (with 0 delay) in that callback, like so:

.onGlobeReady(() => setTimeout(() => globe.controls().maxDistance = 444))

That should make sure it's always applied, and does away with the need to set an arbitrary time length.

ian-whitestone commented 2 years ago

Thanks! that worked