issue194:inkscape
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue194:inkscape [2023/07/01 06:49] – créée d52fr | issue194:inkscape [2023/07/03 17:30] (Version actuelle) – andre_domenech | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | Over the previous few instalments, | + | **Over the previous few instalments, |
Last month, I described a couple of methods by which a browser can be coaxed into showing the extra pages. The first used a little-known version of the URL fragment identifier to target each page by its viewBox values. This doesn’t require the file to be modified, but does need you to dig into the XML to extract the relevant numbers. The second approach modifies the file to manually add < | Last month, I described a couple of methods by which a browser can be coaxed into showing the extra pages. The first used a little-known version of the URL fragment identifier to target each page by its viewBox values. This doesn’t require the file to be modified, but does need you to dig into the XML to extract the relevant numbers. The second approach modifies the file to manually add < | ||
- | Our aim here is to make it easier to access all the pages of an Inkscape document via a web browser. One thing browsers do, which Inkscape doesn’t, is to run JavaScript. So, by adding a small JS function that will be executed when the file is opened in a browser, we can automatically create < | + | Our aim here is to make it easier to access all the pages of an Inkscape document via a web browser. One thing browsers do, which Inkscape doesn’t, is to run JavaScript. So, by adding a small JS function that will be executed when the file is opened in a browser, we can automatically create < |
- | We’ll be using the same multi-page SVG file from last month, consisting of four pages arranged horizontally, with a different background color and content in each. | + | Au cours des derniers numéros, j'ai étudié la nouvelle fonctionnalité |
- | Having created a multi-page Inkscape file, the first thing to do is to save it to disk and open it inside a web browser. This will display only the first page, as expected. As we progress through this code, we’ll log some data to the developer console, so open the dev tools in the browser (typically by pressing F12), and switch to the ‘Console’ tab. Below is how it looks in Firefox on my Ubuntu Mate machine. | + | Le mois dernier, j'ai décrit deux méthodes permettant d' |
- | I’ve talked about adding JavaScript code to Inkscape files in the past, so I won’t go into depth about the options here. For what we’re trying to achieve, we just want a simple chunk of script embedded directly into the file which will run at load time. The easiest way to create this within Inkscape is as follows: | + | Notre objectif ici est de faciliter l' |
+ | |||
+ | |||
+ | **We’ll be using the same multi-page SVG file from last month, consisting of four pages arranged horizontally, | ||
+ | |||
+ | Having created a multi-page Inkscape file, the first thing to do is to save it to disk and open it inside a web browser. This will display only the first page, as expected. As we progress through this code, we’ll log some data to the developer console, so open the dev tools in the browser (typically by pressing F12), and switch to the ‘Console’ tab. Below is how it looks in Firefox on my Ubuntu Mate machine.** | ||
+ | |||
+ | Nous utiliserons le même fichier SVG multipage que le mois dernier, composé de quatre pages disposées horizontalement, | ||
+ | |||
+ | Après avoir créé un fichier Inkscape multipage, la première chose à faire est de l' | ||
+ | |||
+ | |||
+ | **I’ve talked about adding JavaScript code to Inkscape files in the past, so I won’t go into depth about the options here. For what we’re trying to achieve, we just want a simple chunk of script embedded directly into the file which will run at load time. The easiest way to create this within Inkscape is as follows: | ||
• Open the File > Document Properties… dialog | • Open the File > Document Properties… dialog | ||
• | • | ||
Ligne 20: | Ligne 32: | ||
• | • | ||
- | Let’s begin by logging out the existing < | + | Let’s begin by logging out the existing < |
- | It’s not essential to fully understand the workings of this code in order to use it, but I’ll describe it anyway for those who are interested. The first two lines simply set up variables for the namespaces we’ll need. We won’t be using the SVG namespace just yet, but we will require it soon, so this is a good time to introduce it. The third line uses one of the browser’s built-in functions to find all the ‘page’ elements in the Inkscape namespace, and assign them to a variable as a ‘collection’. | + | J'ai déjà parlé de l' |
+ | ••Ouvrez la boîte de dialogue Fichier > Propriétés du document... | ||
+ | ••Passez dans l' | ||
+ | ••Dans cet onglet, choisissez l' | ||
+ | ••Cliquez sur le bouton « + » sous la liste (vide) des scripts intégrés. | ||
+ | ••Vous devriez voir apparaître une nouvelle entrée dans la liste avec un ID quelconque. | ||
+ | ••Assurez-vous que l' | ||
+ | ••Écrivez votre code dans la case « Contenu » en dessous. | ||
+ | ••Vous pouvez enregistrer (Ctrl-S) au fur et à mesure que vous développez, | ||
+ | ••Chaque fois que vous enregistrez le fichier, rechargez-le manuellement dans le navigateur (F5) pour en voir l' | ||
+ | |||
+ | Commençons par déconnecter les éléments < | ||
+ | |||
+ | |||
+ | **It’s not essential to fully understand the workings of this code in order to use it, but I’ll describe it anyway for those who are interested. The first two lines simply set up variables for the namespaces we’ll need. We won’t be using the SVG namespace just yet, but we will require it soon, so this is a good time to introduce it. The third line uses one of the browser’s built-in functions to find all the ‘page’ elements in the Inkscape namespace, and assign them to a variable as a ‘collection’. | ||
For historical and technical reasons, a ‘collection’ is very similar to a JS array, but not quite actually the same thing. These days, JavaScript’s array functions are pretty powerful, so we would really like to create an array from the content of our collection so we can use those functions. The ‘array.from(pages)’ part does exactly that, iterating over each entry in the collection to build up a temporary array. We can then use the ‘forEach’ array method to execute a block of code for each entry in the array. | For historical and technical reasons, a ‘collection’ is very similar to a JS array, but not quite actually the same thing. These days, JavaScript’s array functions are pretty powerful, so we would really like to create an array from the content of our collection so we can use those functions. The ‘array.from(pages)’ part does exactly that, iterating over each entry in the collection to build up a temporary array. We can then use the ‘forEach’ array method to execute a block of code for each entry in the array. | ||
- | The forEach() method expects to have one parameter, and that parameter should be a function. We could build a function elsewhere and pass its name in here, but it’s more common in JS to see ‘anonymous’ functions used for small tasks like this one. In this case, the anonymous function is called once for each element in the array, and, each time it’s called, it’s passed the current element (in a variable we’ve called ‘page’) and the index of that element in the array (‘idx’). The ‘=>’ syntax is used for so-called arrow functions, and can be thought of largely as an alternative to the ‘function’ keyword you might be more familiar with if you haven’t gone near JS for a while. | + | The forEach() method expects to have one parameter, and that parameter should be a function.** |
+ | |||
+ | Il n'est pas indispensable de bien comprendre le fonctionnement de ce code pour pouvoir l' | ||
+ | |||
+ | Pour des raisons historiques et techniques, une « collection » est très similaire à un tableau JS, mais ce n'est pas tout à fait la même chose. De nos jours, les fonctions de tableau de JavaScript sont très puissantes, et nous aimerions donc créer un tableau à partir du contenu de notre collection afin de pouvoir utiliser ces fonctions. C'est exactement ce que fait la partie « array.from(pages) », en itérant par-dessus chaque entrée de la collection pour construire un tableau temporaire. Nous pouvons ensuite utiliser la méthode « forEach » pour exécuter un bloc de code pour chaque entrée du tableau. | ||
+ | |||
+ | La méthode forEach() s' | ||
+ | |||
+ | |||
+ | **We could build a function elsewhere and pass its name in here, but it’s more common in JS to see ‘anonymous’ functions used for small tasks like this one. In this case, the anonymous function is called once for each element in the array, and, each time it’s called, it’s passed the current element (in a variable we’ve called ‘page’) and the index of that element in the array (‘idx’). The ‘=>’ syntax is used for so-called arrow functions, and can be thought of largely as an alternative to the ‘function’ keyword you might be more familiar with if you haven’t gone near JS for a while. | ||
Inside curly braces (‘{…}’) we have the body of the function – just a single line that uses the console.log() function to print the idx and pages values to the developer console. Finally, the last line closes not only the function body, but also the end of the forEach() method. | Inside curly braces (‘{…}’) we have the body of the function – just a single line that uses the console.log() function to print the idx and pages values to the developer console. Finally, the last line closes not only the function body, but also the end of the forEach() method. | ||
- | If you’re not very familiar with JavaScript, then do take a few minutes to try to understand the code above. It’s particularly useful to examine where each pair of brackets (‘(…)’) and braces (‘{…}’) start and end, and what content is inside each one. | + | If you’re not very familiar with JavaScript, then do take a few minutes to try to understand the code above. It’s particularly useful to examine where each pair of brackets (‘(…)’) and braces (‘{…}’) start and end, and what content is inside each one.** |
+ | |||
+ | Nous pourrions créer une fonction ailleurs et passer son nom ici, mais il est plus courant en JS de voir des fonctions « anonymes » utilisées pour de petites tâches comme celle-ci. Dans ce cas, la fonction anonyme est appelée une fois pour chaque élément du tableau et, à chaque fois qu' | ||
+ | |||
+ | À l' | ||
+ | |||
+ | Si vous n' | ||
- | With that code in place, save the file and reload it in the web browser, and you should see something in the console looking similar to this: | + | **With that code in place, save the file and reload it in the web browser, and you should see something in the console looking similar to this: |
The green numbers are the idx values, starting at zero because… well, there are good reasons, but this is not the place to go into them. Suffice to say that most programming languages use zero-based indexing for things like arrays, and JavaScript is no exception. | The green numbers are the idx values, starting at zero because… well, there are good reasons, but this is not the place to go into them. Suffice to say that most programming languages use zero-based indexing for things like arrays, and JavaScript is no exception. | ||
- | Following each green number, you can see an XML representation of each SVG element in the array – the four < | + | Following each green number, you can see an XML representation of each SVG element in the array – the four < |
- | So far, our code hasn’t really achieved very much – just printing the index, and the same nodes we can see in Inkscape’s XML editor. But now that we’ve got a way to grab a handle to each < | + | |
+ | Une fois ce code en place, enregistrez le fichier et rechargez-le dans le navigateur Web. Vous devriez voir quelque chose dans la console qui ressemble à ceci : | ||
+ | |||
+ | Les chiffres verts sont les valeurs idx, qui commencent à zéro parce que... eh bien, il y a de bonnes raisons, mais ce n'est pas l' | ||
+ | |||
+ | Après chaque chiffre vert, vous pouvez voir une représentation XML de chaque élément SVG dans le tableau - les quatre nœuds < | ||
+ | |||
+ | |||
+ | **So far, our code hasn’t really achieved very much – just printing the index, and the same nodes we can see in Inkscape’s XML editor. But now that we’ve got a way to grab a handle to each < | ||
const x = page.getAttribute(' | const x = page.getAttribute(' | ||
Ligne 52: | Ligne 102: | ||
const viewBox = `${x} ${y} ${w} ${h}`; | const viewBox = `${x} ${y} ${w} ${h}`; | ||
- | console.log(viewBox); | + | console.log(viewBox); |
- | Be very careful! The ‘const viewBox’ line uses a feature of JS called ‘template strings’. These are delimited by backticks | + | Jusqu' |
- | All those previous 6 lines should have been added after the existing console.log() and before the closing brace. If you’ve done it correctly, saving the file and reloading it in the browser should show something like this – similar to the previous output, but with the viewBox values displayed after each XML node (see image below). | + | const x = page.getAttribute(' |
- | Now we’ve got all the details we need, it’s time to create a new < | + | const y = page.getAttribute(' |
- | Each < | + | const w = page.getAttribute(' |
+ | |||
+ | const h = page.getAttribute(' | ||
+ | |||
+ | Nous pourrions les déconnecter à ce stade, mais en fin de compte, nous allons vouloir les formater en une chaîne de caractères séparée par des espaces pour les utiliser dans un attribut viewBox. Une ligne de code supplémentaire le fera pour nous, puis nous enregistrerons le résultat : | ||
+ | |||
+ | const viewBox = `${x} ${y} ${w} ${h}` ; | ||
+ | |||
+ | console.log(viewBox) ; | ||
+ | |||
+ | |||
+ | **Be very careful! The ‘const viewBox’ line uses a feature of JS called ‘template strings’. These are delimited by backticks (`) rather than normal quotes or apostrophes. Using this method lets us put our variables directly into the string using the ${} notation, and the JS engine will swap them out for the variables’ values when the code runs. If your log ends up containing the actual ${} string, then you’ve used the wrong type of quotes, and will need to search your keyboard again for the easily-overlooked backtick character. | ||
+ | |||
+ | All those previous 6 lines should have been added after the existing console.log() and before the closing brace. If you’ve done it correctly, saving the file and reloading it in the browser should show something like this – similar to the previous output, but with the viewBox values displayed after each XML node (see image below).** | ||
+ | |||
+ | Soyez très prudent ! La ligne « const viewBox » utilise une caractéristique de JS appelée « template strings ». Celles-ci sont délimitées par des backticks (`) plutôt que par des guillemets normaux ou des apostrophes. L' | ||
+ | |||
+ | Les 6 lignes précédentes auraient dû être ajoutées après le console.log() existant et avant l' | ||
+ | |||
+ | |||
+ | **Now we’ve got all the details we need, it’s time to create a new < | ||
+ | |||
+ | Each < | ||
+ | |||
+ | |||
+ | Maintenant que nous avons tous les détails dont nous avons besoin, il est temps de créer un nouvel élément < | ||
+ | |||
+ | Chaque élément < | ||
+ | |||
+ | |||
+ | **For the sake of simplicity, we’re just going to name the pages ‘page-1’, | ||
const view = document.createElementNS(svgNS, | const view = document.createElementNS(svgNS, | ||
Ligne 72: | Ligne 152: | ||
page.appendChild(view); | page.appendChild(view); | ||
- | With that, the final code should look like this – albeit that you can’t actually see all the lines at once in Inkscape’s unfortunately inflexible editor field (top right). | + | With that, the final code should look like this – albeit that you can’t actually see all the lines at once in Inkscape’s unfortunately inflexible editor field (top right).** |
- | You can optionally remove the console.log() lines if you wish, as they’re purely there for educational and debugging purposes, and have no effect on the actual operation of the code. | + | Par souci de simplicité, |
+ | |||
+ | const view = document.createElementNS(svgNS, | ||
+ | |||
+ | view.setAttribute(' | ||
+ | |||
+ | view.setAttribute(' | ||
+ | |||
+ | Il ne reste plus qu'une chose à faire. Bien que nous ayons créé notre nouvel élément < | ||
+ | |||
+ | page.appendChild(view) ; | ||
+ | |||
+ | Avec cela, le code final devrait ressembler à ceci - bien que vous ne puissiez pas voir toutes les lignes en même temps dans le champ de l' | ||
+ | |||
+ | |||
+ | **You can optionally remove the console.log() lines if you wish, as they’re purely there for educational and debugging purposes, and have no effect on the actual operation of the code. | ||
Now that the code is done, how do you actually use it? Simply load the SVG file directly into your browser, and append ‘# | Now that the code is done, how do you actually use it? Simply load the SVG file directly into your browser, and append ‘# | ||
There we have it: a small chunk of JS that you can add to any multi-page Inkscape file to make the additional pages available via a web browser. What more could you possibly want? | There we have it: a small chunk of JS that you can add to any multi-page Inkscape file to make the additional pages available via a web browser. What more could you possibly want? | ||
- | Quite a bit as it happens. This code is good, but it suffers from a significant limitation: in order for the browser to execute it, the SVG file has to be loaded directly (or within an < | + | Quite a bit as it happens. This code is good, but it suffers from a significant limitation: in order for the browser to execute it, the SVG file has to be loaded directly (or within an < |
+ | |||
+ | Vous pouvez éventuellement supprimer les lignes console.log() si vous le voulez, car elles ne sont là que dans un but éducatif et de mise au propre ; elles n'ont aucun effet dans le fonctionnement réel du code. Maintenant que le code est réalisé, comment vraiment l' | ||
+ | |||
+ | Et voilà : un simple bout de code JS que nous pouvons ajouter à un fichier Inkscape mutipage pour rendre les pages additionnelles disponibles dans un navigateur Web. Que voulez-vous de plus ? | ||
+ | |||
+ | Beaucoup, en fait. Ce code est bon, mais il souffre d'une limitation importante : de façon à ce que le navigateur l' | ||
+ | |||
+ | |||
+ | **Another issue is that we’ve just given each page a rather generic ID. Within Inkscape, it’s possible to name each page – wouldn’t it be nicer if we could use those names when referring to each page, rather than just page-1 and page-2? | ||
+ | |||
+ | Next month, I’ll extend this code a little further to address both these issues. It still won’t give the simple, seamless experience that we could have had if Inkscape natively created named views, but it’s better than being stuck with multi-page files that can display only the first page!** | ||
- | Another issue is that we’ve just given each page a rather generic ID. Within | + | Un autre problème est que nous avons donné à chaque |
- | Next month, I’ll extend this code a little further to address both these issues. It still won’t give the simple, seamless experience that we could have had if Inkscape | + | Le mois prochain, j' |
issue194/inkscape.1688186995.txt.gz · Dernière modification : 2023/07/01 06:49 de d52fr