JavascriptProva

domenica 16 dicembre 2012

Linee animate in Processing

Proviamo a disegnare una linea animata, adesso.
int x=0;
void setup(){
  background(100);
  size(1000,800);
  frameRate(200);
  fill(100);
}
void draw(){
  x++;
  line(0,0,x,500);
}
Ecco, la linea non si muove, ma disegna un triangolo. Per far disegnare un cerchio, dovrei usare le funzioni trigonometriche...
Ma se io voglio che la linea si sposti, posso procedere a quell'artifizio col background... Proviamo.
int x=0;
void setup(){
  background(100);
  size(1000,800);
  frameRate(10);
  fill(100);
}
void draw(){
  x++;
  line(0,0,x,500);
  background(100);
}
...che non funziona!
Vediamo con il contatore di frames...

Ecco: un buon artifizio è questo!
int x=0;
void setup(){
  background(100);
  size(1000,800);
  frameRate(100);
  fill(100);
}
void draw(){
  line(0,0,x,500);
  if(frameCount%5==0) {
    background(100);
    x++;
  }
}
Funziona! ...anche se la linea si muove un po' lentamente.
Ho appreso un artifizio per fare i loop. Fare l'operazione frameCount % [numero di frames che compongono il loop]. Ogni volta che il numero di frames eseguiti è divisibile per il numero di frames che compongono il loop, il risultato dell'operazione MODULO è zero, e questa viene posta come condizione per ottenere un effetto.

Primi rudimenti con Processing

Dunque...

Iniziamo con il metodo (o funzione) void setup...

Ecco:
void setup(){
  size(500,500);
}
Così facendo, con il comando size() imposto l'area del mio canvas. Ci provo con l'editor di Processing.
Ottengo una finestra del calibro voluto.

Ora ci disegno una linea:
void setup(){
  size(500,500);
}
void draw(){
  line(10,10,400,400);
}
Benissimo! Ci sono riuscito.

Ora divaghiamo...

Caricare un'immagine. Cerchiamo su Google "load image"...
PImage img;
void setup(){
  size(500,500);
  stroke(0);
  img=loadImage("bella.jpg");
}
void draw(){
  image(img,0,0,img.width/2,img.height/2);
}
Risultato:

Bene...

Quindi il caricamento dell'immagine è indipendente dalla sua visualizzazione.
L'immagine è stata preventivamente messa nella cartella "data" del file .pde.

martedì 11 dicembre 2012

Canvas: per prima cosa rendiamo un canvas trascinabile, potrebbe servire.

Bene... Sono riuscito a creare una libreria dragdrop.js che contiene l'essenziale per trascinare elementi sulla pagina web.
Essa viene chiamata semplicemente dando all'evento window.onload istruzione di eguagliare l'evento document.onmousedown alla funzione OnMouseDown e l'evento document.onmouseup alla funzione OnMouseUp, e di impostare la proprietà di stile position a "absolute" per gli elementi che si vuole trascinabili.

Ora occupiamoci del canvas.
Dato che sto lavorando con Internet Explorer a causa del fatto che è l'unico browser che mi consente di salvare files su disco fisso, e quindi di mantenere e modificare archivi xml, devo imparare la sintassi del canvas per IE.

Anche il canvas può essere soggetto a DragDrop, impostando le giuste proprietà:
<!DOCTYPE HTML>
<html>
<head>
<style>
#mycanvas{
   border:1px solid red;
   position:absolute;
}
</style>
<script src="funzioni.js"></script>
<script src="dragdrop.js"></script>
<script>
function main(){
 document.onmousedown=OnMouseDown;
 document.onmouseup=OnMouseUp;
}
window.onload=main;
</script>
</head>
<body>
   <canvas id="mycanvas" width="100" height="100">
</body>
</html>
Ecco: con il richiamo delle librerie "dragdrop.js" e "funzioni.js", e impostando quei semplici comandi, il canvas si muove se trascinato.

lunedì 5 novembre 2012

Incapsulamento

Ecco uno schema per creare delle interfacce istanziando oggetti e incapsulando, anzichè creando noiosi innerHTML nei quali mi perdo:

Questo è il costruttore dell'oggetto interfaccia:
function interfaccia(){
 var Me;
 var Notizie;
 var creaMe=function(){
  Me=document.createElement("div");
  Me.setAttribute("className","interfaccia");
  document.body.appendChild(Me); 
  
  var Notizie=new notizie();
  Me.appendChild(Notizie.Me);
 
 }
 creaMe();
 
 this.Me=Me; 
}
Nel contesto di questo costruttore viene istanziato l'oggetto notizie da un altro costruttore, in cui è prevista anche la presenza di una textarea:
function notizie(){
 var Me;
 var Testo
 
 var creaMe=function(){
  //Crea l'oggetto
  Me=document.createElement("div");
  Me.setAttribute("className","bordatoblu");
  
  //Crea la Textarea
  var testo=document.createElement("textarea");
  Testo=testo
  Me.appendChild(testo);
  
 }
 creaMe();
 this.Me=Me;
 
}
Di questo secondo oggetto viene resa pubblica soltanto l'interfaccia Me, ma aggiungendo un this.Testo=Testo potrei rendere pubblica anche la textarea, facendo sì che possa essere gestita anche da altre aree del programma.

domenica 28 ottobre 2012

Oggetto con proprietà dai nomi uguali a quelli dei nodi dell'XML

Procediamo per ordine.
Bisogna innanzitutto vedere quali sono i primi nodi di un documento.
Prendiamo il mio documento xml piuttosto semplice e vediamo quali sono i primi nodi.
La prima proprietà di un oggetto che rappresenta un record del mio database dovrebbe essere il tag che rappresenta.
Cerco di creare una proprietà dell'oggetto che abbia lo stesso nome del tag che rappresenta.
Come fare?

La proprietà la chiamo tipo in quanto il suo nome è rappresentativo del tipo di informazione contenuto nel record. Dato che la mia tabella è fatta di persone, il tag si chiama <persona>.
Ecco il codice:
function record(){
 this.tipo=root.childNodes[0] 
}
In pratica assegno alla proprietà tipo il primo elemento figlio del documento.
Questo approccio non è corretto. Infatti se poi vado a usare istanze dell'oggetto che rappresentano records diversi dal primo, le loro proprietà tipo non dovranno rappresentare il primo nodo figlio del documento, ma quelli successivi.

Il ragionamento che posso fare è questo:
  • individuare il nome dei primi nodi figli del documento.
  • assegnare alla proprietà tipo del record il nodo figlio con quel nome identificato da un numero.
function record(num){
 var nomeNodo=root.childNodes[0].nodeName;
 this.tipo=root.getElementsByTagName(nomeNodo)[num];
}
La prima riga prende il nome del primo nodo figlio del documento.
La seconda riga assegna alla proprietà tipo dell'oggetto il nodo figlio identificato dal numero num, presente come parametro.
Ma ora voglio di più.
Voglio che il nome della proprietà sia uguale al nome del primo nodo figlio che viene trovato.
Ci provo:
function record(num){
 var nomeNodo=root.childNodes[0].nodeName;
 this[nomeNodo]=root.getElementsByTagName(nomeNodo)[num];
}
e poi istanzio l'oggetto chiedendo di mostrarmi il nome del nodo della proprietà persona dell'oggetto.
function init(){
 Record=new record(0);
 alert(Record.persona.nodeName);
}
Dunque la proprietà persona dell'oggetto richiama immediatamente l'omonimo tag di ogni record della tabella.
Sembra che stia procedendo bene, almeno questo è quanto sono riuscito a fare finora.

Ora andiamo avanti con altre proprietà...
Ecco, sembra che sia riuscito a ottenere un codice con un minimo di funzionalità:
function record(num){
 var nomeNodo=root.childNodes[0].nodeName;
 this[nomeNodo]=root.getElementsByTagName(nomeNodo)[num];
 
 var nodo=this[nomeNodo];
 
 for(var i=0;i<nodo.childNodes.length;i++){
  nomeNodo=nodo.childNodes[i].nodeName;
  this[nomeNodo]=nodo.getElementsByTagName(nomeNodo);
 }
}
La prima parte desume il nome dei primi nodi figli nella variabile nomeNodo, quindi la usa per creare una proprietà con lo stesso nome dei nodi, alla quale assegna il nodo figlio indicato dal numero fornito come parametro nel costruttore dell'oggetto.

Ora, questa proprietà, che ha il valore di un oggetto, viene immagazzinata nella variabile privata nodo.

Quindi questa proprietà viene usata ripetutamente, per quanti sono i nodi figli, per desumere il nome dei nodi figli e creare le relative proprietà con gli stessi nomi dei nodi figli.

Così, quando istanzio l'oggetto, posso usare direttamente il nome dei nodi come fossero delle semplici proprietà dell'oggetto:
function init(){
 Record=new record(0);
 alert(Record.nome[0].text);
 alert(Record.cognome[0].text);
 alert(Record.professione[0].text);
 alert(Record.figlio[0].text)
 alert(Record.figlio[1].text);
}
Devo mettere lo zero quando le proprietà non sono array, mentre quando lo sono, come nel caso della proprietà "figlio", devo specificare l'indice dell'array.
Provo a usare un risultato più "grafico" in modo da copiarlo e incollarlo qui.
function init(){
 Record=new record(0);
 document.write(Record.nome[0].text+" "+
 Record.cognome[0].text+" "+
 Record.professione[0].text+" "+
 Record.figlio[0].text+" "+
 Record.figlio[1].text);
 
 document.write("<br>");
 
 Record=new record(1);
 document.write(Record.nome[0].text+" "+
 Record.cognome[0].text+" "+
 Record.professione[0].text);
}
Ed ecco il risultato:
Ciccio Rossi rapinatore Giovanni Luigi
Giuseppe Verdi Musicista


Il fatto che il secondo record non abbia i campi "figlio" fa sorgere tutta una serie di interrogativi che vedrò di affrontare successivamente...

Metodo per cambiare il valore di un campo nel file XML

Bene. Ho messo a punto anche un metodo "cambia()" per il mio schema di oggetto atto alla manipolazione dei files XML.
function persona(num){
 var record=root.getElementsByTagName("persona")[num];
 
  this.nome=record.getElementsByTagName("nome")[0];
  this.cognome=record.getElementsByTagName("cognome")[0];
  this.professione=record.getElementsByTagName("professione")[0];
  this.figli=record.getElementsByTagName("figlio");
  this.cambia=function(campo,valore){
   record.getElementsByTagName(campo)[0].childNodes[0].nodeValue=valore;
   var fso=new ActiveXObject("Scripting.FileSystemObject");
   var path=document.location.pathname;
   path=path.substr(1,path.lastIndexOf("/"));
   path=path.replace(/%20/g," ");
   var f=fso.CreateTextFile(path+"data.xml",true);
   f.write(xmlDoc.xml);
   f.Close();
   fso=null;
  }
}
Funziona.

sabato 27 ottobre 2012

Creazione di oggetti per muoversi in un file XML

Un piccolo artifizio per facilitarsi la vita con le tabelle costruite intorno ai files XML.
C'è un oggetto che rappresenta il record, le cui proprietà sono rappresentate dai suoi childNodes, come se fossero tanti elementi di una tabella.
L'oggetto viene poi istanziato in base al numero ordinale.
var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load("data.xml");
var root=xmlDoc.documentElement;

function persona(num){
 var record=root.getElementsByTagName("persona")[num];
 
  this.nome=record.getElementsByTagName("nome")[0];
  this.cognome=record.getElementsByTagName("cognome")[0];
  this.professione=record.getElementsByTagName("professione")[0];
  this.figli=record.getElementsByTagName("figlio");
}
function init(){
Mario=new persona(0);
Giuseppe=new persona(1);
alert(Mario.nome.text);
alert(Mario.cognome.text);
 for(var n=0;n<Mario.figli.length;n++)
  alert(Mario.figli[n].text);
}
window.onload=init;
costruito per questo XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE tabella [
<!ELEMENT tabella (persona*)>
<!ELEMENT persona (nome, cognome, professione,figlio*)>
<!ELEMENT nome (#PCDATA)>
<!ELEMENT cognome (#PCDATA)>
<!ELEMENT professione (#PCDATA)>
<!ELEMENT figlio (#PCDATA)>
]>
<tabella>
 <persona>
  <nome>Mario</nome>
  <cognome>Rossi</cognome>
  <professione>Ladro</professione>
  <figlio>Giovanni</figlio>
  <figlio>Luigi</figlio>
 </persona>
 <persona>
  <nome>Giuseppe</nome>
  <cognome>Verdi</cognome>
  <professione>Musicista</professione>
 </persona>
</tabella>


Mi sembra molto funzionale, perchè istanziando volta per volta l'oggetto si può accedere a tutti i record della "tabella" e prenderne i campi desiderati come proprietà dell'oggetto.