Dans un précédent billet intitulé « jQuery tagger des images« , j’avais proposé une idée de conception d’un outil permettant de tagger des images. Suite à quelques remarques concernant la forme du tag géré, j’ai pensé à une autre façon de concevoir ces tags.
La propriété HTML
Le plugin de sélection « imgareaselect » ne permet de gérer que la forme RECTANGLE, et je n’ai pas le temps de le modifier pour gérer les deux autres formes. J’ai donc oublié ce plugin pour cette démonstration.
Il est peu modifié par rapport au précédent billet, je vous mets la nouvelle version pour éviter de faire des allers-retours entre les deux billets.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Tagger une image!</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="css/selectarea/imgareaselect-default.css" /> <link rel="stylesheet" type="text/css" href="css/impromptu/impromptu.css" /> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/jquery.maphilight.js"></script> <script type="text/javascript" src="js/jquery-impromptu.3.0.js"></script> <script type="text/javascript" src="js/jquery.tooltip.js"></script> <style type="text/css"> body { background-color: #EFEFEF; } img { border: 0; } #tooltip{ position:absolute; border:2px solid #333; background:orange; padding:2px 5px; color:black; font-weight: bold; display:none; } </style> </head> <body> <h1 style="text-align:center; color: #956AAA;">Test image tag</h1> <table> <tr> <td width="200px;" valign="top"> <br/>1. Cliquer sur le boutton "Tagger!" <br/>2. Créer la selection <br/>3. Sauvegarder <br/>4. Survoler la zone taggée </td> <td width="900px"> <a id="imageTopLink">&nbsp;</a> <img alt="Le mur!" id="photo" src="img/wall1.jpg" usemap="#wall1" /> </td> <td width="100px" valign="top" style="padding-top:20px;"> <input type="button" id="clickFinSelect" value="sauvegarder" disabled="disabled" /> <input type="button" id="clickTagCercle" value="Tagger cercle!" /> <input type="button" id="clickTagRectangle" value="Tagger Rectangle!" /> <input type="button" id="clickTagPerso" value="Tagger polygone!" /> <input type="button" id="testTag" value="Test!" /> </td> </tr> </table> <map id="wall1" name="wall1"> <area title="1" coords="696, 237, 21" shape="CIRCLE" id="areaMapGenerate-1" href="#imageTopLink"> <area title="2" coords="378, 139, 439, 249" shape="RECT" id="areaMapGenerate-2" href="#imageTopLink"> <area title="3" coords="770, 253, 807, 247, 840, 270, 857, 301, 839, 330, 788, 325, 749, 317, 741, 286, 764, 262" shape="POLY" id="areaMapGenerate-3" href="#imageTopLink"> <area title="4" coords="430, 356, 429, 342, 433, 324, 443, 315, 454, 315, 454, 327, 468, 328, 466, 313, 452, 306, 435, 306, 422, 314, 418, 330, 422, 350, 428, 361" shape="POLY" id="areaMapGenerate-4" href="#imageTopLink"> </map> </body> </html> Juste quelques boutons de rajouter pour différencier les formes prisent en compte par la balise de HTML.Les plugins jQueryjQuery.maphilight.jsL'utilisation de ce plugin ne change pas, je vous recopie donc la description de ce plugin pour mon application.« J'ai du modifier un petit peu ce fichier pour arriver à mes fins (jquery.maphilight.js). Ce plugin permet d'afficher graphiquement au survol d'une zone de l'image un div avec un style personnalisable. Les zones à afficher sont tous simplement définies dans le associé à l'image.Cette balise HTML (cf map_tag et area_tag) permet de créer des liens cliquables sur des images. Ce plugin permet donc juste de parser cette balise et d'afficher à l'écran la zone définit dans ces balises. »Le fichier jquery.maphilight.js modifiéVous trouverez ce fichier modifié sur la démo ou plus directement via ce lien.jQuery.tooltip.jsCe plugin permet d'afficher le "title" d'un lien de façon plus élégante que celle du navigateur. Ce plugin n'est pas modifié, vous pouvez prendre la version officielle.jQuery.impromptu.jsIl me permet de demander à l'utilisateur de saisir le libellé du tag de façon plus élégante ! Ce plugin est non essentiel au bon fonctionnement de l'application, la méthode prompt() de JavaScript suffirai largement.Le code jQueryBon le principe est simple. Il faut différencier les trois formes disponibles.Démarche de génération des formesLe cerclePour le cercle, l'utilisateur doit procurer deux informations :Un click pour le centre du cercleUn click pour le rayon du cercleLe rectanglePour le rectangle l'utilisateur doit produire deux clicks également :Un click pour un coin du rectangleUn second click pour le coin opposé au premier clickLe polygoneCas particulier, l'utilisateur a un nombre illimité de click. La procédure de fin se fera alors avec le bouton « Sauvegarder » qui s'active dès que l'on commence à dessiner un polygone.Le code source $().ready(function() { var maphilight = false; var idCourant = 0; var arrayClick = null; var arrayShape = new Array("CIRCLE", "RECT", "POLY"); var circleLength; var startTag = 0; // Gestion des tags (CERCLE, RECTANGLE, POLYGONE) $("input#clickTagCercle").click(function() { startTag = 1; arrayClick = new Array(); }); $("input#clickTagRectangle").click(function() { startTag = 2; arrayClick = new Array(); }); $("input#clickTagPerso").click(function() { startTag = 3; arrayClick = new Array(); }); // Gestion des click sur l'image $("img#photo").live("click", function(e) { var coordClick = getClickPosition($(this), e); // Circle tag! if(startTag == 1) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { var last = arrayClick[0]; var newX = Math.pow(Math.abs(coordClick["x"] - last["x"]), 2); var newY = Math.pow(Math.abs(coordClick["y"] - last["y"]), 2); circleLength = Math.round(Math.sqrt(newX + newY)); validFinTag(); } } else if(startTag == 2) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { arrayClick.push(coordClick); validFinTag(); } } else if(startTag == 3) { if(arrayClick.length == 1) $("input#clickFinSelect").attr("disabled", ""); arrayClick.push(coordClick); } }); // Gestion de la sauvegarde pour le polygone $("input#clickFinSelect").click(function() { $("input#clickFinSelect").attr("disabled", "disabled"); validFinTag(); }) // Récupère la position du click par rapport à l'image function getClickPosition(object, event) { var returnObject = Array(); if(object.css('position') == "absolute") { var imagePosition = object.parent().position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } else { var imagePosition = object.position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } return returnObject; } // Valide et sauvegarde le tag function validFinTag() { idCourant++; // Méthode callback après la validation du prompt function mycallbackform(v,m,f){ var coords; // Cercle if(startTag == 1) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+circleLength; // Rectangle if(startTag == 2) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+arrayClick[1]["x"]+', '+arrayClick[1]["y"]; // Polygon if(startTag == 3) { coords = ""; for(i=0,j=arrayClick.length;i<j;i++) { if(i>=1) coords = coords + ', '; coords = coords+arrayClick[i]["x"]+', '+arrayClick[i]["y"]; } } // Récupère le bon libellé pour la forme courante var shapeId = startTag - 1; var shape = arrayShape[shapeId]; // Ajoute la nouvelle form à la <map ..> $("#wall1").append(' <area href="#imageTopLink"'+ 'id="areaMapGenerate-'+idCourant+ '" shape="'+shape+ '" coords="'+coords+ '" title="'+f.alertName+'" />'); // Actualise le maphilight $('.map').maphilight(); // Actualise les tooltips tooltip(); // Réinitialise les variables globales arrayClick = new Array(); circleLength = 0; } // Texte de la fenêtre prompt var txt = 'Le nom de la personne à tagger:'+ ' <input type="text" '+ 'id="alertName" '+ 'style="width:300px;" '+ 'name="alertName" '+ 'value="" />'; $.prompt(txt,{ callback: mycallbackform, buttons: { Ok: true }, focus: 1 }); } //Gestion de l'affichage ou non du maphilight $("#testTag").click(function() { maphilight = !maphilight; $('.map').maphilight({alwaysOn:maphilight}); }); // Initialisation $('.map').maphilight(); tooltip(); }); Aller plus loinCette mini-demo n'est pas optimisé, sécurisé et blablabla et blablabla. C'est juste à titre d'exemple.Il serait effectivement judicieux que l'utilisateur puisse visualiser les clicks en direct, voir la forme dynamiquement modifier.Il faudrait également rajouter la modification de ces formes.Bref faite travailler votre imagination sans oublier de rester les pieds sur terre et surtout sans oublier qu'un utilisateur veut faire un maximum de chose en un minimum d'action =DBon dév ! Titre : image_taggable_multiformeLégende : Nom du fichier : image_taggable_multiforme.zipTaille : 257 KoGeekos.fr vous recommande les articles suivantsjQuery et CSS : Donner du style à ses liensjQuery & YQL : Effectuer des requêtes AJAX en cross-domainEmbarquer le viewer github sur votre siteJavaScript : Chosen, un plugin jQuery et mooTools pour les balises SELECTjQuery: Utiliser une autre version sans écraser celle existante
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Tagger une image!</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="css/selectarea/imgareaselect-default.css" /> <link rel="stylesheet" type="text/css" href="css/impromptu/impromptu.css" /> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/jquery.maphilight.js"></script> <script type="text/javascript" src="js/jquery-impromptu.3.0.js"></script> <script type="text/javascript" src="js/jquery.tooltip.js"></script> <style type="text/css"> body { background-color: #EFEFEF; } img { border: 0; } #tooltip{ position:absolute; border:2px solid #333; background:orange; padding:2px 5px; color:black; font-weight: bold; display:none; } </style> </head> <body> <h1 style="text-align:center; color: #956AAA;">Test image tag</h1> <table> <tr> <td width="200px;" valign="top"> <br/>1. Cliquer sur le boutton "Tagger!" <br/>2. Créer la selection <br/>3. Sauvegarder <br/>4. Survoler la zone taggée </td> <td width="900px"> <a id="imageTopLink">&nbsp;</a> <img alt="Le mur!" id="photo" src="img/wall1.jpg" usemap="#wall1" /> </td> <td width="100px" valign="top" style="padding-top:20px;"> <input type="button" id="clickFinSelect" value="sauvegarder" disabled="disabled" /> <input type="button" id="clickTagCercle" value="Tagger cercle!" /> <input type="button" id="clickTagRectangle" value="Tagger Rectangle!" /> <input type="button" id="clickTagPerso" value="Tagger polygone!" /> <input type="button" id="testTag" value="Test!" /> </td> </tr> </table> <map id="wall1" name="wall1"> <area title="1" coords="696, 237, 21" shape="CIRCLE" id="areaMapGenerate-1" href="#imageTopLink"> <area title="2" coords="378, 139, 439, 249" shape="RECT" id="areaMapGenerate-2" href="#imageTopLink"> <area title="3" coords="770, 253, 807, 247, 840, 270, 857, 301, 839, 330, 788, 325, 749, 317, 741, 286, 764, 262" shape="POLY" id="areaMapGenerate-3" href="#imageTopLink"> <area title="4" coords="430, 356, 429, 342, 433, 324, 443, 315, 454, 315, 454, 327, 468, 328, 466, 313, 452, 306, 435, 306, 422, 314, 418, 330, 422, 350, 428, 361" shape="POLY" id="areaMapGenerate-4" href="#imageTopLink"> </map> </body> </html>
Juste quelques boutons de rajouter pour différencier les formes prisent en compte par la balise
L'utilisation de ce plugin ne change pas, je vous recopie donc la description de ce plugin pour mon application.
« J'ai du modifier un petit peu ce fichier pour arriver à mes fins (jquery.maphilight.js). Ce plugin permet d'afficher graphiquement au survol d'une zone de l'image un div avec un style personnalisable. Les zones à afficher sont tous simplement définies dans le
Cette balise HTML
et d'afficher à l'écran la zone définit dans ces balises
Vous trouverez ce fichier modifié sur la démo ou plus directement via ce lien.
Ce plugin permet d'afficher le "title" d'un lien de façon plus élégante que celle du navigateur. Ce plugin n'est pas modifié, vous pouvez prendre la version officielle.
Il me permet de demander à l'utilisateur de saisir le libellé du tag de façon plus élégante ! Ce plugin est non essentiel au bon fonctionnement de l'application, la méthode prompt() de JavaScript suffirai largement.
Bon le principe est simple. Il faut différencier les trois formes disponibles.
Pour le cercle, l'utilisateur doit procurer deux informations :
Pour le rectangle l'utilisateur doit produire deux clicks également :
Cas particulier, l'utilisateur a un nombre illimité de click. La procédure de fin se fera alors avec le bouton « Sauvegarder » qui s'active dès que l'on commence à dessiner un polygone.
$().ready(function() { var maphilight = false; var idCourant = 0; var arrayClick = null; var arrayShape = new Array("CIRCLE", "RECT", "POLY"); var circleLength; var startTag = 0; // Gestion des tags (CERCLE, RECTANGLE, POLYGONE) $("input#clickTagCercle").click(function() { startTag = 1; arrayClick = new Array(); }); $("input#clickTagRectangle").click(function() { startTag = 2; arrayClick = new Array(); }); $("input#clickTagPerso").click(function() { startTag = 3; arrayClick = new Array(); }); // Gestion des click sur l'image $("img#photo").live("click", function(e) { var coordClick = getClickPosition($(this), e); // Circle tag! if(startTag == 1) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { var last = arrayClick[0]; var newX = Math.pow(Math.abs(coordClick["x"] - last["x"]), 2); var newY = Math.pow(Math.abs(coordClick["y"] - last["y"]), 2); circleLength = Math.round(Math.sqrt(newX + newY)); validFinTag(); } } else if(startTag == 2) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { arrayClick.push(coordClick); validFinTag(); } } else if(startTag == 3) { if(arrayClick.length == 1) $("input#clickFinSelect").attr("disabled", ""); arrayClick.push(coordClick); } }); // Gestion de la sauvegarde pour le polygone $("input#clickFinSelect").click(function() { $("input#clickFinSelect").attr("disabled", "disabled"); validFinTag(); }) // Récupère la position du click par rapport à l'image function getClickPosition(object, event) { var returnObject = Array(); if(object.css('position') == "absolute") { var imagePosition = object.parent().position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } else { var imagePosition = object.position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } return returnObject; } // Valide et sauvegarde le tag function validFinTag() { idCourant++; // Méthode callback après la validation du prompt function mycallbackform(v,m,f){ var coords; // Cercle if(startTag == 1) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+circleLength; // Rectangle if(startTag == 2) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+arrayClick[1]["x"]+', '+arrayClick[1]["y"]; // Polygon if(startTag == 3) { coords = ""; for(i=0,j=arrayClick.length;i<j;i++) { if(i>=1) coords = coords + ', '; coords = coords+arrayClick[i]["x"]+', '+arrayClick[i]["y"]; } } // Récupère le bon libellé pour la forme courante var shapeId = startTag - 1; var shape = arrayShape[shapeId]; // Ajoute la nouvelle form à la <map ..> $("#wall1").append(' <area href="#imageTopLink"'+ 'id="areaMapGenerate-'+idCourant+ '" shape="'+shape+ '" coords="'+coords+ '" title="'+f.alertName+'" />'); // Actualise le maphilight $('.map').maphilight(); // Actualise les tooltips tooltip(); // Réinitialise les variables globales arrayClick = new Array(); circleLength = 0; } // Texte de la fenêtre prompt var txt = 'Le nom de la personne à tagger:'+ ' <input type="text" '+ 'id="alertName" '+ 'style="width:300px;" '+ 'name="alertName" '+ 'value="" />'; $.prompt(txt,{ callback: mycallbackform, buttons: { Ok: true }, focus: 1 }); } //Gestion de l'affichage ou non du maphilight $("#testTag").click(function() { maphilight = !maphilight; $('.map').maphilight({alwaysOn:maphilight}); }); // Initialisation $('.map').maphilight(); tooltip(); }); Aller plus loinCette mini-demo n'est pas optimisé, sécurisé et blablabla et blablabla. C'est juste à titre d'exemple.Il serait effectivement judicieux que l'utilisateur puisse visualiser les clicks en direct, voir la forme dynamiquement modifier.Il faudrait également rajouter la modification de ces formes.Bref faite travailler votre imagination sans oublier de rester les pieds sur terre et surtout sans oublier qu'un utilisateur veut faire un maximum de chose en un minimum d'action =DBon dév ! Titre : image_taggable_multiformeLégende : Nom du fichier : image_taggable_multiforme.zipTaille : 257 KoGeekos.fr vous recommande les articles suivants
$().ready(function() { var maphilight = false; var idCourant = 0; var arrayClick = null; var arrayShape = new Array("CIRCLE", "RECT", "POLY"); var circleLength; var startTag = 0; // Gestion des tags (CERCLE, RECTANGLE, POLYGONE) $("input#clickTagCercle").click(function() { startTag = 1; arrayClick = new Array(); }); $("input#clickTagRectangle").click(function() { startTag = 2; arrayClick = new Array(); }); $("input#clickTagPerso").click(function() { startTag = 3; arrayClick = new Array(); }); // Gestion des click sur l'image $("img#photo").live("click", function(e) { var coordClick = getClickPosition($(this), e); // Circle tag! if(startTag == 1) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { var last = arrayClick[0]; var newX = Math.pow(Math.abs(coordClick["x"] - last["x"]), 2); var newY = Math.pow(Math.abs(coordClick["y"] - last["y"]), 2); circleLength = Math.round(Math.sqrt(newX + newY)); validFinTag(); } } else if(startTag == 2) { if(arrayClick.length < 1) { arrayClick.push(coordClick); } else if(arrayClick.length == 1) { arrayClick.push(coordClick); validFinTag(); } } else if(startTag == 3) { if(arrayClick.length == 1) $("input#clickFinSelect").attr("disabled", ""); arrayClick.push(coordClick); } }); // Gestion de la sauvegarde pour le polygone $("input#clickFinSelect").click(function() { $("input#clickFinSelect").attr("disabled", "disabled"); validFinTag(); }) // Récupère la position du click par rapport à l'image function getClickPosition(object, event) { var returnObject = Array(); if(object.css('position') == "absolute") { var imagePosition = object.parent().position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } else { var imagePosition = object.position(); returnObject["x"] = Math.round(event.pageX - imagePosition.left); returnObject["y"] = Math.round(event.pageY - imagePosition.top); } return returnObject; } // Valide et sauvegarde le tag function validFinTag() { idCourant++; // Méthode callback après la validation du prompt function mycallbackform(v,m,f){ var coords; // Cercle if(startTag == 1) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+circleLength; // Rectangle if(startTag == 2) coords = arrayClick[0]["x"]+', '+arrayClick[0]["y"]+', '+arrayClick[1]["x"]+', '+arrayClick[1]["y"]; // Polygon if(startTag == 3) { coords = ""; for(i=0,j=arrayClick.length;i<j;i++) { if(i>=1) coords = coords + ', '; coords = coords+arrayClick[i]["x"]+', '+arrayClick[i]["y"]; } } // Récupère le bon libellé pour la forme courante var shapeId = startTag - 1; var shape = arrayShape[shapeId]; // Ajoute la nouvelle form à la <map ..> $("#wall1").append(' <area href="#imageTopLink"'+ 'id="areaMapGenerate-'+idCourant+ '" shape="'+shape+ '" coords="'+coords+ '" title="'+f.alertName+'" />'); // Actualise le maphilight $('.map').maphilight(); // Actualise les tooltips tooltip(); // Réinitialise les variables globales arrayClick = new Array(); circleLength = 0; } // Texte de la fenêtre prompt var txt = 'Le nom de la personne à tagger:'+ ' <input type="text" '+ 'id="alertName" '+ 'style="width:300px;" '+ 'name="alertName" '+ 'value="" />'; $.prompt(txt,{ callback: mycallbackform, buttons: { Ok: true }, focus: 1 }); } //Gestion de l'affichage ou non du maphilight $("#testTag").click(function() { maphilight = !maphilight; $('.map').maphilight({alwaysOn:maphilight}); }); // Initialisation $('.map').maphilight(); tooltip(); });
Cette mini-demo n'est pas optimisé, sécurisé et blablabla et blablabla. C'est juste à titre d'exemple.
Il serait effectivement judicieux que l'utilisateur puisse visualiser les clicks en direct, voir la forme dynamiquement modifier.
Il faudrait également rajouter la modification de ces formes.
Bref faite travailler votre imagination sans oublier de rester les pieds sur terre et surtout sans oublier qu'un utilisateur veut faire un maximum de chose en un minimum d'action =D
Bon dév !
Hello ! Tu ne met pas a disposition le Plugin jQuery “maphilight” ? Vu qu’il est legeremenet modifié ca aurait pu etre bien ! Merci en tout cas pour ce tuto c’est vraiment pas mal ! Dernière question, une piste pour afficher le polygone pendant qu’on est entrain de le créer ? je ne vois pas comment faire ! Merci
Salut brizoo,
Tu as raison, je vais le mettre à disposition. Pour dessiner en temps réel, je ne vois qu’une seule solution : L’utilisation d’un canvas. L’idée est intéressante, si j’ai le temps j’essayerai de faire une démo avec un canvas.
Salut Benjamin, merci pour ce tuto qui ma beaucoup aidé je l’ai modifier pour arrivé à mes fins, peut tu m’aider a utiliser les canvas ! Merci ^^
Salut Dalal, Si tu as quelques questions, tu peux m’envoyer un mail. Je n’ai pas beaucoup de temps, mais j’essayerai d’y répondre. Bon dév!
Salut tous le monde, esque quelqu’un a pu fair: visualiser les clicks en direct la modification des formes Merci
Bonjour – Très intéressant. J’ai télé(dé)chargé les sources à plusieurs reprises, mais le fichier zip semble corrompu: ni Windows ni un utilitaire d’extraction (7-zip) n’arrivent à le lire … Pourriez-vous vérifier ? Merci d’avance.
Salut LeDanD!
Merci pour le commentaire, j’ai remis à jours le fichier zip. Dis moi si cela fonctionne maintenant!
Bonne soirée.
Cliquez ici pour annuler la réponse.
Hello ! Tu ne met pas a disposition le Plugin jQuery “maphilight” ? Vu qu’il est legeremenet modifié ca aurait pu etre bien ! Merci en tout cas pour ce tuto c’est vraiment pas mal ! Dernière question, une piste pour afficher le polygone pendant qu’on est entrain de le créer ? je ne vois pas comment faire ! Merci
Salut brizoo,
Tu as raison, je vais le mettre à disposition.
Pour dessiner en temps réel, je ne vois qu’une seule solution : L’utilisation d’un canvas.
L’idée est intéressante, si j’ai le temps j’essayerai de faire une démo avec un canvas.
Salut Benjamin, merci pour ce tuto qui ma beaucoup aidé je l’ai modifier pour arrivé à mes fins, peut tu m’aider a utiliser les canvas !
Merci ^^
Salut Dalal,
Si tu as quelques questions, tu peux m’envoyer un mail.
Je n’ai pas beaucoup de temps, mais j’essayerai d’y répondre.
Bon dév!
Salut tous le monde, esque quelqu’un a pu fair: visualiser les clicks en direct
la modification des formes
Merci
Bonjour – Très intéressant.
J’ai télé(dé)chargé les sources à plusieurs reprises, mais le fichier zip semble corrompu: ni Windows ni un utilitaire d’extraction (7-zip) n’arrivent à le lire … Pourriez-vous vérifier ?
Merci d’avance.
Salut LeDanD!
Merci pour le commentaire, j’ai remis à jours le fichier zip. Dis moi si cela fonctionne maintenant!
Bonne soirée.