tag:blogger.com,1999:blog-283897282024-03-08T17:30:39.322-08:00SVG, MPEG-4...Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.comBlogger13125tag:blogger.com,1999:blog-28389728.post-85388078621450580722010-02-10T09:26:00.000-08:002010-02-10T09:40:39.368-08:00Georacing, démonstrateur de télévision interactive sur mobileDans le cadre du projet de recherche Georacing, nous avons mis en oeuvre un démonstrateur de télévision interactive sur mobile.<br />Georacing, c'est d'abord la capture en temps réel de la position de tous les coureurs d'une course cycliste. C'est ensuite l'exploitation, toujours temps réel, de ces données pour produire des images ou fournir des services.<br />Au sein de Telecom Paristech, nous avons proposé de diffuser tout ou partie de ces données en même temps que la vidéo de la course, vers des mobiles, afin de permettre à chacun d'avoir une vision personnalisée de la course en train de s'accomplir. Pour cela, nous avons étudié le potentiel de DIMS, MPEG-4 et SVG pour mettre en oeuvre des interactions graphiques sur de la télévision sur mobile.<br /><br />Voici une vidéo de démonstration (la qualité est meilleure si on va la voir sur le site de Vimeo):<br /><br /><object height="300" width="400"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9323680&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=9323680&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="300" width="400"></embed></object><p><a href="http://vimeo.com/9323680">Démonstrateur du projet de recherche Georacing</a> from <a href="http://vimeo.com/user3139593">moissinac</a> on <a href="http://vimeo.com/">Vimeo</a>.</p><p>Plus d'informations ici<br /><a href="http://eng.trimaran.com/Ingeneering/R-D/GeoRacing" target="_blank" rel="nofollow">eng.trimaran.com/Ingeneering/R-D/GeoRacing</a></p><p><br /></p>Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-62719221946920638842009-12-10T07:46:00.001-08:002009-12-10T07:53:05.712-08:00Manipulate SVG 2D Graphics programmatically with GPAC<span style="font-style: italic;">If you publish a scientific work based on GPAC thank you to mention in the article, mentioning "GPAC: open source multimedia framework" (DOI: 10.1145/1291233.1291452)<br /></span><br /><br />GPAC is a framework, focused on multimedia development, developed by Telecom ParisTech. GPAC is an Open Source project hosted on sourceforge.<br /><br />GPAC has excellent SVG support. (look at the Show grid implementations of SVG).<br /><br />This note is a start point for a series on the use of the GPAC library for manipulating SVG documents programmatically. The first note is about creating a SVG scene by C program and its backup as a file.<br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Create SVG</span></span><br /><br /><span style="font-weight: bold;">Create a scenegraph</span><br /><br />Basically, a SceneGraph? is the object used by the Gpac library to manipulate a graphic scene. The same object is used for MPEG-4 BIFS, Laser, SVG.<br /><br />Declaration:<br /><br /><span style="font-style: italic;">GF_SceneGraph * sg;</span><br /><br />Object creation:<br /><br /><span style="font-style: italic;">sg = gf_sg_new ();</span><br /><br />Now we are ready to put things in the sg object.<br /><br /><span style="font-weight: bold;">Create the root of the SVG document </span><br /><br />SVG elements are handled in the GPAC type SVG_Element. We will create such an element, which we call root as the root SVG document.<br /><br />Declaration<br /><br /><span style="font-style: italic;">SVG_Element * root;</span><br /><br />Creation:<br /><br /><span style="font-style: italic;">root = (SVG_Element *)gf_node_new(sg, TAG_SVG_svg);</span><br /><br />Here, we show that we create the element in the scene graph sg created earlier and that the element created must be of type TAG_SVG_svg. The constants used are defined in the file nodes_svg.h. The constants name is constructed with the prefix TAG_SVG_ followed by the name of the corresponding SVG element. For example, TAG_SVG_circle for the element circle, TAG_SVG_text for the text element.<br /><br />The object is created. As it is the root of our SVG document, this particular role must be reported to GPAC by the following call:<br /><br /><span style="font-style: italic;">gf_sg_set_root_node(sg, (GF_Node *)root);</span><br /><br />In addition, each object created should be recorded at its parent (we shall see later that this is useful in the reuse of objects). As the root has no parent, we pass NULL as parameter. The call is:<br /><br /><span style="font-style: italic;">gf_node_register ((GF_Node *) root, NULL);</span><br /><br />Finally, the root element <svg> of an SVG document must have at least one attribute that associates the SVG namespace.<br /><br /><span style="font-style: italic;">setAttributeNS(root, NULL, "xmlns", "http://www.w3.org/2000/svg");</span><br /><br />This procedure is built on the DOM model. As we are not in an object language, we can not write root.setAttributeNS(...); we pass the object as first parameter of the procedure. The other parameters are similar to those of setAttributeNS DOM. The second is the namespace attribute, the third is the attribute name, the fourth is the attribute value. We will return later on the second parameter, the namespace; for the moment we use the default namespace by passing NULL.<br /><br />Now, an empty SVG document is ready to receive content.<br /><br /><span style="font-size:130%;"><span style="font-weight: bold;">Add content into the document</span></span><br /><br />We'll add a circle in the document.<br /><br />For this, we declare a SVG_Element:<br /><br /><span style="font-style: italic;">SVG_Element *circle;</span><br /><br />then we create it:<br /><br /><span style="font-style: italic;">circle = (SVG_Element *)gf_node_new(sg, TAG_SVG_circle);</span><br /><br />like we created the element <svg> <svg>.<br /><br />We must add it to the list of children of the root:<br /><br /><span style="font-style: italic;">gf_node_list_add_child(&root->children, (GF_Node *)circle);</span><br /><br />Then, as before, register it with its parent:<br /><br /><span style="font-style: italic;">gf_node_register((GF_Node *)circle, (GF_Node *)root);</span><br /><br />Finally, we create a set of attributes that will define the circle<br /><br /><span style="font-style: italic;">setAttributeNS (circle, null, "cx", "200");</span><br /><span style="font-style: italic;">setAttributeNS(circle, NULL, "cy", "100"); setAttributeNS (circle, null, "cy", "100");</span><br /><span style="font-style: italic;">setAttributeNS(circle, NULL, "r", "50"); setAttributeNS (circle, NULL, "r", "50"); </span><br /><br />And here we have an SVG document with a circle.<br /><span style="font-size:130%;"><br /><span style="font-weight: bold;">Generate the corresponding file</span></span><br /><br />To create the file, GPAC has a mechanism called dumper which produces an image of a scene graph.<br /><br />We declare a dump object:<br /><br /><span style="font-style: italic;">GF_SceneDumper *dumper; </span><br /><br />Then we create the SVG dumper:<br /><br /><span style="font-style: italic;">dumper = gf_sm_dumper_new(sg, "test", ' ', GF_SM_DUMP_SVG);</span><br /><br />The first parameter is the SVG scene graph which we will dump. The second parameter is the name of file to generate. The third character is the character used for indentation. The fourth is the type of representation we want to generate, here we are concerned only with dump SVG specified by the constant GF_SM_DUMP_SVG.<br /><br />Finally, we start writing the file:<br /><br /><span style="font-style: italic;">gf_sm_dump_graph(dumper, 0, 0);</span><br /><br />The first parameter is obviously the dump created just before. The other two parameters have no interest in the case of SVG backup.<br /><br /><span style="font-weight: bold;font-size:130%;" >Finish properly </span><br /><br />Finally, we must free the memory occupied by the scene and objects within it. For this one call (provided that the objects be properly integrated into the scene):<br /><br /><span style="font-style: italic;">gf_sg_del (sg);</span><br /><br /><span style="font-weight: bold;font-size:130%;" >To be continued </span><br /><br />In the next few notes, we discuss the display of the created SVG document, the creation of more complex scenes with multiple levels of nested elements, then we'll create a scene with internal and external links.</svg></svg></svg>Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-73231472931966923282009-06-11T09:03:00.000-07:002009-06-23T08:37:49.700-07:00Manipuler du graphique 2D SVG par programme avec GPAC<span style="font-style:italic;">Si vous publiez un travail scientifique qui s'appuie sur GPAC, merci de mentionner GPAC en citant cet article <a href="http://portal.acm.org/citation.cfm?doid=1291233.1291452">"GPAC: open source multimedia framework"</a> (DOI: <a href="http://dx.doi.org/10.1145/1291233.1291452">10.1145/1291233.1291452</a>)</span><br /><br /><a href="http://gpac.sourceforge.net/">GPAC</a> est un environnement de travail sur des développements multimédia porté par Telecom ParisTech. GPAC est un projet Open Source hébergé sur <a href="http://sourceforge.net/">sourceforge</a>.<br /><br />GPAC a un excellent support de SVG. Voir la <a href="http://www.svgi.org/">grille des implémentations de SVG</a>.<br /><br />Je démarre avec ce billet une série concernant l'utilisation de la librairie GPAC pour manipuler des documents <a href="http://fr.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG </a>par programme. Ce premier billet porte sur la création par programme C d'une scène SVG et sa sauvegarde sous forme de fichier.<br /><br /><h1>Créer un SVG</h1><br /><br /><h2>Créer un SceneGraph</h2><br /><br />A la base, l'objet manipulé par la librairie GPAC pour représenter une scène graphique est un SceneGraph. Ce même objet est utilisé pour du MPEG-4 BIFS, du Laser, du SVG.<br /><br />La déclaration:<br /> GF_SceneGraph *sg;<br /><br />La création de l'objet:<br /> sg = gf_sg_new();<br /><br />Maintenant, nous sommes prêt pour mettre des choses dans l'objet sg.<br /><br /><h2>Créer la racine du document SVG</h2><br /><br />Les éléments SVG manipulés dans GPAC sont de type SVG_Element. Nous allons créer un tel élément, que nous nommerons root, en tant que racine du document SVG.<br />La déclaration<br />SVG_Element *root;<br /><br />La création:<br />root = (SVG_Element *)gf_node_new(sg, TAG_SVG_svg);<br /><br />Ici, nous indiquons que nous créons l'élément dans la scène graphique sg créée précédemment et que l'élément créé doit être de type TAG_SVG_svg. Les constantes utilisées sont définies dans le fichier nodes_svg.h. Le nom des constantes est construit avec la racine TAG_SVG_ suivi du nom de l'élément SVG concerné. Par exemple, TAG_SVG_circle pour l'élément circle, TAG_SVG_text pour l'élément text.<br /><br /><br />L'objet est créé. Comme c'est la racine de notre document, ce rôle particulier doit être indiqué à GPAC par l'appel suivant:<br /> gf_sg_set_root_node(sg, (GF_Node *)root);<br /><br />En plus, chaque objet créé doit être comptabilisé au niveau de son parent (nous verrons plus tard que cela est utile dans des réutilisations d'objets). Comme la racine n'a pas de parent, on passe NULL comme paramètre. L'appel est donc: gf_node_register((GF_Node *)root, NULL);<br /><br />Enfin, l'élément <svg> racine d'un document SVG doit posséder au moins un attribut qui lui associe le namespace SVG.<br /> setAttributeNS(root, NULL, "xmlns", "http://www.w3.org/2000/svg");<br /><br />Cette procédure est construite sur le modèle DOM. Comme nous ne sommes pas dans un langage objet, nous ne pouvons pas écrire root.setAttributeNS(...); nous passons l'objet comme premier paramètre de la procédure. Les autres paramètres sont similaires à ceux du setAttributeNS DOM. Le deuxième est le namespace de l'attribut, le troisième est le nom de l'attribut, le quatrième est la valeur de l'attribut. Nous reviendrons plus tard sur le deuxième paramètre, le namespace, pour l'instant nous utilisons le namespace par défaut en passant la valeur NULL.<br /><br />Maintenant, un document SVG vide est prêt à recevoir du contenu.<br /><br /><h2>Ajouter du contenu dans le document</h2><br /><br />Nous allons ajouter un cercle dans le document.<br />Pour cela, nous déclarons un SVG_Element:<br />SVG_Element *circle;<br /><br />puis nous le créons:<br />circle = (SVG_Element *)gf_node_new(sg, TAG_SVG_circle);<br />à la façon dont nous avons créé l'élément <svg>.<br /><br />Nous devons l'ajouter dans la liste des enfants de la racine:<br />gf_node_list_add_child(&root->children, (GF_Node *)circle);<br /><br />Puis, comme précédemment, l'enregistrer auprès de son parent:<br />gf_node_register((GF_Node *)circle, (GF_Node *)root);<br /><br />Enfin, nous créons un ensemble d'attribut qui vont définir le cercle: setAttributeNS(circle, NULL, "cx", "200");<br />setAttributeNS(circle, NULL, "cy", "100");<br />setAttributeNS(circle, NULL, "r", "50");<br /><br />Et, voilà, nous avons un document SVG avec un cercle.<br /><br /><h2>Générer le fichier correspondant</h2><br /><br />Pour créer le fichier, GPAC dispose d'un mécanisme nommé dumper qui permet de sauver une représentation d'une scène graphique.<br />Nous déclarons un objet dumper:<br />GF_SceneDumper *dumper;<br /><br />Puis, nous créons l'objet:<br />dumper = gf_sm_dumper_new(sg, "test", ' ', GF_SM_DUMP_SVG);<br /><br />Le premier paramètre est la scène pour laquelle nous créons un dumper. Le deuxième paramètre est le nom du fichier à générer. Le troisième caractère est le caractère utilisé pour l'indentation. Le quatrième est le type de représentation que nous souhaitons générer; ici, nous ne sommes concernés que par le dump SVG, spécifié par la constante GF_SM_DUMP_SVG.<br /><br />Enfin, nous déclencons la sauvegarde proprement dite:<br />gf_sm_dump_graph(dumper, 0, 0);<br /><br />Le premier paramètre est de façon évidente le dumper créé juste avant. Les deux autres paramètres n'ont pas d'intérêt pour le cas de la sauvegarde SVG.<br /><br /><h2>Finir proprement</h2><br /><br />Enfin, nous devons libérer la mémoire occupée par la scène et les objets qui la composent. Pour cela, un appel suffit (pourvu que les objets aient correctement incorporés dans la scène):<br />gf_sg_del(sg);<br /><br /><h2>A suivre</h2><br /><br />Dans les prochains billets, nous évoquerons l'affichage de la scène créée, la création de scènes plus complexe, avec plusieurs niveaux d'imbrication d'éléments, puis nous créerons une scène avec des liens internes et externes.Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-80468951343594216262008-11-18T02:52:00.000-08:002008-11-18T03:17:05.364-08:00<use>, SVG and OperaUne version française de cet article est disponible:<br />http://svgmpeg4.blogspot.com/2008/11/use-svg-et-opera.html<br /><br />I'm currently testing the advanced possibilities of SVG. For my tests, I'm using mainly <a href="http://gpac.sourceforge.net/">GPAC</a>, <a href="http://www.mozilla-europe.org/fr/firefox/">Firefox</a> and <a href="http://www.opera.com/">Opera</a>; Safari also sometimes. You can find a comparison of implementations at this <a href="http://dev.w3.org/SVG/profiles/1.2T/test/SVGT12-ImpReport.html">link</a>, which is based on the test suite for SVG 1.2 defined by the W3C. Moreover, there is a state of the implementation of SVG in Firefox <a href="http://www.mozilla.org/projects/svg/status.html">here</a>. There is an equivalent for Opera <a href="http://www.opera.com/docs/specs/opera95/svg/">here</a>.<br /><br />The <use element on an external link is an interesting possibility for animation, user interfaces, patterns ...<br /><br />For example, you define a widget with id 'mywidget' in a svg named s1.svg. Then you can use it in another svg with the line:<br /><use xlink:href="s1.svg#mywidget" /><br />This is a simple way to develop projects gradually in a structured way.<br /><br />We will quickly find situations where there is a complex document with an external <use> which itself contains a <use>. For example, you run a widget with a <use>, as above, and this widget itself is defined with a <use> pointing to another file.<br /><br />Following is an example used for testing, based on the structure of a cartoon-type svg: a scene uses a background, itself constructed from various elements.<br /><br />Main.svg file:<br /><svg<br />xmlns: xlink = 'http://www.w3.org/1999/xlink'<br />xmlns: svg = 'http://www.w3.org/2000/svg'<br />xmlns = 'http://www.w3.org/2000/svg'<br />width ='800 'height ='600'<br />><br /><use id='decor' xlink:href="decor.svg#decor"/><br /></ svg><br /><br />File decor.svg (resume the previous tag svg)<br /><svg ...><br /><use id='decor' xlink:href="bulle.svg#circ"/><br /></ svg><br /><br />Bulle.svg file:<br /><svg ... ><br /><circle id='circ' cx='100' cy='100' r='50' fill='red'/><br /></ svg><br /><br />This test works well in GPAC, but not in Firefox 3.0.1, or Opera 9.62.<br /><br />For Firefox, the status page above said about <use>: "Only works for internal document references (bug 269482).", So the external references are not yet supported.<br /><br />For Opera, the first level of external <use> works, contrary to what is said on the Opera site "Note: External references, eg, are not supported." <br /><br />It appears that the lack of common support for external <use> prevents the time when we will systematically structure SVG scenes with <use>.<br /><br />I think I will continue to structure scenes with use and make a xslt transformation seeking use in a document to replace the content. To be continued ...Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-70909934519785142792008-11-18T01:34:00.000-08:002008-11-18T03:16:08.257-08:00Use, SVG et OperaAn english version of this article is available:<br />http://svgmpeg4.blogspot.com/2008/11/svg-and-opera.html<br /><br />Actuellement, je teste des possibilités assez avancées de SVG. Pour mes tests, j'utilise principalement <a href="http://gpac.sourceforge.net/">GPAC</a>, <a href="http://www.mozilla-europe.org/fr/firefox/">Firefox</a> et <a href="http://www.opera.com/">Opera</a> et quelquefois aussi Safari. On peut trouver un comparatif des implémentations à ce <a href="http://dev.w3.org/SVG/profiles/1.2T/test/SVGT12-ImpReport.html">lien</a>; ce comparatif repose sur la suite de tests pour SVG 1.2 définie par le W3C. Par ailleurs, on peut trouver un état de l'implémentation de SVG dans Firefox <a href="http://www.mozilla.org/projects/svg/status.html">ici</a>. On trouve une page équivalente pour Opera <a href="http://www.opera.com/docs/specs/opera95/svg/">ici</a>.<br /><br />L'utilisation de l'élément <use> portant sur un lien externe est une possibilité intéressante pour les animation, les interfaces utilisateurs, les schémas...<br /><br />Par exemple, vous définissez une sorte de widget avec un id 'monwidget'dans un svg nommé s1.svg. Ensuite, vous pouvez l'utiliser dans un autre svg avec la ligne:<br /><use xlink:href="s1.svg#monwidget" /><br />Cela constitue une façon simple de développer des projets peu à peu de façon structurée. <br /><br />On imagine bien qu'assez vite on va se retrouver dans des situations où on construit un document complexe avec un <use> externe qui lui-même contient un <use>. Par exemple, vous exploitez un widget avec un <use>, comme ci-dessus, et ce widget lui-même est défini avec un <use> pointant vers un autre fichier.<br /><br />Voilà un exemple utilisé pour les tests, basé sur une structuration de type dessin animé: une scéne utilise un décor, lui-même construit à partir de divers éléments.<br /><br />Fichier main.svg:<br /><svg<br /> xmlns:xlink='http://www.w3.org/1999/xlink'<br /> xmlns:svg='http://www.w3.org/2000/svg'<br /> xmlns='http://www.w3.org/2000/svg' <br /> width='800' height='600' <br />><br /> <use id='decor' xlink:href="decor.svg#decor"/><br /></svg><br /><br />Fichier decor.svg (reprendre la balise svg précédente)<br /><svg ...><br /> <use id='decor' xlink:href="bulle.svg#circ"/><br /></svg><br /><br />Fichier bulle.svg:<br /><svg ... ><br /> <circle id='circ' cx='100' cy='100' r='50' fill='red'/><br /></svg><br /><br />Ce test fonctionne bien dans GPAC, mais ni dans Firefox 3.0.1, ni dans Opera 9.62. <br /><br />Pour Firefox, la page de status mentionnée plus haut dit au sujet de use: "Only works for internal document references (bug 269482).", donc les références externes ne sont pas encore supportées. <br /><br />Pour Opera, le premier niveau de <use> externe fonctionne, contrairement à ce qui est dit sur le site d'Opera "Note: External references, e.g. <use xlink:href="http://www.mydomain.com/util.svg#rects">, are not supported."; il semble que Opera ne sait pas cascader les use, ce qui, concrètement, empêche pour l'instant d'en avoir un usage systématique pour la structuration des scènes.<br /><br />Je crois que je vais continuer à structurer les scènes avec des use et faire une transformation xslt qui cherche les use dans un document pour les remplacer par le contenu correspondant. A suivre...Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-28820823322019583262008-11-12T05:36:00.000-08:002008-11-18T02:31:30.376-08:00Link and animationWe discuss here about links from a SVG page to another page.<br /><br /><span style="font-style:italic;">Une version française de cet article se trouve à <a href="http://svgmpeg4.blogspot.com/2008/11/lien-sur-animation.html">http://svgmpeg4.blogspot.com/2008/11/lien-sur-animation.html</a>.</span><br /><br />The basic method is to surround a set of graphics primitives by <a ...>, a similar tag to html tag <a ...>. This allows for example to move from one page to another on a click on any part of the group by the primitive surrounded by <a>.<br /><br />But, we would like to go further: a click on an element triggers an animation and, at the end of this animation, we go to another SVG page.<br /><br />There is no simple way to do that.<br /><br />Combined with the animated element which has the 'anim1' id, I'll add the following:<br /><ev:listener target='anim1' event='endEvent' handler='#toOtherSVG' /><br /><br />So when the endEvent will be generated for the animation, the handler named 'toOtherSVG' will be executed.<br /><br />The handler can be defined as follows:<br /><handler xml:id='toOtherSVG' type="application/ecmascript"><br />gotoLocation ( 'otherPage.svg');<br /></ handler><br /><br />There is potentially another method that would be feasible in the future. It is syntactically correct, but its operation is not specified by the current standard (even in the draft Tiny 1.2). As a result, SVG viewers may have a different behavior.<br /><br />Suppose we have the following line<br /><ev:listener event="'endEvent'" handler="'#toOtherSVG'"><br /><br />as before. But the element with id 'toOtherSVG', is not a classic handler but:<br /><a id="'toOtherSVG'" href="'otherPage.svg'"><br />This syntax is correct in SVG Tiny 1.2, but the behavior of the tag <a> as a target of the event is not defined. It would suffice to establish that if <a> tag is the target of an event, we follow the link defined by the tag.<br /><br />Perhaps for a coming release of the SVG specification?Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-65489952666653976352008-11-12T02:59:00.000-08:002008-11-12T05:58:34.438-08:00Lien sur animationLa question abordée ici est celle des liens d'une page SVG vers une autre page.<br /><br />An english version of this article is available:<br /><a href="http://svgmpeg4.blogspot.com/2008/11/link-and-animation.html">http://svgmpeg4.blogspot.com/2008/11/link-and-animation.html</a><br /><br />La méthode de base est d'entourer un ensemble de primitives graphiques par une balise <a ...>, analogue à la balise <a ...> du html. Cela permet par exemple de passer d'une page à une autre sur un clic sur n'importe quelle partie du groupe de primitives ancadrées par le <a>.<br /><br />Mais, cherchons à aller plus loin: un clic sur un élément déclenche une animation et, à la fin de cette animation, on passe à une autre page SVG.<br /><br />Rien ne permet cela de façon directe.<br /><br />Associé à l'élément animé d'id 'anim1', je vais ajouter l'élément suivant:<br /><ev:listener target='anim1' event='endEvent' handler='#versAutreSVG' /><br /><br />Ainsi, quand l'évènement de fin d'animation va être généré, le handler nommé 'versAutreSVG' va être exécuté.<br /><br />Le handler peut être défini ainsi:<br /><handler id="'versAutreSVG'" type="application/ecmascript"><handler xml:id='versChambre' type="application/ecmascript"><br /> gotoLocation('autrePage.svg');<br /></handler></handle<handler id="'versAutreSVG'" type="application/ecmascript">r><br /></handler><br />Il y a potentiellement une autre méthode qui serait envisageable dans le futur. Elle est correcte syntaxiquement, mais son fonctionnement n'est pas spécifié par la norme actuelle (même dans le projet Tiny 1.2). Peut-être pourra-t-on l'introduire par la suite. Il en résulte que des afficheurs SVG différents pourraient avoir un comportement différent.<br /><br />Supposons qu'on a<br /><ev:listener event='endEvent' handler='#versAutreSVG' /><br /><br />comme précédemment. Mais que l'objet d'id versAutrePage, n'est pas un handler classique mais:<br /><a id='versAutrePage' xlink:href='autrePage.svg' /><br />Cette syntaxe est correcte dans SVG Tiny 1.2, mais le comportement de la balise <a> en tant que cible de l'évènement n'est pas défini. Il suffirait de définir que si une balise a est la cible d'un évènement, on suit le lien défini par la balise.<br /><br />Peut-être pour une prochaine version de la spécification SVG?Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-58022664000483729892007-10-25T06:46:00.001-07:002007-10-25T06:50:07.265-07:00SVG dans Google MapsJe viens de découvrir avec surprise que sur un téléphone P990i de Sony Ericsson, l'application Google Maps utilise une applet qui déclare utiliser le produit Tinyline.<br /><br />Et qu'est-ce que <a href="http://www.tinyline.com/">Tinyline</a>: un player SVG.<br /><br />J'en conclue que Google Maps, au moins sur mobile, s'appuie sur SVG. Une grande bonne nouvelle pour cette excellente technologie.Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com1tag:blogger.com,1999:blog-28389728.post-80901799829946972972007-06-25T05:00:00.000-07:002007-06-25T22:01:48.588-07:00Comment GZIP traite vos SVG?Je vous présente ici quelques résultats assez paradoxaux sur l'exploitation de GZIP combinée à du SVG. Ces résultats peuvent surement être transposés pour toute combinaison de GZIP avec une représentation XML.<br /><br /><font style="font-weight: bold;">GZIP et SVG<br /></font><br />GZIP peut être utilisé de plusieurs façons pour comprimer du SVG.<br /><br />D'abord, le support de GZIP est encouragé pour les players SVG 1.1 et requis pour les players SVG 1.2 Tiny; ces players doivent pouvoir lire un document SVG zippé, le décompresser, puis l'interpréter comme s'il n'avait pas été compressé.<br /><br />La deuxième méthode fonctionne pour des documents SVG auxquels le player accède via le Web. Il est possible de régler le serveur pour qu'il comprime en GZIP certains types de fichiers lorsqu'il les envoie à un client qui supporte la compression GZIP. Cela est alors indépendant de la norme SVG et peut s'appliquer à de nombreux types de fichiers.<br /><br /><span style="font-weight: bold;">Optimiser la taille d'un SVG</span><br /><br />L'exploitation de GZIP assure une compression et permet donc d'optimiser la quantité de données transmises.<br /><br />On peut être tenté d'optimiser la taille du fichier au niveau du SVG avant le passage par GZIP. On peut par exemple éliminer des espaces. Et, là commencent les surprises!<br /><br />Par exemple, j'ai pris le fichier SVG qui figure ici. Il fait 274 Ko. En l'ouvrant avec Inkscape, puis le sauvant en GZIP, il passe à 106 Ko. En supprimant des décimales sur de nombreuses coordonnées, l'apparence du SVG ne change pas pour une utilisation plein écran et le fichier passe à 244 Ko. En ouvrant ce dernier avec Inkscape et en le sauvant en GZIP, on obtient un fichier de 115 Ko!!! <br /><br />Ainsi, en optimisant la taille de la source SVG, on obtient un plus mauvais résultat en GZIP.<br /><br />Comment optimiser la compression d'un SVG en GZIP? Avez-vous des idées?Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-1165608443670945182006-12-08T12:00:00.000-08:002006-12-08T12:34:38.536-08:00AJAX pour SVGEn complément à <a href="http://svgmpeg4.blogspot.com/2006/07/un-zeste-de-svg-ajax-et-rex.html">un-zeste-de-svg-ajax-et-rex.html</a>, on peut se poser la question du support de XmlHttpRequest par les différents navigateurs.<br /><br />Plusieurs projets proposent des librairies Javascript pour améliorer le support XML/XSLT dans les navigateurs.<br /><br />Je ne ferais que mentionner ici deux projets significatifs:<br />- Sarissa: <a href="http://sarissa.sourceforge.net/">http://sarissa.sourceforge.net/</a><br />- Google: <a href="http://goog-ajaxslt.sourceforge.net/">http://goog-ajaxslt.sourceforge.net/</a>Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-1160203020490706282006-10-06T23:35:00.000-07:002006-10-07T01:13:33.476-07:00Quel avenir pour SVG?Adobe a annoncé ne plus assurer de support pour son Viewer SVG (ASV) à partir de janvier 2007 et ne plus le distribuer à partir de janvier 2008. Hors ASV était jusqu'à présent le plus utilisable et le plus utilisé des viewers SVG.<br /><br />Je ne reviendrais pas en détail ici de la place importante que prend SVG dans les téléphones mobiles, où une très grosse partie des modèles qui sortent comportent un player SVG (notons par exemple que Nokia recommande aux développeurs d'applications pour téléphone de concevoir leurs interfaces en graphique vectoriel SVG).<br /><br />De nombreux concepteurs d'applications Web se demandent s'ils peuvent encore s'appuyer sur SVG. Sans ASV, il apparait difficile d'afficher du SVG dans Internet Explorer. Si on peut se passer d'Internet Explorer et promouvoir Firefox, la situation parait favorable, mais encore très problématique: en effet, le support SVG de firefox ne permet pas actuellement d'imprimer correctement les documents et le plan de travail ne prévoit pas de résoudre ce problème à court terme (http://developer.mozilla.org/en/docs/SVG_in_Firefox_1.5#Printing). Peut-on encore compter sur SVG?<br /><br />D'abord, on peut espérer que Firefox résolve ses problèmes. Ensuite, d'autres solutions émergent qui pourraient prendre une place laissée par Adobe. Par exemple, le player multimédia Osmo4 -qu'on trouve dans le projet GPAC sur sourceforge, http://gpac.sourceforge.net/- a été récemment décliné sous forme d'un plug-in pour Firefox (Osmozilla) et d'un plug-in pour Internet Explorer.<br /><br />SVG se développe fortement sur mobiles, ASV est encore là pour quelques temps et la relève est sur les starting blocks, alors ce n'est pas le moment d'abandonner une bonne technologie sans équivalent: le graphique vectoriel dans un environnement ouvert.Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com2tag:blogger.com,1999:blog-28389728.post-1153395061119978062006-07-20T04:30:00.000-07:002007-03-14T22:32:10.410-07:00Un zeste de SVG, Ajax et REX<div style="text-align: right;"><span style="font-size:78%;">(c) Jean-Claude Moissinac - ENST Juin 2006</span><br /></div><span style="font-weight: bold;"><br />Résumé</span><br />Dans cette note, je présente une implémentation de REX pour modifier dynamiquement des documents SVG à l'aide de XmlHttpRequest popularisé par AJAX. REX est une grammaire XML simple, proposée par le W3C (<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www.w3.org/TR/rex/" target="_blank">http://www.w3.org/TR/rex/</a>) en février 2006, qui permet de décrire des modifications qu'on veut apporter à un document XML: insertion, remplacement ou suppression de sous-arbre, et changement d'attributs. Grâce à cette implémentation, avec très peu de code Javascript, on peut faire toutes sortes de manipulation d'une page graphique SVG par des commandes issues d'un serveur.<br /><br /><span style="font-weight: bold;">ATTENTION: le paragraphe 'les problèmes avec REX' vers la fin de cette note contient un avertissement potentiellement important pour les développeurs qui utilisent AJAX</span><br /><br /><span style="font-weight: bold;">Abstract</span><br />In this article, I present a REX implementation to modify dynamically SVG documents by means of the XmlHttpRequest function popularized by AJAX. REX is a simple XML grammar, proposed by the W3C (<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www.w3.org/TR/rex/" target="_blank">http://www.w3.org/TR/rex/</a>) in February, 2006, which allows to describe modifications which we want to bring to an XML document: insertion, replacement or deletion of a sub-tree, and change of attributes. Thanks to this implementation, with a short piece of Javascript, we can make many transformation of a graphic SVG page by commands obtained from a server.<br /><br />An english version of this article is available:<br /><a href="http://svgmpeg4.blogspot.com/2006/06/taste-of-rex-ajax-and-svg.html">http://svgmpeg4.blogspot.com/2006/06/taste-of-rex-ajax-and-svg.html</a><br /><br /><span style="font-weight: bold;">ATTENTION: the end of this note contains a warning potentially important for the developers which use AJAX<br /><br />SVG</span><br /><br />SVG signifie Scalable Vector Graphics. Il s'agit d'une grammaire XML, définie par le W3C, qui permet de décrire des documents graphiques, éventuellement animés et interactifs, souvent perçu comme un concurrent de Flash. Nous verrons d'ailleurs dans une prochaine note comment les techniques proposées ici permettent d'exploiter une pratique assez courante des développeurs Flash: envoyer une scène graphique initiale presque vide et la compléter ensuite progressivement en fonction des préférences et des interactions de l'utilisateur, du navigateur utilisé, de la taille de la fenêtre...<br /><br />De nombreux développeurs ont développé au cas par cas leur propre code javascript pour modifier des scènes SVG; nous allons voir ci-après qu'avec très peu de code, on peut avoir une solution générique.<br /><br /><span style="font-weight: bold;"><br />AJAX</span><br /><br />Ajax a popularisé, en lui donnant un nom, la méthode de développement de sites Web dynamiques basée notamment sur l'utilisation par script de la fonction XMLHttpRequest pour récupérer les données permettant de modifier une page sans la recharger (voir par exemple <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php">http://www.adaptivepath.com/publications/essays/archives/000385.php</a>). Une pratique courante consiste à demander au serveur un morceau de page HTML à l'aide de XMLHttpRequest et à l'injecter dans la page courante par simple copie. Cela procure une méthode extrêmement souple et légère pour la réalisation de pages dynamiques.<br /><br />Cette façon de travailler s'applique aussi à des documents SVG. Dans le cas des navigateurs qui supportent l'utilisation d'éléments HTML et SVG dans une même page, on peut même manipuler à la fois le HTML et le SVG par cette méthode; c'est le cas, par exemple, avec les versions courantes du navigateur Firefox.<br /><br /><br /><span style="font-weight: bold;">REX, brève introduction</span><br /><br />La proposition faite pat le W3C est courte et claire. On peut la trouver à l'adresse <a href="http://www.w3.org/TR/rex/">http://www.w3.org/TR/rex/</a>. REX signifie Remote Events for XML.<br /><br />REX utilise une sous-partie de la syntaxe Xpath pour désigner la portion de l'arbre XML que l'on souhaite modifier. Cette sous-partie est simple à comprendre, proche de la description d'un chemin dans une arborescence de dossiers. Par exemple:<br />/ désigne la racine du document<br />/svg/g[3] désigne le troisième élément g directement trouvé comme fils de la racine du document svg (rem.: en svg, g permet de grouper des éléments).<br />id('bouton1') désigne le noeud de l'arbre ayant l'identificateur (id) bouton1<br />id('boutons1')/@fill désigne l'attribut fill de l'élément d'identificateur bouton1<br /><br />On le devine à travers ces exemples, la syntaxe est vite assimilable, au moins pour les utilisations les plus courantes.<br /><br />Une fois que nous savons désigner la partie du document à modifier, voilà quelques exemples simples de modifications possibles:<br /><br /><rex xmlns="http://www.w3.org/2006/rex" ><br /><event target="id('S1')/svg:path[13]" name="DOMNodeRemove"><br /></rex xmlns="http://www.w3.org/2006/rex" ><br /><br />name contient le nom de la commande exécutée, ici DOMNodeRemove sert à supprimer un noeud; dans cet exemple, on supprime donc le treizième noeud path (et son sous-arbre éventuel) trouvé sous l'élément d'identificateur S1.<br />_________________________________________________<br /><br /><event target="id('S1')/svg:text[1]/@fill" name="DOMAttrModified" newvalue="blue"><br /><br />Ici, je ne montre que la ligne centrale changée par rapport au message précédent. DOMAttrModified indique qu'on modifie une valeur d'attribut. L'attribut est l'indication de couleur de remplissage (fill) attribuée au premier noeud text trouvé sous un élément d'identificateur S1; la nouvelle valeur donnée à cet attribut est <span style="font-style: italic;">blue</span><br />_________________________________________________<br /><br /><event target="id('S1')/svg:text/text()" name="DOMCharacterDataModified" newvalue="Texte changé"><br /><br />DOMCharacterDataModified indique qu'on modifie le contenu textuel du premier élément text trouvé sous l'élément d'identificateur S1; la nouvelle valeur est <span style="font-style: italic;">Texte changé<br /></span>_________________________________________________<br /><br />Il est possible de groupe plusieurs modifications:<br /><rex xmlns="http://www.w3.org/2006/rex" ><br /><event target="id('S1')/svg:path[13]" name="DOMNodeRemove"><br /><event target="id('S1')/svg:text[1]/@fill" name="DOMAttrModified" newvalue="blue"><br /><event target="id('S1')/svg:text/text()" name="DOMCharacterDataModified" </rex xmlns="http://www.w3.org/2006/rex" ><br /><br />Les trois modifications précédentes sont groupées dans un seul message REX.<br /><br />Pour plus de précisions, le mieux est surement de regarder les 15 pages de la proposition du W3C.<br /><br />_________________________________________________<br />_________________________________________________<br /><br /><span style="font-weight: bold;">Implémentation en Javascript</span><br /><br />La première chose à faire pour implémenter REX est de disposer de méthodes pour trouver un noeud dans un document à partir d'une expression XPATH supportée par REX. Comme j'avais<br />connaissance de l'implémentation Open Source de XPATH en Javascript effectuée par Google (voir <a href="http://goog-ajaxslt.sourceforge.net/">http://goog-ajaxslt.sourceforge.net/</a>), et que je voulais l'évaluer, j'ai commencé par cette solution. J'y reviendrais surement dans une autre note.<br /><br />Ensuite, j'ai considéré que Firefox assurant à la fois un support de SVG et de XPATH , il était intéressant d'étudier cette solution. C'est elle que nous allons d'abord commenter du fait de l'élégance et de la compacité qu'elle autorise: la totalité du support de REX pour des documents utilisés avec Firefox prend environ 200 lignes de code Javascript.<br /><br />La démonstration peut être vue à l'adresse suivante:<br /><a href="http://shadok.enst.fr:8080/modifxml/purMozilla/index.htm">http://shadok.enst.fr:8080/modifxml/purMozilla/index.htm</a><br /><br />Le code REX utilisé dans l'exemple:<br /><a href="http://shadok.enst.fr:8080/modifxml/purMozilla/commandeRex.html">http://shadok.enst.fr:8080/modifxml/purMozilla/commandeRex.html</a><br /><br />Le code Javascript pour exécuter les commandes REX:<br /><a href="http://shadok.enst.fr:8080/modifxml/purMozilla/rexfox.js">http://shadok.enst.fr:8080/modifxml/purMozilla/rexfox.js<br /></a><br />Le document SVG utilisé dans l'exemple:<br /><a href="http://shadok.enst.fr:8080/modifxml/frame1.svgm">http://shadok.enst.fr:8080/modifxml/frame1.svgm</a><br />_________________________________________________<br /><br /><span style="font-style: italic;">Note: les attributs position et timeStamp des commandes REX ne sont pas traités pour l'instant; position va être rapidement rajouté; timeStamp me parait encore insuffisament défini dans le cas général de modifications de documents XML, mais je crois pouvoir en faire une implémentation pour SVG.</span><br />_________________________________________________<br /><span style="font-weight: bold; font-style: italic;"><br />Obtention de l'objet XMLHttpRequest </span><br /><br />function getHTTPObject() {<br />var xmlhttp;<br />if (!xmlhttp && typeof XMLHttpRequest != 'undefined')<br />{<br />try { xmlhttp = new XMLHttpRequest(); }<br />catch (e) { xmlhttp = false; }<br />}<br />return xmlhttp;<br />}<br /><br />Je ne commenterai pas ces 9 lignes de code et renverai aux nombreux tutoriels sur Ajax qu'on peut trouver par exemple à partir de <a href="http://en.wikipedia.org/wiki/AJAX">http://en.wikipedia.org/wiki/AJAX.</a><br /><br />Nous supposerons que la fonction précédente a permis de récupérer un objet nommé xmlupdater.<br /><br />XMLHttpRequest n'est pas standardisée. On trouve cependant sur le Web diverses techniques pour utiliser des objets équivalents avec Firefox et Internet Explorer. Le W3C travaille à la normalisation de ce type de technique dans le groupe de travail WEB API (voir <a href="http://www.w3.org/2006/webapi/">http://www.w3.org/2006/webapi/</a>).<br />_________________________________________________<br /><br /><span style="font-weight: bold; font-style: italic;">Obtention de la liste de commande à exécuter</span><br /><br />Nous supposons que les commandes sont fournies par un serveur et que d'autres éléments de la page en cours de modification permettent de déterminer l'URL du message REX à exécuter.<br /><br />L'envoi de la demande de mise à jour depuis le document nécessite les 6 lignes de code suivantes:<br />function sendRequest(urlcommand)<br />{<br />xmlupdater.open("GET", urlcommand);<br />xmlupdater.onload = handleRexResponse;<br />xmlupdater.send(null);<br />}<br /><br />La gestion spécifique d'une réponse composée d'un message REX est gérée par la fonction handleRexResponse.<br />_________________________________________________<br /><span style="font-weight: bold; font-style: italic;"><br />Exécution du message REX</span><br /><br />Cette exécution représente environ 50 lignes de code pour interpréter le message REX et appeler les fonctions qui exécutent les modifications proprement dites. le code complet est accessible sur le site de démonstration.<br /><br />Par exemple, DOMNodeRemove conduit déterminer le noeud visé à l'aide de la fonction nodesetFromPath, puis à l'appel de la fonction removeNode; c'est à dire la séquence de code suivante:<br /><br /><p>if(commandType == "DOMNodeRemove")</p><p> {</p><p> pointedSet = nodesetFromPath(ru.doc, ru.nsResolver, target);</p><p> for (var k = 0; k < pointedSet.snapshotLength; k++) {</p><p> removeNode(pointedSet.snapshotItem(k));</p><p> }</p><p> }</p><br /><br /><span style="font-weight: bold; font-style: italic;">Obtenir un ensemble de noeuds à partir d'un xpath</span><br /><br />J'ai mentionné dans le paragraphe précédent la fonction nodesetFromPath.<br />Elle est définie de la façon suivante:<br />function nodesetFromPath(doc, resolver, target)<br />{<br />return ret = doc.evaluate( target, doc, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );<br />}<br /><br />où<br />target est la chaîne de caractère représentant le xpath de l'objet ciblé<br />doc est la référence du document XML dans lequel on cherche<br />resolver est une fonction de résolution de namespace (voir ci-dessous)<br /><br />La méthode evaluate de l'objet doc est une méthode définie dans l'implémentation Javascript de Firefox.<br /><br />resolver est la référence à une fonction qui permet d'associer un préfixe d'espace de nommage à une chaîne de caractère, pour assurer la réslution des espaces de nommage. Dans le cas de notre exemple, où du SVG est contenu dans du HTML, la fonction est définie comme suit:<br />function nsResolver(prefix) {<br />var ns = {<br />'xhtml' : 'http://www.w3.org/1999/xhtml',<br />'svg': 'http://www.w3.org/2000/svg'<br />};<br />return ns[prefix] || null;<br />}<br />_________________________________________________<br />_________________________________________________<br /><br /><span style="font-weight: bold;">Les problème avec REX</span><br /><br />Le premier problème posé par REX est qu'il s'agit de XML. Donc:<br />- c'est ralativement verbeux,<br />- c'est un codage textuel peu compact de l'information,<br />- c'est une technologie inadaptée pour le streaming.<br /><br />Ces deux problèmes n'ont rien de spécifique à REX et se posent pour l'ensemble des technologies qui s'appuient sur XML. Il faudra attendre les résultats des travaux sur le XML binarisé pour changer cette situation.<br /><br />Cela n'enlève rien au fait que les propositions ci-dessus proposent une solution générique simple d'emploi pour faire évoluer une scène multimédia SVG A L'INITIATIVE D'ACTIONS SUR LE CLIENT. Il faut en effet que quelquechose -une interaction, un timer...- déclenche l'appel approprié à XMLHttpRequest. Nous verrons dans le prochain paragraphe qu'il existe au moins une solution qui donne l'initiative au serveur.<br /><br />Le deuxième problème est d'ordre juridique. France Telecom revendique la possession de brevets qui empêcheraient la libre exploitation de REX. N'étant pas expert en brevet, je me limiterai à quelques commentaires sur les brevets en question et les technologies auxquelles ils semblent s'appliquer.<br /><br />Les brevets que j'ai vu portent sur l'application de commandes de modification à une scène graphique représentée sur un écran. Les commandes prises en considération sont:<br />- insertion d'un nouvel élément dans la scène,<br />- modification d'un élément de la scène,<br />- suppression d'un élément de la scène.<br />Ces brevets ont été déposés lors de la définition de la technologie BIFS qui est une partie de MPEG-4 (voir <a href="http://gpac.sourceforge.net/tutorial/bifs_intro.htm">http://gpac.sourceforge.net/tutorial/bifs_intro.htm</a>).<br /><br />Il apparait clairement que tous les documents multimédia peuvent être qualifiés de scènes graphiques. Peuvent être couverts par ce brevet les modifications de documents XHTML et Flash.<br /><br />Nous voyons également que les commandes REX appliquées à du SVG semblent couvertes par ce brevet.<br /><br />Les commandes ci-dessus sont les commandes de base de tout éditeur de document: insérer, modifier, supprimer. Si le brevet est valide, il semble que toute édition/modification de document multimédia soit couverte par ce brevet.<br /><br />Je regretterais beaucoup de ne pas pouvoir utiliser REX et la méthode que j'ai proposée ci-dessus sans négocier des licences avec France Telecom, mais c'est le principe des brevets logiciels.<br /><br />Je dois surtout mettre en garde tous les développeurs Ajax qui utilisent XMLHttprequest pour insérer ou modifier un morceau d'une page HTML: leur travail est probablement couvert par les brevets de France Telecom.<br /><br /><span style="font-weight: bold;">LASER, une vision complémentaire des scènes multimédia dynamiques</span><br /><br />Nous avons vu ci-dessus un assemblage de technologies qui se prête bien à une utilisation simple sur le WEB, mais relativement peu performante. Nous allons introduire ici ce qui pourrait être un développement important de SVG.<br /><br />SVG et REX sont des grammaires XML et donc des formats textuels.<br /><br />Dans le cadre de MPEG-4, une application originale de SVG a été proposée sous le nom de LASER. Elle pourrait contribuer de façon significative au développement de l'utilisation de SVG en environnement mobile; son adoption par le 3GPP est envisagée.<br /><br />En effet, en s'appuyant sur SVG, LASER introduit les possibilités suivantes:<br />- offrir une représentation compacte binaire de la scène SVG,<br />- permettre des commandes de modifications du types de celles présentées ci-dessus dans cet article,<br />- permettre de streamer l'envoi progressif, défini temporellement, de ces modifications.<br /><br />Nous reviendrons dans une prochaine note sur cette technologie prometteuse.Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0tag:blogger.com,1999:blog-28389728.post-1151111518758119742006-06-23T18:11:00.000-07:002010-04-19T03:26:33.339-07:00A taste of REX, AJAX and SVG<div style="text-align: right;"><span style="font-size:85%;"><i>(C) Jean-Claude Moissinac - ENST - June, 2006</i></span><br /></div><p style="font-weight: bold;"><span style="font-size:130%;">Abstract</span></p> The purpose of this note is to present my implementation of REX to dynamically modify SVG documents via the XMLHttpRequest instruction, popularized by AJAX. REX is a simple XML grammar - proposed by the W3C in February 2006 - which allows us to describe modifications we want to bring to an XML document: insertion, replacement or deletion of a sub-document, and attributes change. Thanks to this implementation, with a little bit of JavaScript code, we can make any manipulation of a graphic SVG page through commands stemming from a server.<br /><span style="color: rgb(0, 0, 0);"><br />THANKS: to Berthele Rodriguez and Thierry Arbelot for useful reviews</span><p class="MsoPlainText"><span style="color: rgb(0, 0, 0);"><b>Résumé</b><br />Dans cette note, je présente une implémentation de REX pour modifier dynamiquement des documents SVG à l'aide de XMLHttpRequest popularisé par AJAX. REX est une grammaire XML simple, proposée par le W3C en février 2006, qui permet de décrire des modifications qu'on veut apporter à un document XML: insertion, remplacement ou suppression de sous-arbre, et changement d'attributs. Grâce à cette implémentation, avec très peu de code Javascript, on peut faire toutes sortes de manipulation d'une page graphique SVG par des commandes issues d'un serveur.<br /><br />Une version française de cet article se trouve à </span><span style="color: rgb(0, 0, 0);"><a href="http://svgmpeg4.blogspot.com/2006/07/un-zeste-de-svg-ajax-et-rex.html">http://svgmpeg4.blogspot.com/2006/07/un-zeste-de-rex-ajax-et-svg.html</a></span><span style="" lang="EN-GB">.<br /><br /><b></b><span style="font-size:130%;">SVG</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">SVG means Scalable Vector Graphics. It is a XML grammar, defined by the W3C, which allows us to describe graphic documents, even animated and interactive. SVG is often perceived as a competitor of Flash. We shall see in a future note how techniques proposed here allow to use a common practice of Flash developers: send an almost empty initial graphic scene then </span><span style="" lang="EN-GB">gradually </span><span style="" lang="EN-GB">complete it according to the preferences and the interactions of the user, the navigator, the size of the window...<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">Numerous developers developed </span><span style="" lang="EN-GB">their own JavaScript code</span><span style="" lang="EN-GB"> case by case in order t</span><span style="" lang="EN-GB">o modify SVG</span><span style="" lang="EN-GB">; we shall see below that with a short JavaScript code, we can have a useful generic solution.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold;">AJAX</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">By naming it, Ajax popularized the </span><span style="" lang="EN-GB">method of </span><span style="" lang="EN-GB">dynamic </span><span style="" lang="EN-GB">publishing </span><span style="" lang="EN-GB">Web sites based on the use of the XMLHttpRequest function to get back data via script, allowing to modify one page without reloading it. A common practice is to ask the server for a piece of HTML page through an XMLHttpRequest and bring it in the current page by simple copy. This function gives us an extremely flexible and light method for dynamic pages construction.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">This way of working also applies to SVG documents. When navigators support the use of HTML and SVG elements in the same page, we can even manipulate the HTML and the SVG parts by this method. This is the case, for example, of the current versions of Firefox (1.5 when writing this article).<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold;">REX, short introduction</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The REX proposition is short and clear. We can find it at <a href="http://www.w3.org/TR/rex/">http://www.w3.org/TR/rex/</a>. REX means Remote Events for XML.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">REX uses a subsection of the XPATH syntax to point to the XML tree portion we wish to modify. This subsection is simple to understand, close to the description of a path in a file tree. For example:<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">/<span style=""> </span><span style=""> </span>points to the root of the document<span style=""> </span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">/svg/g[3]<span style=""> </span><span style=""> </span>points to the third element g directly found as child of the <o:p></o:p>root of the svg document (rem.: g allows to group svg <o:p></o:p>elements).<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">id('bouton1') <span style=""> </span>points to the node of the tree having the identifier (id) <o:p></o:p>bouton1<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">id('boutons1')/@fill <span style=""> </span>points to the fill attribute of the element with identifier <o:p></o:p>bouton1<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">As seen in these examples, the syntax is quickly discovered, at least for the most common uses.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">Now that we know how to point to the part of the document to be modified, here are some simple modifications examples:</span></p><p class="MsoPlainText"><rex xmlns="http://www.w3.org/2006/rex" ><br /><event target="id('S1')/svg:path[13]" name="DOMNodeRemove"><br /></rex xmlns="http://www.w3.org/2006/rex" ><br /><span style="" lang="EN-GB"><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><xmlns rex="http://www.w3.org/2006/rex"><o:p></o:p></xmlns></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><event target="id ('S1')/svg:path[13]" name="DOMNodeRemove"><o:p></o:p></event></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">name contains the name of the executed command and DOMNodeRemove let us to delete a node; in this example, </span><span style="" lang="EN-GB">DOMNodeRemove is used for deleting a node. W</span><span style="" lang="EN-GB">e thus delete the thirteenth path node (and its possible sub-nodes) found under the element with the S1 identifier.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><event target="id('S1')/svg:text[1]/@fill" name="DOMAttrModified" newvalue="blue"><o:p></o:p></event></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><event target="id('S1')/svg:text[1]/@fill" name="DOMAttrModified" newvalue="blue"><br /></p><p class="MsoPlainText"><span style="" lang="EN-GB">Here, I show only the central line changed from the previous message. DOMAttrModified indicates that we modify the value of an attribute. The attribute is the color filling attribute of the first text node found under the element with the S1 identifier; the new value given to this attribute is blue.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><event target="id('S1')/svg:text/text()" name="DOMCharacterDataModified" newvalue=" changed text"><o:p></o:p></event></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><event target="id('S1')/svg:text/text()" name="DOMCharacterDataModified" newvalue="Texte changé"><br /></p><p class="MsoPlainText"><span style="" lang="EN-GB">DOMCharacterDataModified indicates that we modify the textual content of the first text element found under the element with the S1 identifier; the new value is ‘changed text’.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">We can group several modifications:<o:p></o:p></span></p><rex xmlns="http://www.w3.org/2006/rex" ><br /><event target="id('S1')/svg:path[13]" name="DOMNodeRemove"><br /><event target="id('S1')/svg:text[1]/@fill" name="DOMAttrModified" newvalue="blue"><br /><event target="id('S1')/svg:text/text()" name="DOMCharacterDataModified" </rex xmlns="http://www.w3.org/2006/rex" ><br /><p class="MsoPlainText"><span style="" lang="EN-GB">In this way, the previous three modifications are grouped in a single REX message.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">For more details, your best bet is to look at the <a href="http://www.w3.org/TR/rex/">W3C proposition</a> (15 pages).<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold;font-size:130%;">Implementation of REX in Javascript</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The first step to implement REX is to have methods to find a node in a document from an XPATH expression, REX compliant. My first implementation used an implementation of XPATH from Google (see<a href="http://goog-ajaxslt.sourceforge.net/"> http://goog-ajaxslt.sourceforge.net/</a>). I would comment this implementation in a future note.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">Then, I took into account the fact that Firefox has a support for SVG and XPATH. It was interesting to study this solution. This solution is compact and elegant: the whole REX support for documents used with Firefox takes approximately 200 lines of code Javascript.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The demonstration can be seen at the following address:<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><a href="http://shadok.enst.fr:8080/modifxml/purMozilla/index.htm">http://shadok.enst.fr:8080/modifxml/purMozilla/index.htm</a><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The REX code used in this example:<o:p></o:p></span></p> <p class="MsoPlainText"><span lang="EN-GB"><a href="http://shadok.enst.fr:8080/modifxml/commandeRex.xml">http://shadok.enst.fr:8080/modifxml/commandeRex.xml</a><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The Javascript code to execute the REX commands:<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><a href="http://shadok.enst.fr:8080/modifxml/purMozilla/rexfox.js">http://shadok.enst.fr:8080/modifxml/purMozilla/rexfox.js</a><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The SVG document used in this example:<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><a href="http://shadok.enst.fr:8080/modifxml/frame1.svgm">http://shadok.enst.fr:8080/modifxml/frame1.svgm</a><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-style: italic;">Note: the attributes position and timeStamp of REX commands are not implemented at the time being; position is going to be quickly added; timeStamp still seems to be under-defined in the general case of modifications of XML documents, but I believe I can make an implementation for SVG.</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold; font-style: italic;font-size:130%;">Obtaining the XMLHttpRequest object</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p>function getHTTPObject() {<br />var xmlhttp;<br />if (!xmlhttp && typeof XMLHttpRequest != 'undefined')<br />{<br />try { xmlhttp = new XMLHttpRequest(); }<br />catch (e) { xmlhttp = false; }<br />}<br />return xmlhttp;<br />}<br /><p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">I shall not comment on these 9 lines of code and point to the many tutorials about Ajax, for example from <a href="http://en.wikipedia.org/wiki/AJAX">http://en.wikipedia.org/wiki/AJAX</a>.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">We shall suppose that the previous function allowed to get back an object named xmlupdater.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold; font-style: italic;font-size:130%;">Obtaining the list of command to be executed</span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">We suppose that a server supplies the commands and that the other elements of the modified page allow determining the URL of the REX message.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The request of the REX message requires the following 6 lines of code:<o:p></o:p></span></p>function sendRequest(urlcommand)<br />{<br />xmlupdater.open("GET", urlcommand);<br />xmlupdater.onload = handleRexResponse;<br />xmlupdater.send(null);<br />}<br /><p class="MsoPlainText"><span style="" lang="EN-GB"><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The management of the answered REX message is managed by the handleRexResponse function.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-size:130%;"><span style="font-weight: bold; font-style: italic;">Execution of the REX message</span></span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The execution represents approximately 50 lines of code to interpret the REX message and call the functions, which execute the document modifications. The complete code is accessible on the demonstration site (see below).<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">For example, DOMNodeRemove begin by determining the targeted node by means of the nodesetFromPath function, then by calling the removeNode function; this is the following code sequence:<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p><p><br />if(commandType == "DOMNodeRemove")</p><p> {</p><p> pointedSet = nodesetFromPath(ru.doc, ru.nsResolver, target);</p><p> for (var k = 0; k <></p><p> removeNode(pointedSet.snapshotItem(k)); </p> <p> }</p><p> }</p><br />_______________________________________ __________<o:p></o:p><p></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-size:130%;"><span style="font-weight: bold; font-style: italic;">Obtain a set of nodes from an xpath</span></span><o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">I mentioned in the previous paragraph the nodesetFromPath function.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">It is defined in the following way:<o:p></o:p></span></p>function nodesetFromPath(doc, resolver, target)<br />{<br />return ret = doc.evaluate( target, doc, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );<br />}<br /><p class="MsoPlainText"><span style="" lang="EN-GB">Where target is the string representing the xpath of the targeted object<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">doc is the reference of the XML document XML in which we look and<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">resolver is a function for the resolution of namespaces (see below)<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">The method evaluate of the doc object is a method defined in the Javascript implementation of Firefox.<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><o:p> </o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB">resolver is the function reference that allows to associate a namespace prefix to a string, in order to resolve namespaces. In our example, where an SVG document is contained in a HTML document, the function is defined as follows:<o:p></o:p></span></p>function nsResolver(prefix) {<br />var ns = {<br />'xhtml' : 'http://www.w3.org/1999/xhtml',<br />'svg': 'http://www.w3.org/2000/svg'<br />};<br />return ns[prefix] || null;<br />}<br /><p class="MsoPlainText"><span style="" lang="EN-GB">_______________________________________ __________<o:p></o:p><br />_______________________________________ __________<o:p></o:p></span></p> <p class="MsoPlainText"><span style="" lang="EN-GB"><span style="font-weight: bold;font-size:130%;">Attention: it is possible that patents apply to the methods exposed in this article<br /></span></span></p>Moissinachttp://www.blogger.com/profile/15164264111988753115noreply@blogger.com0