issue147:inkscape
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue147:inkscape [2019/07/29 23:19] – créée d52fr | issue147:inkscape [2019/08/12 15:32] (Version actuelle) – andre_domenech | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | Last time, we used a linked JavaScript file to create an SVG file containing a circle that changes color when a button is pressed, when loaded into a web browser. This time, we’ll extend that simple example to show how the combination of SVG and JavaScript is ideal for animated demonstrations, | + | **Last time, we used a linked JavaScript file to create an SVG file containing a circle that changes color when a button is pressed, when loaded into a web browser. This time, we’ll extend that simple example to show how the combination of SVG and JavaScript is ideal for animated demonstrations, |
- | For simplicity, I’ve based this on the file I created for the previous instalment. That means the red light already has an ID (“redCircle”), | + | For simplicity, I’ve based this on the file I created for the previous instalment. That means the red light already has an ID (“redCircle”), |
- | For this demo, we want the dull colored lights to turn bright at the correct times. Let’s forget about the timing for now, and deal with the colors first. With a variation on our existing code, we could easily set each light to a specific color by targeting it using its ID, then setting the “style.fill” property directly. A better approach, in this case, is to use classes. We can set a class for each light onto some ancestor object, and use CSS to apply the right fill. Since classes can be combined, we don’t need a “red-and-amber” class; we can just set the “red” and “amber” classes at the same time. | + | La dernière fois, nous avons utilisé un fichier JavaScript lié pour créer un fichier SVG contenant un cercle qui change de couleur quand on appuie sur un bouton, lorsqu' |
+ | |||
+ | Par simplicité, | ||
+ | |||
+ | **For this demo, we want the dull colored lights to turn bright at the correct times. Let’s forget about the timing for now, and deal with the colors first. With a variation on our existing code, we could easily set each light to a specific color by targeting it using its ID, then setting the “style.fill” property directly. A better approach, in this case, is to use classes. We can set a class for each light onto some ancestor object, and use CSS to apply the right fill. Since classes can be combined, we don’t need a “red-and-amber” class; we can just set the “red” and “amber” classes at the same time. | ||
But before we get too far ahead of ourselves, we need to set some default colors in CSS, so that we can override them later using classes. Open the file in a text editor, and find the < | But before we get too far ahead of ourselves, we need to set some default colors in CSS, so that we can override them later using classes. Open the file in a text editor, and find the < | ||
+ | |||
+ | < | ||
+ | #redCircle { | ||
+ | fill: #800000; | ||
+ | } | ||
+ | | ||
+ | # | ||
+ | fill: #aa4400; | ||
+ | } | ||
+ | | ||
+ | # | ||
+ | fill: #008000; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Pour cette démo, nous voulons que les couleurs ternes des feux deviennent vives aux bons moments. Oublions le séquencement temporel pour l' | ||
+ | |||
+ | Mais avant de nous engager trop loin, nous avons besoin de paramétrer des couleurs par défaut dans le CSS, afin de pouvoir ensuite les remplacer en utilisant les classes. Ouvrez le fichier dans un éditeur de texte et trouvez la section < | ||
< | < | ||
Ligne 21: | Ligne 43: | ||
</ | </ | ||
- | Don’t worry if there’s already content in your < | + | |
+ | **Don’t worry if there’s already content in your < | ||
Now, we need to add the colors that we want to use when each light is turned on. It’s just another set of three styles added to the end of the < | Now, we need to add the colors that we want to use when each light is turned on. It’s just another set of three styles added to the end of the < | ||
+ | |||
+ | ... | ||
+ | |||
+ | .red #redCircle { | ||
+ | fill: ff0000; | ||
+ | } | ||
+ | |||
+ | .amber # | ||
+ | fill: #ff6600; | ||
+ | } | ||
+ | |||
+ | .green # | ||
+ | fill: #00dd00; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Ne vous inquiétez-pas si du contenu existe déjà dans votre bloc < | ||
+ | |||
+ | Maintenant, nous avons besoin d' | ||
... | ... | ||
Ligne 40: | Ligne 82: | ||
</ | </ | ||
- | Each of these rules is similarly structured, and can be read as “set this fill color for the element with a specific ID, but only if one of its ancestors has a specific class”. With this method we can set classes of “red”, “amber” and “green” on some ancestor element of the lights, such as the parent layer, or even on the root <svg> element, in order to activate the lights. So let’s do that… | + | **Each of these rules is similarly structured, and can be read as “set this fill color for the element with a specific ID, but only if one of its ancestors has a specific class”. With this method we can set classes of “red”, “amber” and “green” on some ancestor element of the lights, such as the parent layer, or even on the root <svg> element, in order to activate the lights. So let’s do that… |
We’ve already seen how to use document.querySelector() with an ID to retrieve a particular element. To add our classes to the Inkscape layer would simply be a case of finding the right ID for the relevant <g> element. But to demonstrate a different approach, we’ll get a reference to the root <svg> element instead, then add a class to that. If you followed along last time you should already have a JavaScript file with a buttonPressed() function. Let’s replace the content of that function with this: | We’ve already seen how to use document.querySelector() with an ID to retrieve a particular element. To add our classes to the Inkscape layer would simply be a case of finding the right ID for the relevant <g> element. But to demonstrate a different approach, we’ll get a reference to the root <svg> element instead, then add a class to that. If you followed along last time you should already have a JavaScript file with a buttonPressed() function. Let’s replace the content of that function with this: | ||
+ | |||
+ | function buttonPressed() { | ||
+ | const svg = document.documentElement; | ||
+ | svg.classList.toggle(" | ||
+ | }** | ||
+ | |||
+ | Chacune de ces règles est structurée à l' | ||
+ | |||
+ | Nous avons déjà vu comment utiliser document.querySelector() avec un ID pour retrouver un élément particulier. L' | ||
function buttonPressed() { | function buttonPressed() { | ||
Ligne 49: | Ligne 100: | ||
} | } | ||
- | The document.documentElement property returns the root element of an XML or XML-alike document. In the case of an SVG file, it returns the <svg> element; for an HTML document, it returns the < | ||
- | Replace | + | **The document.documentElement property returns the root element of an XML or XML-alike document. In the case of an SVG file, it returns the <svg> element; for an HTML document, it returns the < |
- | Our traffic light sequence includes one step in which two lights must be illuminated at once – requiring us to set two classes. In an ideal world, the classList.toggle() method would be flexible enough to take a parameter of “red amber”, and toggle both classes. But we’re stuck in a less than ideal world – one in which the classList methods all work with a single class at a time – so to toggle both classes requires the method to be called twice: | + | Replace the word “red” with “amber”, |
+ | |||
+ | La propriété de document.documentElement retourne l' | ||
+ | |||
+ | Remplacez le mot « red » par « amber », sauvegardez le fichier, rechargez la page Web et cliquez à nouveau sur le bouton. Faites ensuite la même chose avec « green » comme nom de classe. Assurez-vous que chaque feu fonctionne comme attendu, avant de poursuivre. | ||
+ | |||
+ | **Our traffic light sequence includes one step in which two lights must be illuminated at once – requiring us to set two classes. In an ideal world, the classList.toggle() method would be flexible enough to take a parameter of “red amber”, and toggle both classes. But we’re stuck in a less than ideal world – one in which the classList methods all work with a single class at a time – so to toggle both classes requires the method to be called twice: | ||
+ | |||
+ | function buttonPressed() { | ||
+ | const svg = document.documentElement; | ||
+ | svg.classList.toggle(" | ||
+ | svg.classList.toggle(" | ||
+ | }** | ||
+ | |||
+ | La séquence de nos feux tricolores comprend un état où deux feux doivent être éclairés en même temps, nous obligeant à régler deux classes. Dans un monde idéal, la méthode classList.toggle() serait assez flexible pour accepter un paramètre « red amber » et faire basculer les deux classes. Mais nous sommes prisonniers de notre monde qui n'est pas idéal, dans lequel les méthodes classList fonctionnent toutes avec une seule classe à la fois ; aussi, pour faire basculer deux classes, nous devons appeler la méthode deux fois : | ||
function buttonPressed() { | function buttonPressed() { | ||
Ligne 61: | Ligne 125: | ||
} | } | ||
- | In our demo we don’t actually want to toggle lights on and off – we just want to set a fixed selection of lights for each step, without having to also turn off lights from the previous step, or call the same method multiple times. Using the classList interface actually makes life more difficult for us, when all we want to do is set the “class” attribute to a specific value. Luckily for us, browsers provide a function for setting the value of an attribute. It’s got the sensible name of setAttribute() and its arguments are the name of the attribute to set, and the value to set it to. Let’s use it to turn on both the red and amber lights: | + | **In our demo we don’t actually want to toggle lights on and off – we just want to set a fixed selection of lights for each step, without having to also turn off lights from the previous step, or call the same method multiple times. Using the classList interface actually makes life more difficult for us, when all we want to do is set the “class” attribute to a specific value. Luckily for us, browsers provide a function for setting the value of an attribute. It’s got the sensible name of setAttribute() and its arguments are the name of the attribute to set, and the value to set it to. Let’s use it to turn on both the red and amber lights: |
svg.setAttribute(" | svg.setAttribute(" | ||
- | If you try this in your code you’ll find that you can turn the lights on, but as we’re no longer using a toggling function you can’t turn them off again without reloading the page. But we’re not really interested in toggling – we want a sequence of particular lights. For that, however, we need a little foray into the history of JavaScript… | + | If you try this in your code you’ll find that you can turn the lights on, but as we’re no longer using a toggling function you can’t turn them off again without reloading the page. But we’re not really interested in toggling – we want a sequence of particular lights. For that, however, we need a little foray into the history of JavaScript…** |
- | Back in the early days of the web, JavaScript was executed as part of the same “thread” as the browser code itself. This meant that the browser would effectively hand over control to the script, and couldn’t update its UI, or respond to input, until the JS code relinquished that control. You might remember the bad old days when a rogue web page could hang the browser, preventing you from doing anything else with either the page itself or the browser UI. So, JavaScript doesn’t contain any instructions to pause execution of the script, as doing so would block the browser entirely. That means we can’t sequence our lights with something as simple as this pseudo-code: | + | En fait, dans notre démo, nous ne voulons pas que les feux s' |
+ | svg.setAttribute(" | ||
+ | |||
+ | Si vous l' | ||
+ | |||
+ | **Back in the early days of the web, JavaScript was executed as part of the same “thread” as the browser code itself. This meant that the browser would effectively hand over control to the script, and couldn’t update its UI, or respond to input, until the JS code relinquished that control. You might remember the bad old days when a rogue web page could hang the browser, preventing you from doing anything else with either the page itself or the browser UI. So, JavaScript doesn’t contain any instructions to pause execution of the script, as doing so would block the browser entirely. That means we can’t sequence our lights with something as simple as this pseudo-code: | ||
+ | |||
+ | svg.setAttribute(" | ||
+ | pause(3000); | ||
+ | svg.setAttribute(" | ||
+ | pause(3000); | ||
+ | svg.setAttribute(" | ||
+ | ...** | ||
+ | Dans les premiers temps du Web, JavaScript était exécuté comme faisant partie du même « thread » (séquence de calcul) que le code du navigateur lui-même. Cela signifiait que le navigateur transmettait vraiment le pilotage au script, et ne pouvait mettre à jour son interface utilisateur, | ||
svg.setAttribute(" | svg.setAttribute(" | ||
Ligne 78: | Ligne 155: | ||
... | ... | ||
- | Instead JavaScript has a function called setTimeout(). This is a mechanism for queuing up a function call for later on. It doesn’t pause execution of the current function, but asks the browser to run another function after at least a certain amount of time has passed. It takes two parameters: a function or reference to a function, and the minimum timeout in milliseconds. With this, we can write a series of functions that call each other in sequence, to create our demo: | + | **Instead JavaScript has a function called setTimeout(). This is a mechanism for queuing up a function call for later on. It doesn’t pause execution of the current function, but asks the browser to run another function after at least a certain amount of time has passed. It takes two parameters: a function or reference to a function, and the minimum timeout in milliseconds. With this, we can write a series of functions that call each other in sequence, to create our demo: |
function buttonPressed() { | function buttonPressed() { | ||
Ligne 95: | Ligne 172: | ||
const svg = document.documentElement; | const svg = document.documentElement; | ||
svg.setAttribute(" | svg.setAttribute(" | ||
+ | }** | ||
+ | |||
+ | À la place, Javascript a une fonction appelée setTimeout(). C'est un mécanisme pour mettre en file d' | ||
+ | |||
+ | function buttonPressed() { | ||
+ | const svg = document.documentElement; | ||
+ | svg.setAttribute(" | ||
+ | setTimeout(redAmber, | ||
} | } | ||
- | That covers the first three steps of the sequence. I’ll leave it as an exercise for the reader to extend it to the full five steps described at the start of the article. | + | function redAmber() { |
+ | const svg = document.documentElement; | ||
+ | svg.setAttribute(" | ||
+ | setTimeout(green, | ||
+ | } | ||
- | With that, our traffic lights demo is almost complete. Clicking the button will begin the sequence, which will stop automatically at the end. All that’s left is a little more work in Inkscape to make the lights look better. Provided you don’t change the CSS we added, or remove the link to the JS file, you’re free to tweak the design as much as you like without fear of the interactivity being broken. Here’s my result, partway through its cycle, after a little work in Inkscape with a few gradients and some lines. | + | function green() { |
+ | const svg = document.documentElement; | ||
+ | svg.setAttribute(" | ||
+ | } | ||
- | Comparing this to the first image in this article shows just how much impact a little extra design work can achieve. But if I’d done all that design work first and only then started adding JavaScript, I would have had to deal with a much more complex SVG file for the few manual edits required. If you possibly can, it’s usually better to focus on the core aspects of your animations or interactions, | + | **That covers the first three steps of the sequence. I’ll leave it as an exercise for the reader to extend it to the full five steps described at the start of the article. |
+ | |||
+ | With that, our traffic lights demo is almost complete. Clicking the button will begin the sequence, which will stop automatically at the end. All that’s left is a little more work in Inkscape to make the lights look better. Provided you don’t change the CSS we added, or remove the link to the JS file, you’re free to tweak the design as much as you like without fear of the interactivity being broken. Here’s my result, partway through its cycle, after a little work in Inkscape with a few gradients and some lines.** | ||
+ | |||
+ | Voilà pour les trois premières étapes de la séquence. Je laisserai, à titre d' | ||
+ | |||
+ | Avec elle, notre démo de feux tricolores est presque complète. En cliquant sur le bouton, la séquence commence et elle s' | ||
+ | |||
+ | **Comparing this to the first image in this article shows just how much impact a little extra design work can achieve. But if I’d done all that design work first and only then started adding JavaScript, I would have had to deal with a much more complex SVG file for the few manual edits required. If you possibly can, it’s usually better to focus on the core aspects of your animations or interactions, | ||
If you’re careful, editing your file in Inkscape shouldn’t break your code and interactions. But because work like this requires flitting back and forth between Inkscape and a text editor, both working on the same file and therefore able to interfere with each other’s contributions, | If you’re careful, editing your file in Inkscape shouldn’t break your code and interactions. But because work like this requires flitting back and forth between Inkscape and a text editor, both working on the same file and therefore able to interfere with each other’s contributions, | ||
- | Next time, we’ll have a quick look at some other options for manipulating SVG using JavaScript, moving beyond a few changes of fill and stroke color into altering other aspects of your images. | + | Next time, we’ll have a quick look at some other options for manipulating SVG using JavaScript, moving beyond a few changes of fill and stroke color into altering other aspects of your images.** |
+ | |||
+ | En le comparant à celui de la première page de cet article, nous voyons l' | ||
+ | |||
+ | Si vous faites attention, la modification de votre fichier dans Inkscape ne détruit pas vos codes et interactions. Mais, parce qu'un tel travail nécessite d' | ||
+ | |||
+ | La prochaine fois, nous regarderons d' | ||
+ | |||
+ | |||
+ | |||
issue147/inkscape.1564435149.txt.gz · Dernière modification : 2019/07/29 23:19 de d52fr