UI/UX Design & Analysis

Progetti di UI/UX e Analisi

In questa sezione raccolgo esercizi e mini-progetti con cui ho iniziato a esplorare UX, UI e un po’ di front-end. Sono lavori didattici e di base: servono a mostrare il percorso di apprendimento, il metodo e l’attenzione ai dettagli, più che risultati “finito-prodotto”.

Mini-Progetto Web

Pagina web interattiva realizzata con HTML, CSS e JavaScript.

Testing e Analisi

Esercitazioni con task tree, valutazioni SUS e report di usabilità e accessibilità..

Festival Design

Prototipazione UI sviluppata in Figma e implementazione iniziale in WordPress.

Mini-Progetto Web

Pievepelago

Il progetto rappresenta un mini sito web interattivo sviluppato come esercitazione pratica ai fondamenti di HTML, CSS e JavaScript, con un focus sulla progettazione UX/UI e sull’integrazione di logiche funzionali.

La scelta di ambientarlo a Pievepelago, località montana dell’Appennino modenese, non è casuale: l’obiettivo era combinare lo sviluppo tecnico con un contenuto reale e personale. Le fotografie dei paesaggi e dei percorsi escursionistici sono state scattate personalmente, così da rendere l’esperienza più autentica e contestualizzata.

🔹 Funzionalità principali

  1. Calcolo distanze e tempi di percorrenza
    L’utente può selezionare un luogo di partenza e uno di arrivo tra diversi punti di interesse (Monte Giovo, Monte Rondinaio, Lago Santo Modenese, Lago Baccio).
    Il programma, sfruttando una struttura dati JavaScript (distanze), restituisce:
    • i chilometri di distanza tra i due punti;
    • il calcolo dei minuti di percorrenza moltiplicando tempo stimato × km, con gestione di input validi/non validi.
  2. Gestione errori e feedback dinamico
    Sono stati implementati controlli per:
    • campi vuoti, valori non numerici o negativi;
    • messaggi di errore in tempo reale con aggiornamento dinamico della pagina.
  3. Lista interattiva “Oggetti in valigia”
    Una mini-applicazione interna consente di inserire elementi da portare nello zaino, aggiungerli a una lista e rimuoverli in qualsiasi momento.
    Questa sezione unisce l’aspetto ludico a quello pratico, simulando una checklist per l’escursionista.
  4. Slider fotografico
    Con JavaScript puro è stato realizzato uno slider di immagini dei laghi e dei sentieri, con frecce di navigazione e indicatori (dots). Questo permette di esplorare i contenuti visivi in modo più dinamico.
  5. Navigazione e UI
    • Un menù orizzontale (Percorsi, Laghi, Attività) guida la navigazione.
    • Lo stile, realizzato in CSS personalizzato, adotta colori coerenti con l’ambiente naturale (azzurro, verde, lightcyan).
    • Sono stati applicati effetti di hover, ombre sui testi e un layout centrato per garantire leggibilità.

🔹 Codice e tecnologie

  • HTML5: struttura semantica della pagina e dei contenuti.
  • CSS3: personalizzazione grafica, gestione layout responsive di base, slider.
  • JavaScript vanilla: logiche di calcolo, validazione input, dinamica slider, gestione lista oggetti.
  • Strutture dati: utilizzo di oggetti annidati in JavaScript per rappresentare le distanze tra i vari punti.

Il codice completo è stato inserito qua sotto, mentre la descrizione contiene sia gli screenshot del progetto sia gli scatti fotografici originali da me realizzati.

// Distanze Tempo Percorsi
var nodoPartenza;
var nodoDestinazione;
var nodoDistanza;

var nodoMinuti;
var nodoKilometri;
var nodoCalcola;
var nodoRisultato;
var nodoMessaggioCalcola;

var distanze = { 
    lagosantomodenese:  {
        montegiovo: 21,
        monterondinaio: 17,
        lagobaccio: 21,  
		lagosantomodenese: 0,
    },
    
    montegiovo:  {
        lagosantomodenese: 21,
        monterondinaio: 6,
        lagobaccio: 4, 
		montegiovo: 0,
    },

    monterondinaio: {
        lagobaccio: 5,
        lagosantomodenese: 17,
        montegiovo: 6,
	    monterondinaio: 0,
    },

    lagobaccio: {
        lagosantomodenese: 21,
        montegiovo: 4,
        monterondinaio: 5, 	
        lagobaccio: 0,		
    }
}

function gestoreLoad () {
    try {
        nodoPartenza = document.getElementById("whereFrom");
        nodoDestinazione = document.getElementById("whereTo");
        nodoDistanza = document.getElementById("distanza");
        nodoDistanza.value = ""; 

        var PartenzaCorrente = "";    
        var destinazioneCorrente = "";
        var distanzaCorrente = "";
   
        nodoPartenza.onchange = impostaViaggio;   
		nodoDestinazione.onchange = impostaViaggio;
		
		
		nodoMinuti = document.getElementById("minuti");
		nodoKilometri = document.getElementById("kilometri");
		nodoCalcola = document.getElementById("calcola");
		nodoRisultato = document.getElementById("risultato");
		nodoMessaggioCalcola = document.getElementById ("messaggioCalcola");
		nodoMinuti.value = "";
		nodoKilometri.value = "";
		nodoRisultato.value = "";
		nodoCalcola.onclick = gestoreCalcola;

        var nodoTesto = document.createTextNode ("");
        nodoMessaggioCalcola.appendChild (nodoTesto);
           
    }   catch   ( e )   {           
        alert("gestoreLoad " + e);
    }
}

window.onload = gestoreLoad;

function impostaViaggio () {
    try{        
        nodoDistanza.value = "";
        partenzaCorrente = nodoPartenza.value;
        destinazioneCorrente = nodoDestinazione.value;
        
		var i;
		
        if ((partenzaCorrente == "whereFrom") || (destinazioneCorrente == "whereTo")) {
            nodoDistanza.value = "0";         
        } else {
            distanzaCorrente = distanze[partenzaCorrente][destinazioneCorrente];
			 while ((i < distanze.length) && (distanze[i].distanza != distanzaCorrente)) {    
                i++;
            }
            nodoDistanza.value = distanzaCorrente;			
        }              

    }   catch   ( e )   {
        alert("impostaViaggio " + e);
    }
}

function gestoreCalcola () {
	try{
		scriviMessaggio(nodoMessaggioCalcola, "");
		
		if (nodoMinuti.value == "") {
			scriviMessaggio(nodoMessaggioCalcola, "Non hai inserito i minuti");
		return;
		}
		
		var minuti = Number(nodoMinuti.value);
		if (isNaN(minuti)) {
		scriviMessaggio(nodoMessaggioCalcola, nodoMinuti.value + " " + "non è un numero");
		return;
		}
		
		if (minuti <= 0) {
		scriviMessaggio(nodoMessaggioCalcola, "I minuti inseriti non sono validi");
		return;
		}

		if (nodoKilometri.value == "") {
		scriviMessaggio(nodoMessaggioCalcola, "Non hai inserito i km");
		return;
		}

		var kilometri = Number(nodoKilometri.value);
		if (isNaN(kilometri)) {
		scriviMessaggio(nodoMessaggioCalcola, nodoKilometri.value + " " + "non è un numero");
		return;
		}
		
		if (kilometri <= 0) {
		scriviMessaggio(nodoMessaggioCalcola, "I km inseriti non sono validi");
		return;
		}

		nodoRisultato.value = nodoMinuti.value * nodoKilometri.value;
	} catch ( e ) {
	  alert("gestoreCalcola " + e);
	}
}

function scriviMessaggio (nodo, messaggio) {
	var nodoTesto = document.createTextNode(messaggio);
	nodo.replaceChild(nodoTesto, nodo.firstChild);
}
// slider
var slides;    
var dots; 
 
var slideIndex = 0;   
showSlides(slideIndex);  
      
function plusSlides(n) {                  
  showSlides(slideIndex += 1);
}

function minusSlides(n) {                                    
	showSlides (slideIndex -= 1);
}

function currentSlide(n) {                                    
  showSlides(slideIndex = n);
}

function showSlides(n) {                                  
  var i;    
  var slides = document.getElementsByClassName("mySlides");    
  var dots = document.getElementsByClassName("dot");     
  
  if (n >= slides.length) {slideIndex = 0} 
  if (n < 0) {slideIndex = slides.length -1}
  
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";   
  }
  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" active", "");  
  }
 
  slides[slideIndex].style.display = "block"; 
  dots[slideIndex].className += " active"; 
}
// oggetti valigia

function newElement() {
	var li = document.createElement("li");  
    var inputValue = document.getElementById("myInput").value;
    var t = document.createTextNode(inputValue);
    li.appendChild(t);
	
	nodoMessaggioValigia = document.getElementById ("messaggioValigia");
	var nodoTesto = document.createTextNode ("");
        nodoMessaggioValigia.appendChild (nodoTesto);
		
	scriviMessaggio(nodoMessaggioValigia, "");
		
    if (inputValue == "") {
	  scriviMessaggio(nodoMessaggioValigia,"Inserire un oggetto!");
	  return;
      } else {
      document.getElementById("myUL").appendChild(li);
    }
	
	document.getElementById("myInput").value = "";
    var span = document.createElement("Span");
    var txt = document.createTextNode("u00D7"); 
    span.className = "close";
    span.appendChild(txt);
    li.appendChild(span);
	
	var close = document.getElementsByClassName("close");
    var i;
	for (i = 0; i < close.length; i++) {
		close[i].onclick = function() {
        var div = this.parentElement;
        div.style.display = "none";
        }
    }
}

function scriviMessaggio (nodo, messaggio) {
	var nodoTesto = document.createTextNode(messaggio);
	nodo.replaceChild(nodoTesto, nodo.firstChild);
}
/* stylesheet */
body {
	margin-left: 200px;
	margin-right: 200px;
}
/*--------------------------------------------------------*/
/* header */
h1 {
  color: black;
  text-align: center;
  padding: 20px;
  font-size: 65px;
  text-shadow: 4px 4px 8px;
  background-color: lightcyan;
  font-family: "Fantasy", "Papyrus";
  font-weight: bold;
  margin-top: 0;
}

/*top navigation bar */
.topnav {
  overflow: hidden;
  background-color: aliceblue;
  font-weight: bold;
}

/*topnav links */
.topnav a {
  display: block;
  color: black;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 18px;
  
}

/* Cambia colore on hover */
.topnav a:hover {
  background-color: lightcyan;
  color: black;
}
/*---------------------------------------------------------*/
/*slider*/
body {font-family: Verdana, sans-serif; text-align:center; background-color:lightblue;}
.mySlides {display:none;}

/* Next and previous buttons */
.prev, .next {
  padding: 16px;
  color: black;
  font-weight: bold;
  font-size: 25px;
  user-select: none;
  margin-left: 250px;
  margin-right: 250px;
  cursor: pointer;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, aggiungere un colore di sfondo con un po' di trasparenza*/
.prev:hover, .next:hover {
  background-color: rgba(0,0,0,0.8);
}

/* The dots/bullets/indicators */
.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: cornsilk;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;
}

.active,.dot:hover {
  background-color: royalblue;
}
/*---------------------------------------------------------*/
p{ 
	background-color:lightcyan;
	font-size:20px;
	color:black;
	box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
	text-align:center;
	padding: 40px;
}

h2 {
	background-color:lightcyan;
	font-size:25px;
	color:black;
	text-shadow: 2px 2px 4px;
	text-align:center;
	padding: 40px;
}
/*--------------------------------------------------------/
/*luggage box/

/* padding e bordi inclusi nel width and height */

#bagaglio {margin:20px; font-size: 18px; font-weight: bold;text-shadow: 2px 2px 4px;}
* {
  box-sizing: border-box;
  background-color:lightblue;
}
/* list items - controlla i valori di padding*/
ul li {
  list-style-type: none;
  background: aliceblue;
  font-size: 18px;
  padding:12px 8px 12px 40px;
  text-align: center;
}
/* header */
.header {
  background-color: lightblue;
  padding: 30px 40px;
  color: black;
  text-align: center;
}
/*lascia la riga libera dopo il header*/
.header:after {
  content: "";
  display: table;
  clear: both;
}
/* input - allinea obj */
input {
  margin: 0;
  border: none;
  border-radius: 0;
  width: 75%;
  padding: 10px;
  float: left;
  font-size: 16px;
  background-color:aliceblue;
}
/* "Add" button */
.addBtn {
  padding: 10px;
  width: 25%;
  background: lightgrey;
  color: black;
  float: left;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
  border-radius: 0;
}
.close {
	cursor: pointer;
}
#messaggioValigia {
	float: right;
	color: red;
}
/*--------------------------------------------------------*/
h3 {font-size:18px;}
#distanza   {
	border: 2px solid black;
	margin-right: 500px;
	margin-left: 500px;
	height: 30px;
    width: 12%;	
	text-align: center;
}
label {
	text-align: center;
}
select {background:aliceblue;}

/*--------------------------------------------------------*/
h4 {font-size:18px; }
#minuti {
	border: 2px solid black;
	margin-right: 500px;
	margin-left: 500px;
	height: 30px;
    width: 12%;
	text-align:center;
}

#kilometri {
	border: 2px solid black;
	margin-right: 500px;
	margin-left: 500px;
	height: 30px;
    width: 12%;
    text-align: center;
}
#risultato {
	border: 2px solid black;
	margin-right: 500px;
	margin-left: 500px;
	height: 30px;
    width: 12%;
	text-align:center;
}
#calcola {
  border: 3px solid blue;
  border-radius: 17px;
  padding: 8px;
  width: 12%;
  background: lightgrey;
  color: black;
  float: right;
  margin-right: 500px;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
}
#messaggioCalcola {
	float: right;
	color: red;
	margin-right: 200px;
}
/*---------------------------------------------------------*/
h5 {
	background-color:lightcyan;
	font-size:25px;
	color:black;
	text-shadow: 2px 2px 4px;
	text-align:center;
	padding: 40px;
}
h6 {
	background-color:lightcyan;
	font-size:25px;
	color:black;
	text-shadow: 2px 2px 4px;
	text-align:center;
	padding: 40px;
}

Testing e Analisi

Questa sezione raccoglie esercitazioni e analisi dedicate alla valutazione dell’usabilità e dell’accessibilità.
Attraverso casi di studio e verifiche pratiche, sono stati applicati metodi di visual design, test di responsive design, analisi euristiche e strumenti per la valutazione automatica.
L’obiettivo è mostrare come progettare interfacce efficaci e inclusive, migliorando la user experience e garantendo conformità agli standard di usabilità e accessibilità.

Festival Design

Il sito progettato per il Festival “démadé – Liberi Libri” di Livorno è di proprietà dell’agenzia Oimmei Digital di Livorno.

Ho curato la progettazione dei prototipi ad alta fedeltà in Figma e l’avvio dell’implementazione su WordPress, con attenzione alla chiarezza informativa, all’accessibilità e all’interazione del pubblico.

Il Processo

Design & Analisi

Fase Uno: Ricerca e Pianificazione

Analisi del contesto, definizione utenti e raccolta requisiti.

Fase Due: Prototipazione e Test

Creazione di prototipi interattivi e test di usabilità con strumenti dedicati.

Fase Tre: Validazione e Iterazione

Applicazione di metriche (SUS, questionari) e revisione per migliorare il design.