Uso di SVG nella didattica

   Agli strumenti a disposizione di un docente per la costruzione di ipertesti didattici online come HTML, Javascript, Java, Flash si e' aggiunto SVG uno degli ultimi arrivati. Esso e' in effetti un particolare dialetto XML: e' stato soprannominato l'HTML della grafica vettoriale. Gli esempi mostrati in questo seminario dovrebbero aiutare a mostrare sia la semplicita' di uso che le possibilita' che offre specialmente nella creazione di materiali didattici interattivi per l'insegnamento della scienza.

Giuseppe Zito

Questo documento e' stato usato in un seminario tenuto il giorno 8 Aprile 2005 nel Dipartimento di Fisica di Bari . Suggerimenti e commenti sono graditi: spediteli a zito@ba.infn.it.



Materiali usati nel seminario
Simulazione di lancio di monete prova ad usarlo


<html>
<head>
<script  language="Javascript">
function genera(modulo) {
 var n =modulo.finestra.value;
 if(n > 100) n= 100;
 document.writeln("<html><body>");
 for (i=0;i<n;i++){
 if (Math.random() < .5) document.write("<img src=\"retro.jpg\" width=100 height=100>");
  else
     document.writeln("<img src=\"fronte.jpg\" width=100 height=100>");
 }
 document.writeln("<body><html>");
}
</script>
</head>
<body>
<form name="scheda">
<input type=text name="finestra" value=5>
<br>
<input type=button value="Numero di lanci da fare" onClick="genera(this.form)">
</form>
</body>
</html>

Poligono regolare prova a calcolare le coordinate e a guardare il poligono svg


<html>
<head>
<script  language="Javascript">
function calcola(modulo) {
 var n =modulo.nlati.value;
 var s = '<path d=\"';
 var cx = 100, cy = 100, r = 50;
 var xmax=200;ymax=200;
 if(n > 100) n= 100;
 var angolo=Math.PI/180.*(360/n);
 x0=r;y0=0;
 for (i=0;i<n;i++){
  xc = x0 + cx; yc = y0 + cy;
  yc= ymax-yc;
  if(i==0){s = s + 'M ' + xc +' '+yc+' \n';}
   else { s = s + 'L ' + xc +' '+yc+' \n';}
  x = x0*Math.cos(angolo) - y0*Math.sin(angolo); 
  y = x0*Math.sin(angolo) + y0*Math.cos(angolo); 
  x0 = x; y0 = y;
 }
 s = s + 'z\"  fill="yellow" stroke="black" stroke-width="3"/>';
 modulo.risultato.value = s;
}
</script>
</head>
<body>
<form name="scheda">
<input type=text name="nlati" value=6>
<br>
<textarea name="risultato" cols="80" rows="4"></textarea>
<br>
<input type=button value="Calcola le coordinate del poligono" onClick="calcola(this.form)">
</form>
</body>
</html>

Spirale di esagoni guardate l'immagine svg

<xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" >
<defs>
<g id="esagono" transform="translate(-100,-100)">
<path d="M 150 100 
L 125 56.698729810778076 
L 75 56.69872981077805 
L 50 99.99999999999999 
L 74.99999999999999 143.30127018922192 
L 124.99999999999997 143.30127018922195 
z" fill="yellow" stroke="black" stroke-width="1"/>
</g>
</defs>
<g transform="translate(100,100)" >
<use xlink:href="#esagono" />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
<g transform="scale(.9,.9) rotate(6)"><use xlink:href="#esagono"  />
</g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g> </g>
</svg>

Animazione prova ad usarlo


<svg>
  <circle cx="250" cy="250" r="10" fill="red" >
    <animate attributeName="cx" from="1" to="250" dur="5s" 
              repeatCount="5" />
    <animate attributeName="cy" from="1" to="250" dur="5s" 
              repeatCount="5" />
  </circle>
</svg> 

Moto circolare 1 prova ad usarlo


<svg>
  <path d="M300,50   a150,150 0 1 0 0.01 0 z" style="fill: none;
            stroke:black;"/>
  <circle r="25"  style="fill: red; stroke: black;" >
    <animateMotion path="M300,50   a150,150 0 1 0 0.01 0 z" dur="6s"
              fill="freeze"/>
  </rect>
</svg>


Moto circolare 2 prova ad usarlo


<xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  width="800" height="600" >

<g transform="translate(400,300)">
  <circle r="18"  style="fill: red;" />

<g>
<g  transform="translate(-150,0)">
  <circle r="8"  style="fill: blue;" />

<g>
<g  transform="translate(-50,0)">
  <circle r="4"  style="fill: gray;" />
</g>
  <animateTransform type="rotate" repeatCount="100"   from="0" to="360" dur="1s" attributeName="transform"/>
</g>

</g>
  <animateTransform type="rotate" repeatCount="100"   from="0" to="360" dur="8s" attributeName="transform"/>
</g>

</g>

</svg>
  • Animazione realizzata con animateTransform
    Generazione di un poligono regolare a caso prova ad usarlo

    
    <xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" viewBox=" 0 0 300 300 " onload="disegna(evt)" >
    <script type="text/javascript">
    <![CDATA[
    function disegna(evt) {
    var n =Math.round(Math.random()*12+3);
    var targ = evt.getTarget();
    svgdoc = targ.getOwnerDocument();
    poligono = svgdoc.getElementById('poligono');
     var s = '';
     var cx = 100, cy = 100, r = 50;
     var angolo=Math.PI/180.*(360./n);
     x0=r;y0=0;
     for (i=0;i<n;i++){
      xc = x0; yc = y0;
      if(i==0){s = s + 'M ' + xc +' '+yc+' \n';}
       else { s = s + 'L ' + xc +' '+yc+' \n';}
      x = x0*Math.cos(angolo) - y0*Math.sin(angolo); 
      y = x0*Math.sin(angolo) + y0*Math.cos(angolo); 
      x0 = x; y0 = y;
     }
     s = s + 'z';
     poligono.setAttribute("d",s);
     }
    // ]]>
    </script>
    <g transform="translate(100,100)">
    <path d="M 150 100 
    L 135.35533905932738 64.64466094067262 
    L 100.00000000000001 50 
    L 64.64466094067264 64.64466094067262 
    L 50 99.99999999999999 
    L 64.64466094067261 135.35533905932735 
    L 99.99999999999997 150 
    L 135.35533905932735 135.35533905932738 
    z"  id="poligono" fill="yellow" stroke="black" stroke-width="3"/>
    </g>
    </svg>
    

    Figure di Lissajous prova ad usarlo

    
    <xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality" viewBox="0 0 400 400" zoomAndPan="disable" onload="disegna(evt)" >
    <script type="text/javascript">
    <![CDATA[
    function disegna(evt) {
    diagramWidth = 300;
    diagramHeight = 300;
    plotScale = (diagramHeight) / 2;
    plotCenter = (diagramHeight) / 2;
    nbPoints=500;
    var nbX =Math.round(Math.random()*12+1);
    var nbY =Math.round(Math.random()*12+1);
    var targ = evt.getTarget();
    svgdoc = targ.getOwnerDocument();
    lissajous = svgdoc.getElementById('lissajous');
     var s = 'M ';
     for( i = 0; i <= nbPoints; i++) {
            theta = i * 2 * Math.PI / nbPoints;
            x = Math.sin( nbX * theta);
            y = Math.sin( nbY * theta);
            x = x * plotScale + plotCenter;
            y = plotCenter - y * plotScale;
            s=s+"  "+x+" "+ y+" ";
     }
     s = s + 'z';
     lissajous.setAttribute("d",s);
     }
    // ]]>
    </script>
    <defs>
    <path d="M 150 100 
     135.35533905932738 64.64466094067262 
     100.00000000000001 50 
     64.64466094067264 64.64466094067262 
     50 99.99999999999999 
     64.64466094067261 135.35533905932735 
     99.99999999999997 150 
     135.35533905932735 135.35533905932738 
    z" id="lissajous" style="stroke:red; fill:white" />
    </defs>
    <g transform="translate(50,50)">
    <use xlink:href="#lissajous" />
    </g> 
    </svg>
    

    Grafico prova ad usarlo

    
    <?xml version="1.0" encoding="UTF-8"?>
    <svg height="400" width="400" onload="disegna(evt)">
    <script type="text/javascript">
    <![CDATA[
    function disegna(evt) {
    valori =new Array (11,23,23,45,5,61,73,180,95,100,110,12);
    var targ = evt.getTarget();
    svgdoc = targ.getOwnerDocument();
    grafico = svgdoc.getElementById('mese');
    titolo = svgdoc.getElementById('titolo');
    
    gennaio=grafico.getFirstChild().getNextSibling().getNextSibling().getNextSibling().getNextSibling().getNextSibling();
    gennaio.setAttribute("height",+valori[0]);
    gennaio.setAttribute("y",+(-valori[0]));
    prossimo_mese = gennaio;
      for(i=0;i<11;i++){
        prossimo_mese=prossimo_mese.getNextSibling().getNextSibling();
        prossimo_mese=prossimo_mese.getNextSibling().getNextSibling();
        prossimo_mese.setAttribute("height",+valori[i]);
        prossimo_mese.setAttribute("y",+(-valori[i]));
        }
    
     }
    
    // ]]>
    </script>
    <g transform="translate(0,200)" id="mese">
    <text y="50" x="50" id="titolo"> Grafico andamento annuale</text>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="32.5">Gen</text>
    <rect style="fill:red" width="15" height="31.5" y="-31.5" x="25"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="57.5">Feb</text>
    <rect style="fill:red" width="15" height="76.5" y="-76.5" x="50"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="82.5">Mar</text>
    <rect style="fill:red" width="15" height="180" y="-180" x="75"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="107.5">Apr</text>
    <rect style="fill:red" width="15" height="81" y="-81" x="100"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="132.5">Mag</text>
    <rect style="fill:red" width="15" height="10.5" y="-10.5" x="125"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="157.5">Giu</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="150"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="182.5">Lug</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="175"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="207.5">Ago</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="200"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="232.5">Set</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="225"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="257.5">Ott</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="250"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="282.5">Nov</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="275"/>
    <text style="font-family:arial;text-anchor:middle;baseline-shift:-15;" y="0" x="307.5">Dic</text>
    <rect style="fill:red" width="15" height="132" y="-132" x="300"/>
    </g>
    </svg>
    

    Moto di un grave prova ad usarlo

    <xml version="1.0" encoding="UTF-8"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  width="300" height="500" >
    <script type="text/javascript">
    <![CDATA[
       var cerchio;
       var i = 10;
       var t = 0;
    function muovi(evt)
    {
        cerchio = evt.getTarget();
        aggiorna();
    }
    function aggiorna() 
    {
       t = t + .1;
       i=i+t*t;
       cerchio.setAttribute("cy", i);
       setTimeout("aggiorna()", 50);
    }
    // ]]>
    </script>
    <text id="start" x="10" y="500" >Clicca sul cerchio per farlo cadere!</text>
    <circle r="8" cx="50" cy="10" fill="red" onclick="muovi(evt)" />
    </svg>
    </pre>
    
    Maintained by Giuseppe Zito: Giuseppe.Zito@cern.ch Last modified: