Bonjour à tous,

j'ai intégré le code d'un document svg directement dans un document html5. Mon objectif serait que des div de mon document html, identifiées par un id unique, apparaissent lorsque je survole certains éléments <path> du document svg.
Je sais que je pourrais intégrer ces div sous une forme ou un autre dans le document svg, mais voilà, il s'agit de texte mis en forme (arrière plan, arrondi de bordure...) et ça ne ressort pas toujours très bien en svg pur...
Mes maigres connaissances en html, svg, css et javascript ne me permettent pas de solutionner ce problème tout seul... Smiley bawling Quelle serait la solution?
Modérateur
Bonjour,

Il va falloir passer par du Javascript car en CSS c'est quasi impossible de réaliser ce que tu veux faire si les éléments ne sont pas parents.

Mais c'est pas très compliqué. Il suffit de récupérer le svg et d'attacher à chaque forme une fonction qui se déclenche au survol. Petite astuce j'utilise les attributs data-machin sur les formes du svg (http://www.alsacreations.com/article/lire/1397-html5-attribut-data-dataset.html) pour passer l'id du bloc à faire apparaître. Autres truc tricky j'ai utilisé un évènement "mouseout" pour savoir quand la souris ressort de la forme car le mouseover ne détecte que quand elle rentre... mais je ne sais pas s'il n'y a plus propre que ça..

Voici un exemple :
http://fiddle.jshell.net/8kjdmqh0/

Bonne aprem Smiley murf
Modifié par _laurent (08 Jul 2015 - 14:36)
Bonjour!
merci _laurent pour tes conseils! Je suis arrivé à faire fonctionner mon code comme je voulais en modifiant l'attribut display (none => inline-block).

Voici ce que ça donne:

<?xml version="1.0"?> 
<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <title>Test</title>
  <link rel="stylesheet" href="style.css">
  <script language="javascript" type="text/javascript">
function bascule(elem)
   {
   etat=document.getElementById(elem).style.display;
   if(etat=="none"){
   document.getElementById(elem).style.display="inline-block";
   }
   else{
   document.getElementById(elem).style.display="none";
   }
   }
</script>
  
  <LINK rel=STYLESHEET href="../spip/squelettes/css/styles.css" type="text/css">
  <LINK rel=STYLESHEET href="../spip/squelettes/css/stylearticle.css" type="text/css">
  
 
</head>

<body>

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">


  <rect width="100%" height="100%" fill="red" onmouseover="bascule('texte1');return false;"/>


</svg>

<div id="texte1">Texte à afficher au survol</div>

</body>
</html>


Maintenant, j'aimerais pourvoir ajouter un effet de transition qui fasse que le texte n'apparaisse pas brutalement comme il le fait avec l'attribut display. Je pensais faire varier l'attribut max-height de 0 à 15em dans mon script, mais je n'y arrive pas!!!
Modérateur
Salut,

C'est tout simple. A la place de :
document.getElementById(elem).style.display="inline-block";
// et
document.getElementById(elem).style.display="none";

il va faloir que tu joue sur la hauteur (ou l'opacité, ou autre chose que tu veux animer). Donc au lieu du display tu aura un truc du genre :
document.getElementById(elem).style.height="0px";
// et
document.getElementById(elem).style.height="500px"; // 500px c'est pour l'exemple hein tu met la taille qui va bien

Et après ca se passe coté CSS. Ton élément devra avoir une transition sur le paramètre que tu fais varier. Ici c'est height donc tu auras :
#texte1{
    transition: height 200ms; /* La aussi fait varier la durée comme tu le sent*/
}

Et... c'est tout Smiley smile
La déclaration de la transition en CSS dit que quand la height varie, il le fera en animation en 200ms et c'est ton js qui donne l'état d'arrivée.

Pense juste à rajouter un overflow:hidden; sur ton bloc #texte1 pour que rien ne dépasse.

Bonne journée Smiley smile
Alors, ça marche presque parfaitement! Il me reste deux soucis à résoudre:
- le script ne se déclenche pas au premier, mais au 2e passage de la souris sur l'objet svg, je ne sais pas pourquoi...
- même avec le max-height ramené à 0 et avec l'overflow:hidden, une partie de mon bloc de texte apparaît toujours. Pour plus de lisibilité, je mets mes codes séparément ci-dessous:

le html:
<?xml version="1.0"?> 
<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <title>test</title>
  <link rel="stylesheet" href="style.css">
  <script language="javascript" type="text/javascript" src="script.js"></script>
  
  <LINK rel=STYLESHEET href="../spip/squelettes/css/styles.css" type="text/css">
  <LINK rel=STYLESHEET href="../spip/squelettes/css/stylearticle.css" type="text/css">
  
 
</head>

<body onload:"afficher(elem);">

<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">

  <rect width="100%" height="100%" fill="red" onmouseover="afficher('texte1');return false;" onmouseout="cacher('texte1');return false;"/>

</svg>


<div id="texte1">Texte à afficher au survol</div>

</body>
</html>


Le script:
function afficher(elem)
   {
   etat=document.getElementById(elem).style.maxHeight;
   if(etat=="0px"){
   document.getElementById(elem).style.maxHeight="500px";
   }
   else{
   document.getElementById(elem).style.maxHeight="0px";
   }
   }
   
 function cacher(elem)
   {
   {
   document.getElementById(elem).style.maxHeight="0px";
   }
   }
 


et enfin le CSS:
#texte1{
background-color: #B14934;
text-align: left;
font-size: 1.3em;
line-height:1.5em;
font-family: Tahoma;
color: white;
border-radius: 10px;
padding: 10px;
position:absolute;
max-height: 0px;
width:33%;
transition: max-height 5s;
display:inline-block;
overflow:hidden;
}


Ca doit tenir à un détail que je n'ai pas vu Smiley confused ...
Modifié par bouffandt (11 Jul 2015 - 15:18)
Bonjour bouffandt,
cela tient peut-être plus qu'à un détail : si ton script est placé dans le html avant l'appel css de l'élément à animer, il n'aura pas lu son css : cela explique l'inertie au premier passage, en fait de découverte !

Il y a deux possibilités nécessaires à ton problème :
1. placer le script en bas de html
2. attribuer de préférence à ton id (ou à tes id) une classe distincte que ton script va faire basculer vers une autre au onmouseover et ensuite au onmouseout. Ou sans rien changer de ton script, ton html peut/doit rependre l'état css de ton id.

Ainsi, dans le html :
<a id="truc_1" class="cacher">truc1</a>
[#green]//ou[/#]
<a id="truc_1" style="height:0">truc1</a>


Autre petite chose, mais que je ne comprends pas. Pourquoi :
<body onload:"afficher(elem);">
On aurait pu penser que tu initie ton id="truc_1" ...
<body onload:"afficher('truc_1');">
et c'aurait été une autre solution, mais alors pour le faire disparaître, et donc l'initier au javascript :
<body onload:"cacher('truc_1');">
Mais parce que ton script sera placé en fin de html, c'est plutôt là que devras initier ton élément :
<script
//Ici ta/tes fonction(s)
...
//et enfin :
afficher("truc_1");
</script>


Enfin tu pourrais compiler en une seule fonction (toute simple) tes 2 fonctions afficher(id) cacher(id) par 2 conditions :
if, else if
s'il était possible d'attribuer un id="x" à ton rectangle svg.

Dans l'exemple que je donne, ceci fonctionne bien (sans svg) :
<?xml version="1.0"?> 
<!doctype html>
<html lang="fr">

<head>
 <meta charset="utf-8">
<title>essai</title>
<style>
.cacher{display:inline-block;max-width:0;background:#fff;color:#fff;transition:all ease .5s;overflow:hidden}
.afficher{display:inline-block;max-width:60px;background:#ece;color:#000;transition:all ease .5s;overflow:hidden}
</style>
</head>

<body>
<div>
<a id="rectangle1" onmouseover="alterner('rectangle1','texte1')">Rectangle1</a> <a id="rectangle2" onmouseover="alterner('rectangle2','texte2')">Rectangle2</a>
<br />
<a id="texte1" class="cacher"><i>Coucou&nbsp;!</i><br />Texte1</a><a id="texte2" class="cacher"><i>Coucou&nbsp;!</i><br />Texte2</a>
</div>

<script>
function alterner(elem1,elem2)
{
elem1=document.getElementById(elem1);
elem2=document.getElementById(elem2);
elem1.onmouseover=function(){elem2.className="afficher"};
elem1.onmouseout=function(){elem2.className="cacher"};
}

alterner('rectangle1','texte1');//Initier les 2 éléments au chargement de la page.
alterner('rectangle2','texte2');//Initier les 2 éléments au chargement de la page.
</script>

</body>
</html>

Modifié par pictural (12 Jul 2015 - 15:21)
bouffandt a écrit :
Merci pour tes conseils! Ca marche enfin!

Et pour être parfait, dès lors que l'on a effectivement initié des couples de 2 éléments en fin de script, il n'est pas utile ni nécessaire de pratiquer dans le html le onmouseover (qui provoque une redondance inutile).

Ainsi dans le html, ce qui suit à la ligne correspondante est suffisant :
<a id="rectangle1">Rectangle1</a> <a id="rectangle2">Rectangle2</a>
et donc parfaitement performant
Modifié par pictural (13 Jul 2015 - 21:46)