issue148:inkscape
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue148:inkscape [2019/09/02 11:48] – créée auntiee | issue148:inkscape [2019/09/14 15:09] (Version actuelle) – d52fr | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | So far in this series, we’ve used some JavaScript to change the fill or stroke color of an object in an SVG file when loaded in a web browser. But JavaScript in SVG is the same language, powered by the same engine, as JavaScript in HTML. That makes it a powerful tool for doing far more than just tweaking some colors. | + | **So far in this series, we’ve used some JavaScript to change the fill or stroke color of an object in an SVG file when loaded in a web browser. But JavaScript in SVG is the same language, powered by the same engine, as JavaScript in HTML. That makes it a powerful tool for doing far more than just tweaking some colors.** |
+ | |||
+ | Jusqu' | ||
+ | |||
+ | **First, a quick reminder of the structure of an XML tag, of the sort you might find in an SVG file:** | ||
+ | |||
+ | Tout d' | ||
- | First, a quick reminder of the structure of an XML tag, of the sort you might find in an SVG file: | ||
<tagName id=" | <tagName id=" | ||
- | Let’s look at each part of this individually: | + | **Let’s look at each part of this individually: |
- | • tagName – The name of the tag or element. In SVG, this might be a ‘g’ for a group, or ‘rect’ for a rectangle or square, for example. | + | |
- | • id – This is just an attribute that happens to be named ‘id’, but the rules of XML dictate that IDs must be unique within a document. That makes them handy for targeting with the querySelector() function. | + | Examinons chaque partie individuellement : |
- | • attributeName – Each tag may have zero or more attributes which contain additional data associated with the element. In XML languages, these always take the form of attributeName=" | + | |
- | • textContent – This is not so common in XML. Usually, an element will contain zero or more child elements before the closing tag (the </ | + | **• tagName – The name of the tag or element. In SVG, this might be a ‘g’ for a group, or ‘rect’ for a rectangle or square, for example.** |
+ | |||
+ | • tagName - Le nom de la balise ou de l' | ||
+ | |||
+ | ** • id – This is just an attribute that happens to be named ‘id’, but the rules of XML dictate that IDs must be unique within a document. That makes them handy for targeting with the querySelector() function. | ||
+ | |||
+ | • id - C'est juste un attribut qui s' | ||
+ | |||
+ | ** • attributeName – Each tag may have zero or more attributes which contain additional data associated with the element. In XML languages, these always take the form of attributeName=" | ||
+ | |||
+ | • attributeName - Chaque balise peut avoir zéro attribut ou plus qui contiennent des données supplémentaires associées à l' | ||
+ | |||
+ | ** • textContent – This is not so common in XML. Usually, an element will contain zero or more child elements before the closing tag (the </ | ||
+ | |||
+ | • textContent - Ce n'est pas si commun en XML. Habituellement, | ||
+ | |||
+ | ** There are also a couple of variations to be aware of. Self-closing tags take the form <tagName … />. By definition these can have no children or text content. XML documents also make use of namespaces, which are defined in the main tag for the document (e.g. the <svg> tag), and may then crop up appended to tags and attributes with a colon. You won’t see these often: usually a default namespace is declared, in which case namespaces need to be added only to tags and attributes that are from ‘foreign’ XML languages. ** | ||
+ | |||
+ | Il y a aussi quelques variations à prendre en compte. Les balises à fermeture automatique prennent la forme < | ||
- | There are also a couple of variations to be aware of. Self-closing tags take the form <tagName … />. By definition these can have no children or text content. XML documents also make use of namespaces, which are defined in the main tag for the document (e.g. the <svg> tag), and may then crop up appended to tags and attributes with a colon. You won’t see these often: usually a default namespace is declared, in which case namespaces need to be added only to tags and attributes that are from ‘foreign’ XML languages. | + | ** The theory is fine, but let’s see how these parts manifest themselves with yet another super-simplified SVG file: ** |
- | The theory is fine, but let’s see how these parts manifest themselves with yet another | + | La théorie est bonne, mais voyons comment ces parties se présentent avec un autre fichier SVG super-simplifié |
<svg xmlns=" | <svg xmlns=" | ||
Ligne 20: | Ligne 43: | ||
</ | </ | ||
- | Breaking this down, we have an <svg> tag containing a < | + | **Breaking this down, we have an <svg> tag containing a < |
- | The < | + | En décomposant cet exemple, nous avons une balise <svg> contenant une balise |
- | Finally the < | + | **The < |
- | Save the file and load it into a web browser – preferably Firefox or Chrome, as they have better developer tools than most others. From the previous articles, you already know how to add JavaScript to your SVG file, either directly in Inkscape or by linking to an external JS file, but we won’t be doing that today. For the rest of this article, we’re going to rattle through a few ways you can affect your SVG, but we’ll do so within the browser’s developer tools. Any of these commands or techniques can be added to your own JavaScript if you want to create something less ephemeral. | + | La balise < |
- | Press F12 or use the menu to open your browser’s developer tools. Somewhere along the top should be a row of tabs (though they’re not always clearly styled as such). Make sure you have the “Console” tab selected. If the panel is already filled with text, find the button in the console’s toolbar to clear it, for clarity. Click inside the console area to give it the focus, and type the following (followed by the Enter key): | + | **Finally the < |
+ | |||
+ | Enfin, la balise < | ||
+ | |||
+ | **Save the file and load it into a web browser – preferably Firefox or Chrome, as they have better developer tools than most others. From the previous articles, you already know how to add JavaScript to your SVG file, either directly in Inkscape or by linking to an external JS file, but we won’t be doing that today. For the rest of this article, we’re going to rattle through a few ways you can affect your SVG, but we’ll do so within the browser’s developer tools. Any of these commands or techniques can be added to your own JavaScript if you want to create something less ephemeral.** | ||
+ | |||
+ | Sauvegardez le fichier et chargez-le dans un navigateur Web - de préférence Firefox ou Chrome, car ils disposent de meilleurs outils de développement que la plupart des autres navigateurs. Dans les articles précédents, | ||
+ | |||
+ | **Press F12 or use the menu to open your browser’s developer tools. Somewhere along the top should be a row of tabs (though they’re not always clearly styled as such). Make sure you have the “Console” tab selected. If the panel is already filled with text, find the button in the console’s toolbar to clear it, for clarity. Click inside the console area to give it the focus, and type the following (followed by the Enter key):** | ||
+ | |||
+ | Appuyez sur F12 ou utilisez le menu pour ouvrir les outils de développement de votre navigateur. Quelque part en haut de l’écran, il devrait y avoir une rangée d' | ||
var t = document.querySelector("# | var t = document.querySelector("# | ||
- | The console will display the string “undefined” at this point. That’s nothing to worry about, it just indicates that the line you entered didn’t return a value. But what it has done is find the element with an ID of “text” and assign it to the variable “t”. You can confirm that by typing the letter “t” on its own, then pressing Enter. The console should show a representation of the < | + | **The console will display the string “undefined” at this point. That’s nothing to worry about, it just indicates that the line you entered didn’t return a value. But what it has done is find the element with an ID of “text” and assign it to the variable “t”. You can confirm that by typing the letter “t” on its own, then pressing Enter. The console should show a representation of the < |
+ | |||
+ | La console affichera la chaîne de caractères « undefined » à ce point. Il n'y a pas de quoi s' | ||
- | Let’s use some JavaScript we already know to reduce the size of the font a little. Type this into the console: | + | **Let’s use some JavaScript we already know to reduce the size of the font a little. Type this into the console: |
+ | |||
+ | Utilisons un peu de JavaScript que nous connaissons déjà pour réduire un peu la taille de la police. Tapez ceci dans la console : | ||
t.style.fontSize = " | t.style.fontSize = " | ||
- | The SVG content should react as soon as you press the Enter key. Type the letter “t” again and you’ll see that the element now has a “style” attribute with the font-size property set. Notice that we set “fontSize” in JS, but the CSS in the attribute shows “font-size”. If you tried to use the latter in JavaScript, it would be interpreted as trying to subtract the “size” variable from the “font” variable, and would throw an error. As a general rule, any CSS property containing embedded hyphens is available as a JavaScript property by removing the hyphens and capitalising the first letter of all but the first word. | + | **The SVG content should react as soon as you press the Enter key. Type the letter “t” again and you’ll see that the element now has a “style” attribute with the font-size property set. Notice that we set “fontSize” in JS, but the CSS in the attribute shows “font-size”. If you tried to use the latter in JavaScript, it would be interpreted as trying to subtract the “size” variable from the “font” variable, and would throw an error. As a general rule, any CSS property containing embedded hyphens is available as a JavaScript property by removing the hyphens and capitalising the first letter of all but the first word.** |
+ | |||
+ | Le contenu SVG devrait réagir dès que vous appuyez sur la touche Entrée. Tapez à nouveau la lettre « t » et vous verrez que l' | ||
+ | |||
+ | **Breaking down the line above, you know that “t” is a JavaScript representation of our XML node. The browser exposes various properties and methods (functions tied to a specific object) on that node, including the “style” property. This property, in turn, has a “fontSize” property, which we’ve set to a value of “10px”. But the browser treats the “style” property a little differently to most JavaScript properties, and instead also applies any changes to the “style” attribute in the XML. In this instance, it doesn’t matter whether you change the attribute or the property – but that’s not usually the case.** | ||
+ | |||
+ | En décomposant la ligne ci-dessus, vous savez que « t » est une représentation JavaScript de notre nœud XML. Le navigateur expose diverses propriétés et méthodes (fonctions liées à un objet spécifique) sur ce nœud, dont la propriété « style ». Cette propriété, | ||
- | Breaking down the line above, you know that “t” is a JavaScript | + | **To change most attributes, therefore, you can’t just set a correspondingly named JavaScript |
- | To change most attributes, therefore, you can’t just set a correspondingly named JavaScript | + | Pour changer la plupart des attributs, vous ne pouvez donc pas simplement définir une propriété |
t.setAttribute(" | t.setAttribute(" | ||
- | Type “t” again to see the XML, and you’ll notice the “y” attribute now has a value of “20”. We can also retrieve that value using the getAttribute() method: | + | **Type “t” again to see the XML, and you’ll notice the “y” attribute now has a value of “20”. We can also retrieve that value using the getAttribute() method:** |
+ | |||
+ | Tapez à nouveau « t » pour voir le XML, et vous remarquerez que l' | ||
t.getAttribute(" | t.getAttribute(" | ||
// Returns " | // Returns " | ||
- | Remembering that the y-axis in SVG runs from the top of the screen to the bottom, you might be inclined to try some code like this to move the text down by 10 units: | + | **Remembering that the y-axis in SVG runs from the top of the screen to the bottom, you might be inclined to try some code like this to move the text down by 10 units:** |
+ | |||
+ | Rappelez-vous que l'axe des y dans SVG va du haut de l' | ||
var yPos = t.getAttribute(" | var yPos = t.getAttribute(" | ||
t.setAttribute(" | t.setAttribute(" | ||
- | Gah! Where did the text go!? Actually it’s still there, but it’s been positioned so far down in the image that it’s dropped out of the 100x100 viewBox, so isn’t visible. But why is that, when we just wanted to adjust the value from 20 to 30? | + | **Gah! Where did the text go!? Actually it’s still there, but it’s been positioned so far down in the image that it’s dropped out of the 100x100 viewBox, so isn’t visible. But why is that, when we just wanted to adjust the value from 20 to 30?** |
- | The problem is that XML is a text-based system, and doesn’t really have a concept of different data types. All attributes are therefore text strings, regardless of the value you put in, so our call to getAttribute() returns the string “20”, not the number 20. JavaScript then tries to be ‘helpful’ by determining that we’re trying to ‘add’ the number 10 to the string “20”. Since you can’t add a number to a string, it automatically converts the number into a string (“10”), then concatenates the two, to give a result of “2010”. That’s the value we end up putting into the attribute in our setAttribute() call, so our text ends up being moved to a y-position of 2010 units! | + | Bah ! Où est passé le texte ? En fait, il est toujours là, mais il a été positionné si bas dans l' |
- | We can fix this by converting the value returned from getAttribute() into a number. We only want an integer value, so the parseInt() function is the tool to use – but there is also a parseFloat() if you need to deal with decimal fractions. parseInt() has a second parameter for the number base that you should always provide (with a value of 10 for a decimal conversion) to avoid some rare-but-odd corner case bugs when converting certain strings. Entering the following lines into the console should get us the result we were looking for: | + | **The problem is that XML is a text-based system, and doesn’t really have a concept of different data types. All attributes are therefore text strings, regardless of the value you put in, so our call to getAttribute() returns the string “20”, not the number 20. JavaScript then tries to be ‘helpful’ by determining that we’re trying to ‘add’ the number 10 to the string “20”. Since you can’t add a number to a string, it automatically converts the number into a string (“10”), then concatenates the two, to give a result of “2010”. That’s the value we end up putting into the attribute in our setAttribute() call, so our text ends up being moved to a y-position of 2010 units!** |
+ | |||
+ | Le problème est que XML est un système basé sur le texte, et n'a pas vraiment un concept de différents types de données. Tous les attributs sont donc des chaînes de texte, quelle que soit la valeur que vous entrez, donc notre appel à getAttribute() renvoie la chaîne « 20 », pas le nombre 20. JavaScript essaie alors de se rendre « utile » en déterminant que nous essayons d' | ||
+ | |||
+ | **We can fix this by converting the value returned from getAttribute() into a number. We only want an integer value, so the parseInt() function is the tool to use – but there is also a parseFloat() if you need to deal with decimal fractions. parseInt() has a second parameter for the number base that you should always provide (with a value of 10 for a decimal conversion) to avoid some rare-but-odd corner case bugs when converting certain strings. Entering the following lines into the console should get us the result we were looking for:** | ||
+ | |||
+ | Nous pouvons corriger cela en convertissant la valeur retournée par getAttribute() en nombre. Nous voulons seulement une valeur entière, donc la fonction parseInt() est celle à utiliser, mais il y a aussi un parseFloat() si vous avez besoin de traiter des fractions décimales. parseInt() a un second paramètre pour la base de nombres que vous devriez toujours fournir (avec une valeur de 10 pour une conversion décimale) pour éviter certains bugs (cas rares, mais étranges), quand vous convertissez certaines chaînes. Le fait de saisir les lignes suivantes dans la console devrait nous donner le résultat que nous recherchons | ||
t.setAttribute(" | t.setAttribute(" | ||
Ligne 68: | Ligne 121: | ||
t.setAttribute(" | t.setAttribute(" | ||
- | You can run the last three lines repeatedly to move your text down by 10 units each time. | + | **You can run the last three lines repeatedly to move your text down by 10 units each time.** |
+ | |||
+ | Vous pouvez exécuter les trois dernières lignes plusieurs fois pour réduire votre texte de 10 unités à chaque fois. | ||
+ | |||
+ | **Now we know how to get and set attributes, but you can also remove them entirely. This will get rid of the “style” attribute we indirectly created earlier, returning the text to its ‘natural’ size:** | ||
- | Now we know how to get and set attributes, but you can also remove them entirely. This will get rid of the “style” attribute we indirectly created earlier, returning the text to its ‘natural’ size: | + | Nous savons maintenant comment obtenir et définir les attributs, mais vous pouvez aussi les supprimer entièrement. Cela nous débarrassera de l' |
t.removeAttribute(" | t.removeAttribute(" | ||
- | There’s no equivalent createAttribute() call - setting the value of a non-existent attribute using setAttribute() will automatically create it. Let’s get our style back by manipulating the attribute rather than the property: | + | **There’s no equivalent createAttribute() call - setting the value of a non-existent attribute using setAttribute() will automatically create it. Let’s get our style back by manipulating the attribute rather than the property:** |
+ | |||
+ | Il n'y a pas d' | ||
t.setAttribute(" | t.setAttribute(" | ||
- | As well as working with attributes, you can also dynamically change the text content of an element. Let’s type a few lines into the console to alter the first < | + | **As well as working with attributes, you can also dynamically change the text content of an element. Let’s type a few lines into the console to alter the first < |
+ | |||
+ | En plus d' | ||
var ts1 = document.querySelector("# | var ts1 = document.querySelector("# | ||
Ligne 85: | Ligne 146: | ||
ts1.textContent = "a bit of"; | ts1.textContent = "a bit of"; | ||
- | [relevant image shown above] | + | **[relevant image shown above]** |
- | Being able to change the text content via JavaScript opens up a world of possibilities, | + | |
+ | [voir illustration ci-dessous] | ||
+ | |||
+ | **Being able to change the text content via JavaScript opens up a world of possibilities, | ||
+ | |||
+ | Être capable de modifier le contenu du texte via JavaScript ouvre un monde de possibilités, | ||
ts1.textContent = prompt(" | ts1.textContent = prompt(" | ||
- | [relevant image shown below] | + | **[relevant image shown below]** |
+ | |||
+ | [voir illustration ci-dessous] | ||
+ | |||
+ | **Modifying the properties, attributes and text content of existing elements is useful, but to have complete control over a document we also need to be able to add and remove elements using JavaScript. The removal part is trivial, provided you can get a reference to the element using querySelector() or some other mechanism. Let’s delete our first < | ||
- | Modifying the properties, attributes and text content of existing elements is useful, but to have complete control over a document | + | Modifier les propriétés, les attributs et le contenu textuel des éléments existants est utile, mais pour avoir un contrôle complet sur un document, nous devons également pouvoir ajouter et supprimer des éléments en utilisant |
ts1.remove(); | ts1.remove(); | ||
- | Adding a new element to the page can be trivially easy, or it can be rather convoluted. Let’s start with the easy method, by adding another < | + | **Adding a new element to the page can be trivially easy, or it can be rather convoluted. Let’s start with the easy method, by adding another < |
+ | |||
+ | Ajouter un nouvel élément à la page peut être vraiment facile ou plutôt compliqué. Commençons par la méthode facile, en ajoutant un autre < | ||
t.innerHTML += '< | t.innerHTML += '< | ||
- | Even though we’re working on an SVG file, which is a form of XML document, we still have to use the “innerHTML” property. This returns all the descendants of the specified node as a string – basically a string of HTML (or XML in this case) much like the ones you type into a text editor. The “+=” operator essentially retrieves a value, adds or concatenates something to it, and puts the result back into the same place. In our case it has the effect of appending a new < | + | **Even though we’re working on an SVG file, which is a form of XML document, we still have to use the “innerHTML” property. This returns all the descendants of the specified node as a string – basically a string of HTML (or XML in this case) much like the ones you type into a text editor. The “+=” operator essentially retrieves a value, adds or concatenates something to it, and puts the result back into the same place. In our case it has the effect of appending a new < |
+ | |||
+ | Même si nous travaillons sur un fichier SVG, qui est une forme de document XML, nous devons quand même utiliser la propriété « innerHTML ». Cela retourne tous les descendants du nœud spécifié sous la forme d'une chaîne de caractères - essentiellement une chaîne de caractères HTML (ou XML dans ce cas-ci) comme celles que vous tapez dans un éditeur de texte. Essentiellement, | ||
+ | |||
+ | **Let’s do something similar, but with a more complex approach…** | ||
+ | |||
+ | Faisons quelque chose de similaire, mais avec une approche plus complexe... | ||
- | Let’s do something similar, but with a more complex approach… | ||
var ns = " | var ns = " | ||
var newTS = document.createElementNS(ns, | var newTS = document.createElementNS(ns, | ||
Ligne 110: | Ligne 187: | ||
t.appendChild(newTS); | t.appendChild(newTS); | ||
- | That’s a lot more lines to explain: | + | **That’s a lot more lines to explain:** |
- | • We set up a variable, “ns”, that will hold our SVG namespace. Usually this is done once at the top of the JavaScript so you can use it in multiple places. | + | |
- | • We create a new < | + | Là, il y a un peu plus de lignes à expliquer : |
- | • We give the element an ID to make it easier to get hold of later. We could have used setAttribute() for this, but the browser has an implicit mapping between the property and attribute in this case, in the same manner as we saw earlier with the ‘style’ property. | + | |
- | • Now we can set an attribute on the new element. We would need to repeat a line like this for each attribute we wish to set. | + | **• We set up a variable, “ns”, that will hold our SVG namespace. Usually this is done once at the top of the JavaScript so you can use it in multiple places.** |
- | • We’ve created a < | + | |
- | • Finally, we append it as a child of the object referred to by the “t” variable – our < | + | • Nous avons mis en place une variable, « ns », qui contiendra notre espace de noms SVG. Habituellement, |
+ | |||
+ | **• We create a new < | ||
+ | |||
+ | • Nous créons un nouvel élément < | ||
+ | |||
+ | **• We give the element an ID to make it easier to get hold of later. We could have used setAttribute() for this, but the browser has an implicit mapping between the property and attribute in this case, in the same manner as we saw earlier with the ‘style’ property.** | ||
+ | |||
+ | • Nous donnons à l' | ||
+ | |||
+ | **• Now we can set an attribute on the new element. We would need to repeat a line like this for each attribute we wish to set.** | ||
+ | |||
+ | • Nous pouvons maintenant définir un attribut sur le nouvel élément. Nous aurions besoin de répéter une ligne comme celle-ci pour chaque attribut que nous souhaitons définir. | ||
+ | |||
+ | **• We’ve created a < | ||
+ | |||
+ | • Nous avons créé un < | ||
+ | |||
+ | **• Finally, we append it as a child of the object referred to by the “t” variable – our < | ||
+ | |||
+ | • Enfin, nous l' | ||
+ | |||
+ | **Clearly that’s a lot more typing than the innerHTML version, so why would you ever want to take this approach? Precisely because it’s verbose, splitting the element, attributes and text content into separate lines, it lends itself to some types of looping or manipulation that can otherwise become unwieldy when using just a single chunk of text.** | ||
+ | |||
+ | De toute évidence, c'est beaucoup plus de code que la version innerHTML, alors pourquoi voudriez-vous adopter cette approche ? Précisément parce qu'il est verbeux, divisant l' | ||
+ | |||
+ | **Consider trying to plot a graph using SVG. Each point on the graph might be represented by a < | ||
+ | |||
+ | Et si vous tentiez de tracer un graphique à l'aide de SVG ? Chaque point du graphique peut être représenté par un < | ||
- | Clearly that’s a lot more typing than the innerHTML version, so why would you ever want to take this approach? Precisely because it’s verbose, splitting | + | **Next time, we’ll build on the techniques used in this instalment, to further investigate ways to manipulate |
- | Consider trying to plot a graph using SVG. Each point on the graph might be represented by a < | + | La prochaine fois, nous nous appuierons sur les techniques utilisées dans cet article pour étudier, un peu plus en avant, les moyens de manipuler les éléments individuels d'un document |
- | Next time, we’ll build on the techniques used in this instalment, to further investigate ways to manipulate the individual elements in an SVG document through | + | |
issue148/inkscape.1567417700.txt.gz · Dernière modification : 2019/09/02 11:48 de auntiee