Fermer

juillet 26, 2021

Fonctions sans serveur de Gatsby et la Station spatiale internationale —


Résumé rapide ↬

Gatsby a récemment annoncé le lancement de "fonctions". Dans cet article, Paul Scanlon explique comment obtenir l'emplacement actuel de la Station spatiale internationale (ISS) alors qu'elle orbite autour de la Terre en temps réel à l'aide de Gatsby Functionspuis l'afficher sur un globe interactif 3D à l'aide de Réagissez Trois Fibres.

Gatsby a récemment annoncé le lancement de Functions qui ouvre une nouvelle dimension de possibilités – et pour ma part, je ne pourrais pas être plus excité ! Avec Gatsby fournissant désormais des fonctions sans serveur sur Gatsby Cloud (et Netlify fournissant également une assistance via @netlify/plugin-gatsby), le cadre qui était autrefois mal compris comme étant « uniquement pour les blogs » est maintenant plus que jamais, (à mon avis) le fournisseur de technologie le plus passionnant dans l'espace Jamstack.

La démo de cet article est le résultat d'un projet récent sur lequel j'ai travaillé où j'avais besoin de tracer emplacements autour d'un globe 3D et j'ai pensé qu'il serait amusant de voir s'il était possible d'utiliser la même technique en utilisant des emplacements hors planète. Alerte spoiler : c'est possible ! Voici un aperçu de ce dont je vais parler dans ce postou si vous préférez aller de l'avant, le code fini peut être trouvé ici.

Mise en route[19659005]Avec Gatsby Functions, vous pouvez créer des applications plus dynamiques en utilisant des techniques généralement associées aux applications côté client en ajoutant un répertoire api à votre projet et en exportant une fonction, par exemple

|-- src
  |-- api
     -- une-fonction.js
  |-- pages
 // src/api/some-function.js
Exporter le gestionnaire de fonction par défaut (req, res) {
  res.status(200).json({ bonjour: `world` })
}

Si vous avez déjà une configuration de projet Gatsby, parfait ! mais assurez-vous d'avoir mis à niveau Gatsby au moins vers la version v3.7

npm install gatsby@lastest --save

Si ce n'est pas le cas, n'hésitez pas à cloner mon dépôt de démarrage Gatsby à nu absolu : mr-minimum.

Avant de pouvoir commencer à utiliser Gatsby Functions pour suivre la Station spatiale internationale, j'ai d'abord besoin pour créer un globe en orbite.

Image en vedette montrant la Station spatiale internationale en orbite autour de la Terre

Faisons quelque chose comme ça ! ( Grand aperçu)

Étape 1 : Créer le globe interactif 3D

Je commence par configurer un globe interactif 3D qui peut être utilisé ultérieurement pour tracer l'emplacement actuel de l'ISS.

Dépendances d'installation

npm install @react-three/ fibre @react-three/drei trois trois-geojson-geometry axios --save

Créer la scène

Créer un nouveau fichier dans src/components appelé three-scene.js

//src/components/three-scene.js
importer React à partir de « react » ;
importer { Canvas } depuis '@react-three/fiber' ;
importer { OrbitControls } depuis '@react-three/drei' ;

const ThreeScene = () => {
  revenir (
     {
        gl.setClearColor('#ffffff');
      }}
      style={{
        largeur : '100vw',
        hauteur : '100vh',
        curseur : 'déplacer'
      }}
    >
      
    
  );
} ;

exporter le ThreeScene par défaut ;

Ce qui précède configure un nouvel élément et peut être configuré à l'aide des accessoires exposés par React Three Fibre.

Les éléments renvoyés en tant qu'enfants du composant canvas seront affichés dans le cadre de la scène 3D. Vous verrez ci-dessus que j'ai inclus qui ajoute une interactivité tactile/souris permettant aux utilisateurs de faire pivoter la scène dans l'espace 3D

Assurez-vous que ThreeScene est importé et rendu sur une page quelque part dans votre site . Dans mon exemple de référentiel, j'ai ajouté ThreeScene à index.js:

//src/pages/index.js
importer React à partir de « react » ;

importer ThreeScene depuis '../components/three-scene';

const IndexPage = () => {
  revenir (
    
); } ; exporter la page d'index par défaut ;
Plus après le saut ! Continuez à lire ci-dessous ↓

Cela ne fera pas grand-chose pour le moment car il n'y a rien à afficher dans la scène. Corrigons cela !

Créer la sphère

Créer un fichier dans src/components appelé three-sphere.js:

//src/components/three- sphère.js
importer React à partir de « react » ;

const Trois Sphère = () => {
  revenir (
    
      
      
    
  );
} ;

exporter le ThreeSphere par défaut ;

Si la syntaxe ci-dessus semble un peu différente de celle des Three.js docs c'est parce que React Three Fiber utilise une approche déclarative pour utiliser Three.js dans React.

Une bonne explication de la façon dont Les arguments du constructeur fonctionnent dans React Three Fiber peuvent être vus dans la documentation ici : Constructor arguments

Now add ThreeSphere to ThreeScene:

// src /components/trois-scene.js
importer React à partir de « react » ;
importer { Canvas } depuis '@react-three/fiber' ;
importer { OrbitControls } depuis '@react-three/drei' ;

+ importer ThreeSphere de './three-sphere';

const ThreeScene = () => {
  revenir (
     {
        gl.setClearColor('#ffffff');
      }}
      style={{
        largeur : '100vw',
        hauteur : '100vh',
        curseur : 'déplacer'
      }}
    >
      
+ 
    
  );
} ;

exporter le ThreeScene par défaut ;

Vous devriez maintenant voir quelque chose de similaire à l'image ci-dessous.

image de ThreeSphere rendue dans ThreeScene

Une sphère vierge Three.js rendue dans une scène 3D (Grand aperçu)

Pas très excitant, n'est-ce pas ? Faisons quelque chose à ce sujet !

Créer la géométrie (pour visualiser les pays de la planète Terre)

Cette prochaine étape nécessite l'utilisation de three-geojson-geometry et d'une ressource CDN qui contient Natural Earth Données. Vous pouvez faire votre choix parmi une liste complète des géométries appropriées ici.

J'utiliserai admin 0 pays. J'ai choisi cette option car elle fournit suffisamment de détails géométriques pour voir chaque pays, mais pas au point d'ajouter une pression inutile sur le GPU de votre ordinateur.

Maintenant, créez un fichier dans src/components appelé three-geo.js:

//src/components/three-geo.js
import React, { Fragment, useState, useEffect } de 'react';
importer { GeoJsonGeometry } de 'three-geojson-geometry' ;
importer des axios à partir de « axios » ;

const ThreeGeo = () => {
const [isLoading, setIsLoading] = useState(true);
  const [geoJson, setGeoJson] = useState(null);
 
  useEffect(() => {
    axios
      .avoir(
   'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_110m_admin_0_countries.geojson'
      )
      .then((réponse) => {
        setIsLoading(false);
        setGeoJson(response.data);
      })
      .catch((erreur) => {
        console.log(erreur);
        lancer une nouvelle erreur ();
      });
  }, []);

  revenir (
    
      {!est en cours de chargement ? (
        
          {geoJson.features.map(({ géométrie }, index) => {
            revenir (
              
                
              
            );
          })}
        
      ) : nul}
    
  );
} ;

exporter ThreeGeo par défaut ;

Il se passe beaucoup de choses dans ce fichier, je vais donc vous guider.

  1. Créez une instance d'état isLoading à l'aide des hooks React et définissez-la sur true. Cela empêche React d'essayer de renvoyer des données que je n'ai pas encore.
  2. À l'aide d'un useEffectje demande le geojson au CDN CloudFront.
  3. En cas de récupération réussie, je définis la réponse dans l'état React en utilisant setGeoJson(...) et définissez isLoading sur false
  4. À l'aide d'un Array.prototype.map J'itére sur le " features" contenues dans la réponse geojson et renvoient lineSegments avec lineBasicMaterial pour chaque geometry
  5. Je définis les lineSegments geometry à la valeur de retour fournie par GeoJsonGeomtry qui passe les "caractéristiques" geometry avec un rayon de 100.

(Vous avez peut-être remarqué que je' j'ai utilisé le même rayon de 100 ici que j'ai utilisé dans le sphereGeometry args dans [1 9459062]trois-sphère.js. Vous n'êtes pas obligé de définir le rayon sur la même valeur, mais il est logique d'utiliser les mêmes rayons pour ThreeSphere et ThreeGeo.

Si vous souhaitez en savoir plus sur le fonctionnement de GeoJsonGeometry, voici le référentiel open source pour référence : https://github.com/vasturiano/three-geojson-geometry. Le référentiel a un répertoire example cependant, la syntaxe est légèrement différente de ce que vous voyez ici car les exemples sont écrits en JavaScript vanille et non en React.

Combine The Sphere And Geometry

Maintenant, il est temps de superposez la géométrie au-dessus de la sphère vierge : ajoutez ThreeGeo à ThreeScene

// src/components/three-scene.js
importer React à partir de « react » ;
importer { Canvas } depuis '@react-three/fiber' ;
importer { OrbitControls } depuis '@react-three/drei' ;

importer ThreeSphere de './three-sphere';
+ importer ThreeGeo depuis './three-geo';


const ThreeScene = () => {
  revenir (
     {
        gl.setClearColor('#ffffff');
      }}
      style={{
        largeur : '100vw',
        hauteur : '100vh',
        curseur : 'déplacer'
      }}
    >
      
      
+ 
    
  );
} ;

Vous devriez maintenant voir quelque chose de similaire à l'image ci-dessous.

image de ThreeGeo rendue dans ThreeScene

Sphère excitante Three.js affichant les pays du monde (Grand aperçu)

Maintenant, c'est un peu plus excitant !

Étape 2 : Créer une fonction sans serveur

Créer une fonction

Cette étape suivante consiste à utiliser une fonction Gatsby pour demander des données à Où se trouve ISSqui renvoie l'emplacement actuel de la Station spatiale internationale.

Créez un fichier dans src/api appelé get-iss-location.js:

// src/api/get-iss-location.js
const axios = require('axios');

exporter le gestionnaire de fonction asynchrone par défaut (req, res) {
  essayer {
    const { données } = wait axios.get(
      'https://api.wheretheiss.at/v1/satellites/25544'
    );

    res.status(200).json({ iss_now: data });
  } catch (erreur) {
    res.status(500).json({ erreur });
  }
}

Cette fonction est chargée de récupérer les données de api.whereistheiss.at et, en cas de succès, renverra le data et un 200 code d'état au navigateur .

Les ingénieurs de Gatsby ont fait un travail incroyable en simplifiant les fonctions sans serveur que ce qui précède est tout ce dont vous avez vraiment besoin pour commencer, mais voici un peu plus de détails sur ce qui se passe.

  • Le la fonction est une exportation default à partir d'un fichier nommé get-iss-location.js;
  • Avec Gatsby Functions, le nom de fichier devient le chemin de fichier utilisé côté client get requête préfixée par apipar exemple /api/get-iss-location;
  • Si la demande de "Où est l'ISS à" réussit, je renvoie un objet iss_now contenant données de où se trouve l'ISS à l'API et un code d'état de 200 au client ;
  • Si la demande s'avère erronée, j'envoie l'erreur au client.

Étape 3 : Construire la Station spatiale internationale

Créer la sphère ISS

Dans cette étape suivante, j'utilise les fonctions de Gatsby pour positionner une sphère qui représente la Station spatiale internationale en orbite autour du globe. Je le fais en appelant à plusieurs reprises une requête axios.get à partir d'une fonction poll et en définissant la réponse dans l'état React.

Créez un fichier dans src/components appelé three-iss.js

// src/components/three-iss.js
import React, { Fragment, useEffect, useState } de 'react';
importer * comme TROIS à partir de « trois » ;
importer des axios à partir de « axios » ;

export const getVertex = (latitude, longitude, rayon) => {
  vecteur const = new THREE.Vector3().setFromSpherical(
    nouveau TROIS.Sphérique(
      rayon,
      TROIS.MathUtils.degToRad(90 - latitude),
      TROIS.MathUtils.degToRad(longitude)
    )
  );
  vecteur de retour ;
} ;

const TroisIss = () => {
  const [issNow, setIssNow] = useState(null);

  const sondage = () => {
    axios
      .get('/api/get-iss-location')
      .then((réponse) => {
        setIssNow(response.data.iss_now);
      })
      .catch((erreur) => {
        console.log(erreur);
        lancer une nouvelle erreur ();
      });
  } ;

  useEffect(() => {
    const pollInterval = setInterval(() => {
      sondage();
    }, 5000);

    sondage();
    return() => clearInterval(pollInterval);
  }, []);

  revenir (
    
      {issMaintenant ? (
        
          
          
        
      ) : nul}
    
  );
} ;

exporter le ThreeIss par défaut ;

Il se passe beaucoup de choses dans ce fichier, je vais donc vous guider.

  1. Créez une instance d'état issNow à l'aide des hooks React et définissez-la sur null. Cela empêche React d'essayer de renvoyer des données que je n'ai pas encore ;
  2. À l'aide d'un useEffectje crée un intervalle JavaScript qui appelle la fonction poll toutes les 5 secondes ;
  3. La fonction poll est l'endroit où je demande l'emplacement de l'ISS à partir du point de terminaison de la fonction Gatsby (/api/get-iss-location);
  4. Une fois la récupération réussie, j'ai défini la réponse dans React state en utilisant setIssNow(...);
  5. Je passe les latitude et longitude sur une fonction personnalisée appelée getVertexavec un rayon.

Vous avez peut-être remarqué qu'ici j'utilise un rayon de 120. Cela diffère de la valeur de rayon 100 utilisée dans ThreeSphere et ThreeGeo. L'effet du plus grand rayon est de positionner l'ISS plus haut dans la scène 3D, plutôt qu'au niveau du sol – parce que c'est logiquement là où l'ISS serait, n'est-ce pas ?
100 a l'effet de la sphère et de la géométrie se chevauchent pour représenter la Terre, et 120 pour l'ISS a l'effet de la station spatiale « en orbite » autour du globe que j'ai créé.

Une chose qui a pris un peu de temps à comprendre, du moins pour moi , était de savoir comment utiliser des coordonnées sphériques à deux dimensions (latitude et longitude) en trois dimensions, par exemple x,y,z. Le concept a été assez bien expliqué dans ce post de Mike Bostock.

La clé pour tracer lat/lng dans l'espace 3D réside dans cette formule… qui n'a absolument aucun sens pour moi !

x =rcos(ϕ)cos(λ)
y=rsin(ϕ)
z=−rcos(ϕ)sin(λ)

Heureusement, Three.js a un ensemble de MathUtils que j'ai utilisé comme ceci :

  • Passer la latitudelongitude et radius dans la fonction getVertex(...)
  • Créez un nouvel objet THREE.Spherical à partir des paramètres nommés ci-dessus
  • Définissez l'objet THREE.Vector3 à l'aide des valeurs Spherical renvoyées par la fonction d'assistance setFromSpherical.

Ces nombres peuvent désormais être utilisés pour positionner des éléments dans l'espace 3D sur leurs x, y respectifs. , axe z — ouf ! Merci, Three.js !

Ajoutez maintenant ThreeIss à ThreeScene :

importez React depuis 'react' ;
importer { Canvas } depuis '@react-three/fiber' ;
importer { OrbitControls } depuis '@react-three/drei' ;

importer ThreeSphere de './three-sphere';
importer ThreeGeo à partir de './three-geo' ;
+ importer ThreeIss de './three-iss';

const ThreeScene = () => {
  revenir (
     {
        gl.setClearColor('#ffffff');
      }}
      style={{
        largeur : '100vw',
        hauteur : '100vh',
        curseur : 'déplacer'
      }}
    >
      
      
 
+ 
    
  );
} ;

exporter le ThreeScene par défaut ;

Et voilà ! Vous devriez maintenant voir quelque chose de similaire à l'image ci-dessous.

image de ThreeIss rendue dans ThreeScene

Regardez, c'est l'ISS (le point noir) ! ( Grand aperçu)

La fonction poll appellera à plusieurs reprises la fonction Gatsby, qui à son tour demande l'emplacement actuel de l'ISS et restitue le composant React chaque fois qu'une réponse est réussie. Vous devrez surveiller attentivement, mais l'ISS changera de position très légèrement toutes les 5 secondes.

L'ISS se déplace à environ 28 000 km/h et interroger la fonction Gatsby moins souvent révélerait des sauts de position plus importants. J'ai utilisé 5 secondes ici car c'est le temps de demande le plus fréquent autorisé par l'API Where is ISS at API

Vous avez peut-être également remarqué qu'aucune authentification n'est requise pour demander des données à l'API Where is ISS at API. Cela signifie que oui, techniquement, j'aurais pu appeler l'API directement depuis le navigateur, cependant, j'ai décidé de faire cet appel API côté serveur en utilisant Gatsby Functions pour deux raisons :

  1. Cela n'aurait pas fait un très bon blog publier sur les fonctions Gatsby si je ne les ai pas utilisées.
  2. Qui sait ce que l'avenir nous réserve pour Où est l'ISS, cela pourrait à un moment donné nécessiter une authentification et l'ajout de clés API aux requêtes API côté serveur est assez simple, de plus ce changement ne nécessiterait aucune mise à jour du code côté client.

Étape 4 : Rendez-le plus sophistiqué ! (Facultatif)

J'ai utilisé l'approche ci-dessus pour créer cette implémentation légèrement plus élégante : https://whereisiss.gatsbyjs.io,

Dans ce site, j'ai visualisé le délai à partir de la fonction poll en implémentant une animation de compte à rebours Svg et en ajoutant un supplémentaire avec un stroke-dashoffset pour créer les lignes pointillées qui l'entourent.

Capture d'écran de whereisiss.gatsbyjs.io

En voici un que j'ai fait plus tôt. ( Grand aperçu)

Étape 5 : Appliquez vos nouvelles compétences de rendu géographique de manière amusante !

J'ai récemment utilisé cette approche pour tracer les emplacements géographiques des gagnants du concours de 500 bouteilles : https://500bottles.gatsbyjs.io. Un cadeau promotionnel en édition limitée GRATUIT sur lequel j'ai travaillé avec l'équipe marketing de Gatsby.

 Capture d'écran de 500bottles.gatsbyjs.io

Trois.js peuvent faire beaucoup de choses ! ( Grand aperçu)

Vous pouvez tout savoir sur la réalisation de ce site sur le blog Gatsby : How We Made the Gatsby 500 Bottles Giveaway

Dans le site 500 Bottles je trace les emplacements géographiques de chacun des concours gagnants en utilisant la même méthode que celle décrite dans ThreeIss, qui permet à toute personne visitant le site de voir où dans le monde se trouvent les gagnants.

image des emplacements géographiques des gagnants de 500 bouteilles rendues sur un globe 3D.[19659013]Le plus chic de tous. (<a href= Grand aperçu)

Réflexions de clôture

Les fonctions Gatsby ouvrent vraiment beaucoup de possibilités pour les développeurs de Jamstack et ne jamais avoir à se soucier de faire tourner ou de faire évoluer un serveur supprime tant de problèmes nous laissant libres de réfléchir à de nouvelles façons ils peuvent être utilisés.

J'ai un certain nombre d'idées que j'aimerais explorer en utilisant les API V4 Space X alors suivez-moi si c'est votre tasse de thé : @PaulieScanlon[19659136]Autres lectures

J'espère que vous avez apprécié cet article. Ttfn 🕺!






Source link