issue143:inkscape
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue143:inkscape [2019/03/31 15:30] – créée auntiee | issue143:inkscape [2019/04/15 09:50] (Version actuelle) – auntiee | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | Last time, we looked at some very basic JavaScript to alert or log a message when you click on an object in your drawing, or move the mouse over it. The one-line boxes in the object properties are okay for such short snippets of code, but you wouldn’t want to write anything too complex in there. Instead, Inkscape has a couple of other mechanisms for using larger amounts of code in your page: embedded scripts and external scripts. | + | **Last time, we looked at some very basic JavaScript to alert or log a message when you click on an object in your drawing, or move the mouse over it. The one-line boxes in the object properties are okay for such short snippets of code, but you wouldn’t want to write anything too complex in there. Instead, Inkscape has a couple of other mechanisms for using larger amounts of code in your page: embedded scripts and external scripts. |
- | Both of these features live in the Document Properties dialog, so open that first (File > Document Properties, or CTRL-SHIFT-D), | + | Both of these features live in the Document Properties dialog, so open that first (File > Document Properties, or CTRL-SHIFT-D), |
- | In my opinion, there are a few issues with the UI in this dialog. You might think you can just go ahead and type some JavaScript | + | La dernière fois, nous avons regardé un peu de JavaScript |
- | Let’s create a new entry by clicking the “+” button, then select it and enter a little JavaScript into the bottom. We’ll just call the alert() function a couple of times at this point. | + | Ces deux fonctionnalités vivent dans le dialogue des Propriétés du document ; aussi, ouvrons-le en premier |
- | Note that our alert() calls finish with semicolons, so the JavaScript interpreter knows where one statement ends and the next begins. Save your file, and open it directly in a web browser. You should immediately see two messages appear, even before | + | **In my opinion, there are a few issues with the UI in this dialog. You might think you can just go ahead and type some JavaScript into the “Content” section, but that won’t actually create anything in your file. Instead you must first either select an existing entry from the “Embedded script files” section, or create a new one using the “+” button |
- | Now repeat the process to create a second embedded script file, with similar alert() calls, but the message changed to ‘Second embedded script…’. Save your file, and reload | + | Let’s |
- | One way around this problem is to just use a single embedded script, and manually reorder your lines in the Content box. Multiple scripts are all just concatenated together by the browser anyway, so whether you use a single script, or a hundred, it doesn’t matter from a JavaScript perspective. Note, however, that the Content box is a little short, and can’t be resized (another UI fail). If you want to put a lot of code into your file, then, being able to see only a tiny sliver of it at a time will make it rather difficult to work on. | + | De mon point de vue, il y a quelques problèmes dans l' |
- | Usually, the ordering of the scripts isn’t too much of a problem, as JavaScript | + | Créons une nouvelle entrée en cliquant sur le bouton « + », puis sélectionnons-la et saisissons un peu de JavaScript |
- | In a new file, create a simple object – a square or circle – with a visible stroke and an obvious fill color. I’ve stuck with the red rounded rectangle I used last time. Now create a new embedded script file, with the following content: | + | **Note that our alert() calls finish with semicolons, so the JavaScript interpreter knows where one statement ends and the next begins. Save your file, and open it directly in a web browser. You should immediately see two messages appear, even before the content of your document is rendered. JavaScript statements entered like this – outside of any function – are part of the global scope, and are executed as soon as the file is loaded. |
+ | |||
+ | Now repeat the process to create a second embedded script file, with similar alert() calls, but the message changed to ‘Second embedded script…’. Save your file, and reload it in your web browser (F5). You should see four messages displayed in succession – but, if you read the details, you’ll notice that the ones from your second script are displayed first! This is something to be very careful with: the scripts appear in the XML file, and are therefore processed by the browser, in the order they appear in the list, not in the order you created them. In another UI faux-pas, however, it’s not possible to re-order the scripts in this dialog.** | ||
+ | |||
+ | Notez que nos appels avec alert() finissent avec des points-virgules, | ||
+ | |||
+ | Maintenant, répétons ce processus pour créer un second fichier de script incorporé, avec des appels alert() identiques, mais le message change pour « Second programme incorporé ». Sauvegardez votre fichier et rechargez-le dans votre navigateur Web (F5). Vous devriez voir quatre messages affichés l'un derrière l' | ||
+ | |||
+ | **One way around this problem is to just use a single embedded script, and manually reorder your lines in the Content box. Multiple scripts are all just concatenated together by the browser anyway, so whether you use a single script, or a hundred, it doesn’t matter from a JavaScript perspective. Note, however, that the Content box is a little short, and can’t be resized (another UI fail). If you want to put a lot of code into your file, then, being able to see only a tiny sliver of it at a time will make it rather difficult to work on. | ||
+ | |||
+ | Usually, the ordering of the scripts isn’t too much of a problem, as JavaScript code is typically arranged into functions. The order in which the code executes then depends on the sequence in which the functions are called, not the order they appear in the file. This also goes some way to explaining why the fields in the Interactivity section of the Object Properties dialog allow only a single line of code: typically they have to make only a single call to execute a separate multi-line function. As an example of this, let’s use a function in an embedded script to change the fill color of an object when it’s clicked on.** | ||
+ | |||
+ | Une façon de contourner ce problème est de n' | ||
+ | |||
+ | Habituellement, | ||
+ | |||
+ | **In a new file, create a simple object – a square or circle – with a visible stroke and an obvious fill color. I’ve stuck with the red rounded rectangle I used last time. Now create a new embedded script file, with the following content: | ||
function change_to_blue(elem) { | function change_to_blue(elem) { | ||
Ligne 25: | Ligne 41: | ||
change_to_blue(this); | change_to_blue(this); | ||
- | Save and reload your file, then click on your red object. It should turn to blue. See, interactive SVG isn’t so tricky after all! | + | Save and reload your file, then click on your red object. It should turn to blue. See, interactive SVG isn’t so tricky after all!** |
- | Try creating more objects, each with a different fill color, but each with the same line in their onclick field. Notice that clicking each one changes the color of only that specific element, thanks to the “this” keyword. | + | Dans un nouveau fichier, créez un simple objet - un rectangle ou un cercle - avec un contour visible et, évidemment, |
+ | |||
+ | function change_to_blue(elem) { | ||
+ | elem.style.fill = ' | ||
+ | } | ||
+ | |||
+ | Nous avons créé une fonction nommée change_to_blue() (changer en bleu) qui prend un seul paramètre que nous avons choisi d' | ||
+ | |||
+ | change_to_blue(this); | ||
+ | |||
+ | Enregistrez et chargez votre fichier, puis cliquez sur l' | ||
+ | |||
+ | **Try creating more objects, each with a different fill color, but each with the same line in their onclick field. Notice that clicking each one changes the color of only that specific element, thanks to the “this” keyword. | ||
Rather than just set the color to blue, how about creating a toggle between two colors each time the object is clicked. The code’s pretty straightforward: | Rather than just set the color to blue, how about creating a toggle between two colors each time the object is clicked. The code’s pretty straightforward: | ||
Ligne 39: | Ligne 67: | ||
} | } | ||
- | If you’re not familiar with JavaScript, be particularly aware of the ‘===’ in the ‘if’ statement: this triple equals means “are both the value and the type of the variable identical? | + | If you’re not familiar with JavaScript, be particularly aware of the ‘===’ in the ‘if’ statement: this triple equals means “are both the value and the type of the variable identical? |
- | This new code is all well and good, but it would be better still if, instead of simply toggling between blue and red, we toggled between blue and whatever color the object previously had. To do this we need to store the old value of the fill color before we change it to blue, then use that stored value when we turn it back again. Fortunately for us, the “elem” reference that is passed in (“this” on the calling element) is a JavaScript ‘Object’ (not the same as an object you draw in Inkscape), which can hold additional custom properties. We’ll dynamically create a new property, called ‘previousFill’ to hold the value of the fill just before we change it. Our toggling code becomes this: | + | Essayez d' |
+ | |||
+ | Plutôt que de régler simplement la couleur sur bleu, créons une bascule entre deux couleurs à chaque fois que l' | ||
+ | |||
+ | function change_to_blue(elem) { | ||
+ | if (elem.style.fill === ' | ||
+ | elem.style.fill = ' | ||
+ | } else { | ||
+ | elem.style.fill = ' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Si vous n' | ||
+ | |||
+ | **This new code is all well and good, but it would be better still if, instead of simply toggling between blue and red, we toggled between blue and whatever color the object previously had. To do this we need to store the old value of the fill color before we change it to blue, then use that stored value when we turn it back again. Fortunately for us, the “elem” reference that is passed in (“this” on the calling element) is a JavaScript ‘Object’ (not the same as an object you draw in Inkscape), which can hold additional custom properties. We’ll dynamically create a new property, called ‘previousFill’ to hold the value of the fill just before we change it. Our toggling code becomes this: | ||
function change_to_blue(elem) { | function change_to_blue(elem) { | ||
Ligne 52: | Ligne 94: | ||
} | } | ||
- | In the “else” section we store the old fill in our ‘previousFill’ property; in the “if” section we use that value instead of the string “red”. Strictly speaking, we should probably also rename the function to toggle_fill() or something similar – but that suggests we could toggle to a color other than blue, which the code doesn’t do at the moment. | + | In the “else” section we store the old fill in our ‘previousFill’ property; in the “if” section we use that value instead of the string “red”. Strictly speaking, we should probably also rename the function to toggle_fill() or something similar – but that suggests we could toggle to a color other than blue, which the code doesn’t do at the moment.** |
- | Let’s extend it a little further so that we can toggle to a different color. By taking an optional second parameter we can let the calling code determine what the toggle color should be, but still fall back to blue as a default. The toggling code becomes this: | + | Ce nouveau code est bien beau, mais il serait encore meilleur si, au lieu de basculer simplement entre le bleu et le rouge, nous basculions entre le bleu et la couleur quelconque que l' |
+ | |||
+ | function change_to_blue(elem) { | ||
+ | if (elem.style.fill === ' | ||
+ | elem.style.fill = elem.previousFill; | ||
+ | } else { | ||
+ | elem.previousFill = elem.style.fill; | ||
+ | elem.style.fill = ' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Dans la section « else », nous stockons le vieux remplissage dans notre propriété « previousFill » ; dans la section « if », nous utilisons cette valeur au lieu de la chaîne « red » (rouge). Strictement parlant, nous devrions probablement aussi renommer la fonction toggle_fill() ou quelque chose du genre - mais ceci suggère que nous pouvons basculer sur une autre couleur que le bleu, ce que le code ne permet pas pour le moment. | ||
+ | |||
+ | **Let’s extend it a little further so that we can toggle to a different color. By taking an optional second parameter we can let the calling code determine what the toggle color should be, but still fall back to blue as a default. The toggling code becomes this: | ||
function toggle_fill(elem, | function toggle_fill(elem, | ||
Ligne 67: | Ligne 122: | ||
} | } | ||
- | Note that we test the color variable to see if it’s the special value ‘undefined’. Note that this is a primitive type in JavaScript, like ‘Number’, | + | Note that we test the color variable to see if it’s the special value ‘undefined’. Note that this is a primitive type in JavaScript, like ‘Number’, |
- | Whenever a parameter is missing in a function call, the corresponding value in the receiving function is given a value of ‘undefined’. By explicitly testing for this, we can therefore decide what to do if the parameter is omitted – in this case use a default value of ‘blue’ instead. There are various ways to handle missing and default parameters in JavaScript, but this particular syntax is clear, robust, and works even in older browsers. | + | Étendons-la un peu plus de sorte que nous puissions basculer vers une autre couleur. En prenant un second paramètre optionnel, nous pouvons laisser le code d' |
+ | |||
+ | function toggle_fill(elem, | ||
+ | if (color === undefined) color = ' | ||
+ | |||
+ | if (elem.style.fill === color) { | ||
+ | elem.style.fill = elem.previousFill; | ||
+ | } else { | ||
+ | elem.previousFill = elem.style.fill; | ||
+ | elem.style.fill = color; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Notez que nous testons la variable de la couleur pour voir si c'est la valeur spéciale « undefined » (indéfinie). Notez que celle-ci est un type de primitive de JavaScript, comme « Number », « String » ou « Object » ; aussi, nous testons pour voir si la couleur est de ce type spécial, et non pour voir s'il y a une chaîne contenant le mot « undefined ». C'est pourquoi il n'y a pas de guillemets autour de ce mot dans le code. | ||
+ | |||
+ | **Whenever a parameter is missing in a function call, the corresponding value in the receiving function is given a value of ‘undefined’. By explicitly testing for this, we can therefore decide what to do if the parameter is omitted – in this case use a default value of ‘blue’ instead. There are various ways to handle missing and default parameters in JavaScript, but this particular syntax is clear, robust, and works even in older browsers. | ||
With this default value in place, the calling code can be any one of these examples: | With this default value in place, the calling code can be any one of these examples: | ||
Ligne 78: | Ligne 148: | ||
toggle_fill(this, | toggle_fill(this, | ||
- | This toggle_fill() function can therefore work with just a single parameter – in which case ‘color’ is undefined and gets set to ‘blue’ – or with two parameters. If the second parameter is explicitly set to ‘undefined’ then it’s the same as using just one parameter; otherwise the value will be used to set the fill color. But see how already, with only a short function like this, we’ve exceeded the number of lines in the Content box in Inkscape. I hope you like coding through a letterbox! | + | This toggle_fill() function can therefore work with just a single parameter – in which case ‘color’ is undefined and gets set to ‘blue’ – or with two parameters. If the second parameter is explicitly set to ‘undefined’ then it’s the same as using just one parameter; otherwise the value will be used to set the fill color. But see how already, with only a short function like this, we’ve exceeded the number of lines in the Content box in Inkscape. I hope you like coding through a letterbox!** |
+ | |||
+ | Chaque fois qu'un paramètre manque dans un appel de fonction, la valeur correspondante reçue dans la fonction est une valeur « undefined ». En testant ceci explicitement, | ||
+ | |||
+ | Cette valeur par défaut mise en place, la fonction d' | ||
+ | |||
+ | toggle_fill(this); | ||
+ | toggle_fill(this, | ||
+ | toggle_fill(this, | ||
+ | toggle_fill(this, | ||
+ | |||
+ | Cette fonction toggle_fill() peut par conséquent fonctionner avec seulement un paramètre - dans ce cas, « color » est indéfinie et devient « blue » - ou avec deux paramètres. Si le second paramètre est explictement réglé sur « undefined », c'est alors identique à l' | ||
+ | |||
+ | **Although this function is a lot more flexible than our original creation, you should be aware that not all valid CSS colors will work in this type of code: rgb() values might get returned by the browser as hexadecimal strings, for example, or the it might change the case, either of which will stop the equality test from working. Code like this, which makes assumptions about data without testing those assumptions rigorously, is fragile and easily broken. But writing this code in a less fragile way isn’t easy, and is certainly outside the scope of this tutorial series. For now you can play around with the code just to get a feel for embedding JavaScript into your SVG files. Next time, however, I’ll show you how to use CSS classes, in conjunction with JavaScript, to make toggling fill colors (and other styles) far more robust.** | ||
+ | |||
+ | Bien que cette fonction est beaucoup plus flexible que notre création de départ, vous devez être conscient que, dans ce type de code, certaines couleurs valides du CCS ne marchent pas : les valeurs rgb() pourraient être retournées par le navigateur comme des chaînes hexadécimales, | ||
- | Although this function is a lot more flexible than our original creation, you should be aware that not all valid CSS colors will work in this type of code: rgb() values might get returned by the browser as hexadecimal strings, for example, or the it might change the case, either of which will stop the equality test from working. Code like this, which makes assumptions about data without testing those assumptions rigorously, is fragile and easily broken. But writing this code in a less fragile way isn’t easy, and is certainly outside the scope of this tutorial series. For now you can play around with the code just to get a feel for embedding JavaScript into your SVG files. Next time, however, I’ll show you how to use CSS classes, in conjunction with JavaScript, to make toggling fill colors (and other styles) far more robust. | ||
issue143/inkscape.1554039052.txt.gz · Dernière modification : 2019/03/31 15:30 de auntiee