Ces articles sont destinés à vous aider à apprendre à utiliser three.js.
Ils supposent que vous savez programmer en JavaScript. Ils supposent
que vous savez ce qu'est le DOM, comment écrire du code HTML et comment créer des éléments DOM
en JavaScript. Ils supposent que vous savez utiliser
les modules es6
via import et via les balises <script type="module">
. Ils supposent que vous savez utiliser les import maps.
Ils supposent que vous connaissez un peu de CSS et que vous savez ce que
sont les sélecteurs CSS.
Ils supposent également que vous connaissez ES5, ES6 et peut-être un peu ES7.
Ils supposent que vous savez que le navigateur n'exécute du JavaScript que via des événements et des callbacks.
Ils supposent que vous savez ce qu'est une closure.
Voici quelques rappels et notes
Les modules es6 peuvent être chargés via le mot-clé import
dans un script
ou en ligne via une balise <script type="module">
. Voici un exemple
<script type="importmap"> { "imports": { "three": "./path/to/three.module.js", "three/addons/": "./different/path/to/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; ... </script>
Voir plus de détails au bas de cet article.
document.querySelector
et document.querySelectorAll
Vous pouvez utiliser document.querySelector
pour sélectionner le premier élément
qui correspond à un sélecteur CSS. document.querySelectorAll
retourne
tous les éléments qui correspondent à un sélecteur CSS.
onload
Beaucoup de pages vieilles de 20 ans utilisent du HTML comme ceci
<body onload="somefunction()">
Ce style est obsolète. Mettez vos scripts au bas de la page.
<html> <head> ... </head> <body> ... </body> <script> // javascript inline </script> </html>
ou utilisez la propriété defer
.
function a(v) { const foo = v; return function() { return foo; }; } const f = a(123); const g = a(456); console.log(f()); // imprime 123 console.log(g()); // imprime 456
Dans le code ci-dessus, la fonction a
crée une nouvelle fonction à chaque fois qu'elle est appelée. Cette
fonction englobe la variable foo
. Voici plus d'informations.
this
this
n'est pas magique. C'est effectivement une variable qui est automatiquement passée aux fonctions, tout comme
un argument est passé à une fonction. L'explication simple est que lorsque vous appelez une fonction directement
comme ceci
somefunction(a, b, c);
this
sera null
(en mode strict ou dans un module), alors que lorsque vous appelez une fonction via l'opérateur point .
comme ceci
someobject.somefunction(a, b, c);
this
sera défini sur someobject
.
Là où les gens se perdent, c'est avec les callbacks.
const callback = someobject.somefunction; loader.load(callback);
ne fonctionne pas comme une personne inexpérimentée pourrait s'attendre, car lorsque
loader.load
appelle le callback, il ne l'appelle pas avec l'opérateur point .
donc par défaut this
sera null (sauf si le loader le définit explicitement sur autre chose).
Si vous voulez que this
soit someobject
lorsque le callback a lieu, vous devez
le dire à JavaScript en le liant à la fonction.
const callback = someobject.somefunction.bind(someobject); loader.load(callback);
Cet article pourrait aider à expliquer this
.
var
est obsolète. Utilisez const
et/ou let
Il n'y a aucune raison d'utiliser var
JAMAIS et à ce stade, il est considéré comme une mauvaise pratique
de l'utiliser du tout. Utilisez const
si la variable ne sera jamais réassignée, ce qui est la plupart du temps.
Utilisez let
dans les cas où la valeur change. Cela aidera à éviter des tonnes de bugs.
for(elem of collection)
jamais for(elem in collection)
for of
est nouveau, for in
est ancien. for in
avait des problèmes qui sont résolus par for of
Par exemple, vous pouvez itérer sur toutes les paires clé/valeur d'un objet avec
for (const [key, value] of Object.entries(someObject)) { console.log(key, value); }
forEach
, map
et filter
là où c'est utileLes tableaux ont ajouté les fonctions forEach
,
map
et
filter
et
sont assez largement utilisés dans le JavaScript moderne.
Supposons un objet const dims = {width: 300, height: 150}
ancien code
const width = dims.width; const height = dims.height;
nouveau code
const {width, height} = dims;
La déstructuration fonctionne aussi avec les tableaux. Supposons un tableau const position = [5, 6, 7, 1]
;
ancien code
const y = position[1]; const z = position[2];
nouveau code
const [, y, z] = position;
La déstructuration fonctionne également dans les arguments de fonction
const dims = {width: 300, height: 150}; const vector = [3, 4]; function lengthOfVector([x, y]) { return Math.sqrt(x * x + y * y); } const dist = lengthOfVector(vector); // dist = 5 function area({width, height}) { return width * height; } const a = area(dims); // a = 45000
ancien code
const width = 300; const height = 150; const obj = { width: width, height: height, area: function() { return this.width * this.height }, };
nouveau code
const width = 300; const height = 150; const obj = { width, height, area() { return this.width * this.height; }, };
...
Le paramètre rest peut être utilisé pour consommer un nombre quelconque de paramètres. Exemple
function log(className, ...args) { const elem = document.createElement('div'); elem.className = className; elem.textContent = args.join(' '); document.body.appendChild(elem); }
L'opérateur spread peut être utilisé pour étendre un itérable en arguments
const position = [1, 2, 3]; someMesh.position.set(...position);
ou copier un tableau
const copiedPositionArray = [...position]; copiedPositionArray.push(4); // [1,2,3,4] console.log(position); // [1,2,3] position n'est pas affectée
ou pour fusionner des objets
const a = {abc: 123}; const b = {def: 456}; const c = {...a, ...b}; // c est maintenant {abc: 123, def: 456}
class
La syntaxe pour créer des objets de type classe avant ES5 était peu familière à la plupart
des programmeurs. À partir d'ES5, vous pouvez maintenant utiliser le mot-clé class
qui est plus proche du style C++/C#/Java.
Les getters et
setters sont
courants dans la plupart des langages modernes. La syntaxe class
d'ES5 les rend beaucoup plus faciles qu'avant ES5.
C'est particulièrement utile avec les callbacks et les promises.
loader.load((texture) => { // utiliser la texture });
Les fonctions fléchées lient this
au contexte dans lequel vous créez la fonction fléchée.
const foo = (args) => {/* code */};
est un raccourci pour
const foo = (function(args) {/* code */}).bind(this));
Voir le lien ci-dessus pour plus d'informations sur this
.
Les Promises aident avec le code asynchrone. Async/await aident à utiliser les promises.
C'est un sujet trop vaste pour être abordé ici, mais vous pouvez lire sur les promises ici et sur async/await ici.
Les littéraux de gabarit sont des chaînes utilisant des accents graves (backticks) au lieu de guillemets.
const foo = `this is a template literal`;
Les littéraux de gabarit ont fondamentalement 2 fonctionnalités. La première est qu'ils peuvent être multi-lignes
const foo = `this is a template literal`; const bar = "this\nis\na\ntemplate\nliteral";
foo
et bar
ci-dessus sont identiques.
L'autre est que vous pouvez sortir du mode chaîne et insérer des fragments de
JavaScript en utilisant ${javascript-expression}
. C'est la partie gabarit. Exemple :
const r = 192; const g = 255; const b = 64; const rgbCSSColor = `rgb(${r},${g},${b})`;
ou
const color = [192, 255, 64]; const rgbCSSColor = `rgb(${color.join(',')})`;
ou
const aWidth = 10; const bWidth = 20; someElement.style.width = `${aWidth + bWidth}px`;
Bien que vous soyez libre de formater votre code comme bon vous semble, il existe au moins une convention dont vous devriez être conscient. Les variables, noms de fonctions, noms de méthodes, en JavaScript sont tous en lowerCasedCamelCase. Les constructeurs, les noms de classes sont en CapitalizedCamelCase. Si vous suivez cette règle, votre code correspondra à la plupart des autres codes JavaScript. Beaucoup de linters, des programmes qui vérifient les erreurs évidentes dans votre code, vous signaleront des erreurs si vous utilisez la mauvaise casse, car en suivant la convention ci-dessus, ils peuvent savoir quand vous utilisez quelque chose de manière incorrecte.
const v = new vector(); // clairement une erreur si toutes les classes commencent par une majuscule const v = Vector(); // clairement une erreur si toutes les fonctions commencent par une minuscule.
Bien sûr, utilisez l'éditeur que vous voulez, mais si vous ne l'avez pas essayé, envisagez d'utiliser Visual Studio Code pour JavaScript et après l'avoir installé, configurez eslint. Cela pourrait prendre quelques minutes à configurer, mais cela vous aidera énormément à trouver les bugs dans votre JavaScript.
Quelques exemples
Si vous activez la règle no-undef
alors
VSCode via ESLint vous avertira de nombreuses variables non définies.
Ci-dessus, vous pouvez voir que j'ai mal orthographié doTheThing
en doThing
. Il y a un trait ondulé rouge
sous doThing
et en survolant, il me dit qu'il n'est pas défini. Une erreur
évitée.
Si vous utilisez des balises <script>
pour inclure three.js, vous recevrez des avertissements en utilisant THREE
, alors ajoutez /* global THREE */
en haut de vos
fichiers JavaScript pour dire à eslint que THREE
existe. (ou mieux, utilisez import
😉)
Ci-dessus, vous pouvez voir qu'eslint connaît la règle selon laquelle les UpperCaseNames
sont des constructeurs
et que vous devriez donc utiliser new
. Une autre erreur détectée et évitée. C'est la
règle new-cap
.
Il existe des centaines de règles que vous pouvez activer ou désactiver ou
personnaliser. Par exemple, j'ai mentionné ci-dessus que vous
devriez utiliser const
et let
plutôt que var
.
Ici, j'ai utilisé var
et il m'a averti que je devrais utiliser let
ou const
Ici, j'ai utilisé let
, mais il a vu que je ne changeais jamais la valeur, alors il a suggéré que j'utilise const
.
Bien sûr, si vous préférez continuer à utiliser var
, vous pouvez simplement désactiver cette règle.
Comme je l'ai dit ci-dessus, je préfère utiliser const
et let
plutôt que var
car ils
fonctionnent mieux et préviennent les bugs.
Dans les cas où vous avez vraiment besoin de outrepasser une règle, vous pouvez ajouter des commentaires pour les désactiver pour une seule ligne ou une section de code.
La plupart des navigateurs modernes sont mis à jour automatiquement, donc l'utilisation de toutes ces fonctionnalités vous aidera à être productif et à éviter les bugs. Cela dit, si vous êtes sur un projet qui doit absolument prendre en charge les anciens navigateurs, il existe des outils qui prendront votre code ES5/ES6/ES7 et le transpileront vers du JavaScript pré-ES5.