28 aprile 2015

Javascript e video random

Per motivi vari dovevo preparare dei test basati sulla somministrazione di video. Esperienze precedenti mi hanno portato a considerare $pauerpoint come qualcosa di incredibilmente ingombrante e ricco di complicazioni, specialmente se il test doveva essere usato su computer diversi (mac e/o pc, con versioni sia di SO che di $pauerpoint molto probabilmente diverse). Figurarsi voler "randomizzare" questi video.

Per questo ho deciso invece di usare Firefox e il formato video webm, almeno per le versioni "preliminari" di questi test (quelle che nemmeno arrivano allo 0.9.9, per capirci :)) E dato che il tutto doveva avvenire in "locale", dovevo necessariamente usare javascript.

Qui di seguito troverete il codice per randomizzare un array di video:

<!DOCTYPE html><html><head><meta charset="utf-8" />
<title>Test Video con 3 bottoni</title>
<!-- https://raw.githubusercontent.com/coolaj86/knuth-shuffle/master/index.js -->
<!-- http://bost.ocks.org/mike/shuffle/  -->
<link href="css.css" type="text/css" rel="stylesheet">
<script type="text/javascript">

var TestFilm = ["00_cor","01_cor","02_err","..."]; /* qui mettete solo il NOME dei filmati */

var Info1  =  ["italiano","straniero"]; /* esempio di informazioni per dropdown menù */

/* questa è la funzione di randomizzazione usata */
function kshuffle(array) {
    var m = array.length, t, i;
    while (m) {
        i = Math.floor(Math.random() * m--);
        t = array[m];
        array[m] = array[i];
        array[i] = t;
    }
    return array;
}

var NewFilm = kshuffle(TestFilm);
var risultati = [];

/* serve per confermare il bottone premuto e salvare i risultati */
function GoAhead(reslt) {
    if (reslt == "1") {var btn = ",verde";} else {var btn = ",rosso";}
    if (((NewFilm[0].search("_cor") != -1) && (reslt == "1")) || ((NewFilm[0].search("_err")!= -1) && (reslt == "0")))
        {esito = NewFilm[0]+" OK,1"+btn} else {esito = NewFilm[0]+" NO,0"+btn;}
    document.getElementById("avanti").innerHTML = '<img src="img/avanti0.png" width="95" height="70" hspace="30"'+
    ' onmouseover="this.src=\'img/avanti1.png\';" onmouseout="this.src=\'img/avanti0.png\';"'+
    ' onclick=\'NextFilm("'+esito+'")\'>';
}

/* mostra il film presente nell'array NewFilm[0] */
function ShowFilm(){
    if (NewFilm.length >= 1) {
        var filmato = '<video src="webm/'+NewFilm[0]+'.webm" controls mute muted width="960" height="540" '+
        'preload="auto" id="video"></video>';
        document.getElementById("Test").innerHTML = '<p align="center" id="Filmato"></p>';  
        document.getElementById("Filmato").innerHTML = '<table align="center" width="100%">'+
        '<tr align="center" valign="middle"><td width="20%">&nbsp;</td>'+
        '<td align="center" width="60%">'+filmato+'</td><td align="right" width="20%" id="avanti">'+
        '<img src="img/avanti_null.png" width="95" height="70" hspace="30"></td></tr><tr><td></td><td>'+
        '<img src="img/si_0.png" style="vertical-align: middle; float: left;" align="left" '+
        'width="80" height="85" vspace="30" hspace="90" id="giusto" onmousedown="this.src=\'img/si_1.png\';'+
        ' errato.src=\'img/no_0.png\';" onclick="GoAhead(1)"> &nbsp; '+
        '<img src="img/no_0.png" style="vertical-align: middle; float: right;" align="right" width="80"'+
        ' height="85" vspace="30" hspace="90" id="errato" onmousedown="this.src=\'img/no_1.png\'; '+
        'giusto.src=\'img/si_0.png\';" onclick="GoAhead(0)">'+
        '</td><td></td></tr></table>';
    } else {
        document.getElementById("Test").innerHTML = '<h3>Il test è terminato!<br>'+
        'Grazie mille per la tua collaborazione</h3>'+
        '<p align="center"><form method="get" name="AltriDati" id="AltriDati">'+
        '<b>Nome:</b>&nbsp;<input type="text" name="nome" value=""> '+
        '<b>Cognome:</b>&nbsp;<input type="text" name="cognome" value=""> '+
        '<b>Età:</b>&nbsp;<input type="text" name="età" size="4" maxlength="4"></p>'+
        '<p align="center"><b>Tipologia:</b>&nbsp;<select name="tipologia" id="tipologia" size="1"></select> '+
        '<b>Inizio:</b>&nbsp;<input type="text" name="inizio" value=""></p>'+
        '<p align="center"><textarea name="annotazioni" rows="6" cols="60"></textarea></p>'+
        '<p align="center" style="text-decoration: underline;" id="Estrazione Risultati" '+
        'onclick="return ShowResults(this.form)"><b>Mostra (o aggiorna) i risultati</b></form></p>'+
        '<div id="EsitoTest" align="center" valign="middle" style="text-align: center; '+
        'vertical-align: middle;"></div>';

        for(var i = 0; i < Info1.length; i++) {
            var opt = document.createElement('option');
            opt.innerHTML = Info1[i]; opt.value = Info1[i];
            document.getElementById("tipologia").appendChild(opt);
        }
    }
}

/* mette in risultati[0] i dati passati tramite GoAhead() e toglie, se necessario, il film appena visto da NewFilm[0] */
function NextFilm(result) {
    var risultato = result+",";
    if (NewFilm.length >= 1) {
        risultati.push(risultato); NewFilm.shift(); ShowFilm();
    } else {
        risultati.push(risultato);
    }
}

/* ordina i risultati per film, crea un file csv e visualizza i risultati delle risposte ad ogni film */
function ShowResults(form) {
    var f = document.AltriDati;
    var OrdRis = risultati.sort();
    var d= new Date();
    var Oggi = d.getDate()+'/'+(d.getMonth()+1)+'/'+d.getFullYear()+' '+d.getHours()+':'+d.getMinutes();
    var fileName = d.getFullYear()+'_'+(d.getMonth()+1)+'_'+d.getDate()+'_'+f.cognome.value+".csv";
    var buffer = "Data:,"+Oggi+"\r\nNome Cognome:,"+f.nome.value+' '+f.cognome.value+"\r\nEtà:,"+
        f.età.value+"\r\nTipologia:,"+f.tipologia.value+"\r\nInizio:,"+f.inizio.value+
        "\r\n\r\nNote:,\""+f.annotazioni.value+'\"'+
        "\r\n\r\nRisultati (ordinati per film) ⇊⬇⇊,\r\n"+OrdRis.join("\r\n");
    var blob = new Blob([buffer],{type: 'text/csv;charset=utf-8;'});
    var lnkcsv = document.createElement('a');
    var urlcsv = URL.createObjectURL(blob);

    lnkcsv.href = urlcsv;
    lnkcsv.align = 'center';
    lnkcsv.style = 'text-align: center';
    lnkcsv.download = fileName;
    lnkcsv.innerHTML = 'Salva come CSV';

    document.getElementById("EsitoTest").innerHTML = '<p align="center" id="MostraRisultati">'+
    '<b>Clicca sul link al CSV, oppure copia ed incolla</b><br><span id="LinkCsv"></span></p>'+
    '<hr align="center" size="1" width="80%" noshade="noshade"></hr>'+
    '<p align="center" style="text-align: center; -moz-column-count: 4; -moz-column-gap: 10px;'+
    ' -webkit-column-count: 4; -webkit-column-gap: 10px;">'+
    OrdRis.join('<br>')+'</p><hr align="center" size="1" width="80%" noshade="noshade"></hr>';
    document.getElementById("LinkCsv").appendChild(lnkcsv);
}
</script>
</head>
<body class="content" valign="middle" align="center" style="text-align: center; vertical-align: middle;">
<div id="Test" class="table" align="center" valign="middle" style="text-align: center; vertical-align: middle;">
<noscript><h3 align="center" style="color: #AA0000; text-decoration: blink;">Buongiorno! Fatti un caffè, disattiva NoScript e poi riprova...</h3></noscript>
<script type="text/javascript">ShowFilm();</script>
</div></body></html>

Oltre al video, questo codice prevede due risposte date mediante due bottoni separati ed una freccia per passare al filmato successivo, tutti e tre con animazioni. il "avanti_null" è semplicemente una png "vuota" delle stesse dimensioni della freccia vera e propria che compare solo DOPO che si è premuto uno o l'altro bottone. Se si cambia idea e si preme l'altro bottone, il bottone premuto precedentemente torna alla immagine originaria. Il premere la freccia "avanti" memorizza in un array, con push, la scelta effettuata, e rimuove con shift dalla prima posizione dell'array il film appena visto prima di ritornare alla funzione ShowFilm. Si arriva alla schermata di inserimento di ulteriori informazioni quando l'array NewFilm è ormai vuoto.

Lo metto qua perché, per essere una soluzione "home made", mi sembrava onesto metterla a disposizione di chi, per motivi vari (soldi, tempo, disponibilità), non può o non ha bisogno di roba incredibilmente più raffinata o, banalmente, abbisogna di una impalcatura di base per le versioni PRELIMINARI di un test in via di sviluppo. Fatene quel che cazzo pare a voi e alla vostra coscienza :)

Nessun commento:

Posta un commento

NOTA BENE: Se vi ostinate a commentare posts di un mese fa, scatta la moderazione (se non sono in vacanza, controllo quasi ogni giorno)... Ovviamente, se siete spammers vi cancello :)