Ich verwende das planetaryjs -Paket, um einen Globus in js zu zeichnen.

Es gibt eine Funktion planetary.plugins.pings.add. Es funktioniert, wenn es in dieser Schleife ist:

setInterval(function() {
    var lat = 30.2500;
    var lng = 120.1667;
    var color = 'white';
    globe.plugins.pings.add(lng, lat, { color: color, ttl: 30000, angle: Math.random() * 10 });
}, 200);

Aber ich möchte nur einen Ping zeichnen, also habe ich es getan

    var lat = 30.2500;
    var lng = 120.1667;
    var color = 'white';
    globe.plugins.pings.add(lng, lat, { color: color, ttl: 30000, angle: Math.random() * 10 });

Aber Firefox sagt es mir

TypeError: globe.plugins.pings is undefined

Weiß jemand warum das so ist? Der vollständige Code ist hier (siehe Zeile 67-77). Quelle ist hier

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <script type='text/javascript' src='http://d3js.org/d3.v3.min.js'></script>
    <script type='text/javascript' src="http://d3js.org/topojson.v1.min.js"></script>
    <script type='text/javascript' src="http://labs.rivendellweb.net/data-vis/planetary/planetaryjs.js"></script>

  </head>

  <body>

    <canvas id='rotatingGlobe' width='800' height='600' style='width: 800px; height: 600px; cursor: move;'></canvas>
        <script>

            (function() {

                      var globe = planetaryjs.planet();

                      // Load our custom `autorotate` plugin; see below.
                      globe.loadPlugin(autorotate(0));

                      // The `earth` plugin draws the oceans and the land; it's actually
                      // a combination of several separate built-in plugins.
                      // Note that we're loading a special TopoJSON file
                      // (world-110m-withlakes.json) so we can render lakes.
                      globe.loadPlugin(planetaryjs.plugins.earth({
                        topojson: { file:   'world-110m-withlakes.json' },
                        oceans:   { fill:   '#000080' },
                        land:     { fill:   '#339966' },
                        borders:  { stroke: '#008000' }
                      }));

                      // Load our custom `lakes` plugin to draw lakes; see below.
                      globe.loadPlugin(lakes({
                        fill: '#000080'
                      }));

                      // The `pings` plugin draws animated pings on the globe.
                      globe.loadPlugin(planetaryjs.plugins.pings());

                      // The `zoom` and `drag` plugins enable
                      // manipulating the globe with the mouse.
                      globe.loadPlugin(planetaryjs.plugins.zoom({
                        scaleExtent: [100, 2000]
                      }));
                      globe.loadPlugin(planetaryjs.plugins.drag({
                        // Dragging the globe should pause the
                        // automatic rotation until we release the mouse.
                        onDragStart: function() {
                          this.plugins.autorotate.pause();
                        },
                        onDragEnd: function() {
                          this.plugins.autorotate.resume();
                        }
                      }));

                      // Set up the globe's initial scale, offset, and rotation.
                      globe.projection
                            .scale(400)
                            .translate([400, 300])
                            .rotate([-100, -30, 0]);

                      // Every few hundred milliseconds, we'll draw another random ping.
                      //var colors = ['red', 'yellow', 'white', 'orange', 'green', 'cyan', 'pink'];
                        setInterval(function() {
                            var lat = 30.2500;
                            var lng = 120.1667;
                            var color = 'white';
                            globe.plugins.pings.add(lng, lat, { color: color, ttl: 30000, angle: Math.random() * 10 });
                        }, 200);

                            var lat = 30.2500;
                            var lng = 120.1667;
                            var color = 'white';
                            globe.plugins.pings.add(lng, lat, { color: color, ttl: 30000, angle: Math.random() * 10 });

                      var canvas = document.getElementById('rotatingGlobe');
                      // Special code to handle high-density displays (e.g. retina, some phones)
                      // In the future, Planetary.js will handle this by itself (or via a plugin).
                      if (window.devicePixelRatio == 2) {
                        canvas.width = 800;
                        canvas.height = 800;
                        context = canvas.getContext('2d');
                        context.scale(2, 2);
                      }
                      // Draw that globe!
                      globe.draw(canvas);

                      // This plugin will automatically rotate the globe around its vertical
                      // axis a configured number of degrees every second.
                      function autorotate(degPerSec) {
                        // Planetary.js plugins are functions that take a `planet` instance
                        // as an argument...
                        return function(planet) {
                          var lastTick = null;
                          var paused = false;
                          planet.plugins.autorotate = {
                            pause:  function() { paused = true;  },
                            resume: function() { paused = false; }
                          };
                          // ...and configure hooks into certain pieces of its lifecycle.
                          planet.onDraw(function() {
                            if (paused || !lastTick) {
                              lastTick = new Date();
                            } else {
                              var now = new Date();
                              var delta = now - lastTick;
                              // This plugin uses the built-in projection (provided by D3)
                              // to rotate the globe each time we draw it.
                              var rotation = planet.projection.rotate();
                              rotation[0] += degPerSec * delta / 1000;
                              if (rotation[0] >= 180) rotation[0] -= 360;
                              planet.projection.rotate(rotation);
                              lastTick = now;
                            }
                          });
                        };
                      };

                      // This plugin takes lake data from the special
                      // TopoJSON we're loading and draws them on the map.
                      function lakes(options) {
                        options = options || {};
                        var lakes = null;

                        return function(planet) {
                          planet.onInit(function() {
                            // We can access the data loaded from the TopoJSON plugin
                            // on its namespace on `planet.plugins`. We're loading a custom
                            // TopoJSON file with an object called "ne_110m_lakes".
                            var world = planet.plugins.topojson.world;
                            lakes = topojson.feature(world, world.objects.ne_110m_lakes);
                          });

                          planet.onDraw(function() {
                            planet.withSavedContext(function(context) {
                              context.beginPath();
                              planet.path.context(context)(lakes);
                              context.fillStyle = options.fill || 'black';
                              context.fill();
                            });
                          });
                        };
                      };
                    })();


        </script>





  </body>
</html>
3
YJZ 14 Aug. 2015 im 06:58

3 Antworten

Beste Antwort

Ersetzen Sie setInterval durch setTimeout.

Der Grund, warum Ihr direkter Aufruf fehlschlägt, liegt darin, dass globe.plugins.pings erst nach dem Aufruf von globe.draw(canvas); initialisiert wird. Sie können es auch danach verschieben.

Im Vergleich zum Ersetzen durch den Codeblock verschiebt setTimeout die Ausführung des Codeblocks an das Ende der Ausführungswarteschlange, d. H. Bis nach globe.draw (canvas); wird aufgerufen und globe.plugins.pings wird initialisiert - aber im Gegensatz zu setInterval wird es nur einmal ausgeführt.

3
user2864740 14 Aug. 2015 im 06:04

Es wäre besser, eine Art Rückruf zu verwenden, als nur auf eine zufällige Zeitüberschreitung zu antworten. Etwas wie das. planet.onInit( function([done]){} )

3
atinder 14 Aug. 2015 im 04:16

Das DOM wird zum Zeitpunkt der Ausführung nicht initialisiert. Sie sollten die Initialisierung in document.addEventListener('DOMContentLoaded', function () { /* your code here */ }); einschließen.

1
mfeineis 14 Aug. 2015 im 04:18