Bentornati alla nostra città in costruzione. Abbiamo buttato giù la pianta e ora è il momento di tirare su degli edifici.
Hai perso la prima parte o la seconda? We got you covered.
Assembliamo la città
A questo punto siamo in grado di assemblare il diorama partendo dalla struttura di blocchi contenitori.
Per avere un’idea più chiara riguardo a spaziature e posizionamenti, rimuoviamo la regola css che attua la trasformazione 3d su #base_platform:
Il div con classe “block” non ha attualmente dimensioni definite: sapendo che ogni edificio occupa uno spazio di 60px per lato (50px + 5px di margine per lato) possiamo impostare le misure usando multipli di questo valore.
Nel caso del primo contenitore, optiamo per una griglia di 4 edifici su due righe:
1 2 3 4 5 6 7 8 9 10 11 12 13 | .block { position: absolute; top: 0; left: 0; width: 240px; height: 120px; } |
Completiamo il riempimento inserendo altri edifici nel nostro file html, e creando un nuovo contenitore con classe “block” a cui assegnamo una classe aggiuntiva “b2” che useremo per sovrascrivere le coordinate di posizionamento:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | <div class="block"> <div class="building medium bisque"></div> <div class="building tall palegoldenrod"></div> <div class="building medium"></div> <div class="building"></div> <div class="building"></div> <div class="building medium bisque"></div> <div class="building"></div> <div class="building palegoldenrod"></div> </div> <div class="block b2"> <div class="building medium bisque"></div> <div class="building tall palegoldenrod"></div> <div class="building medium"></div> <div class="building"></div> <div class="building"></div> <div class="building medium bisque"></div> <div class="building"></div> <div class="building medium palegoldenrod"></div> <div class="building"></div> <div class="building"></div> <div class="building medium"></div> <div class="building palegoldenrod"></div> <div class="building tall"></div> <div class="building bisque"></div> <div class="building medium"></div> <div class="building medium"></div> <div class="building"></div> <div class="building medium bisque"></div> <div class="building "></div> <div class="building bisque"></div> </div> <div class="block b3"> <div class="building medium palegoldenrod"></div> <div class="building large bisque"></div> <div class="building"></div> <div class="building bisque"></div> <div class="building"></div> </div> |
Nel file scss:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | .block { position: absolute; top: 0; left: 0; width: 240px; height: 120px; } .b2 { top: 180px; height: 300px; } |
Il secondo blocco viene spostato di 180px , ovvero la misura dell’altezza del blocco precedente più 60px di spazio vuoto che useremo per le strade della città. Viene anche sovrascritta la sua altezza, per creare una griglia di 5 x 4 edifici.
Utilizzando lo stesso sistema possiamo creare altri tre isolati e assemblare l’intero diorama.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | .block { position: absolute; top: 0; left: 0; width: 240px; height: 120px; } .b2 { top: 180px; height: 300px; } .b3 { left: 300px; width: 180px; height: 120px; } .b4 { top: 180px; left: 300px; width: 180px; height: 180px; } .b5 { top: 420px; left: 300px; width: 180px; height: 60px; } |
A questo punto dobbiamo creare le strade per riempire gli spazi vuoti nella mappa. Definiamo un nuovo div nel nostro html e assegnamo la classe “road”, che si occuperà della colorazione e spaziatura, e un div innestato con classe “traffic_line” per usare un bordo tratteggiato come segnaletica orizzontale :
1 2 3 4 5 6 7 8 9 10 11 |
E procediamo con la stilizzazione:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | .road { position: absolute; background: gray; height: 30px; width: $platform_side; margin: 15px 0 15px 0px; z-index: -1; .traffic_line { border: 2px dashed white; top: 40%; position: relative; width: 98%; } } |
Impostiamo “position: absolute” per lo stesso principio considerato nel posizionare gli isolati, aggiungiamo un background grigio, l’altezza a 30px e la larghezza uguale a quella della piattaforma, un margine di 15px per i lati superiore e inferiore, e lo z-index a -1 per far si che la strada sia sempre coperta dagli edifici.
Per ogni strada aggiuntiva dovremo creare un nuovo div con classe “road”, e appendere la classi di modifica relative.
1 2 3 4 5 6 7 8 9 |
Per la strada verticale avremo la classe “vertical” da appendere al div:
1 2 3 4 5 6 7 8 9 10 11 | .vertical { transform: rotate(90deg); transform-origin: 0% -50%; top: 0px; left: 300px; } |
Non facciamo altro che ruotare il div di 90 gradi, allineare l’origine della trasformazione, e impostare top e left per il posizionamento.
Mentre le due orizzontali richiederanno una differenziazione:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | .horizontal_top { top: 120px; } .horizontal_bottom { top: 360px; width: $platform_side /2 -45px; right: 0; } |
In questo modo la strada posizionata in basso nel diorama occuperà metà dello spazio disponibile con un’ulteriore sottrazione di 45px per evitare l’overlap con altri elementi e verrà ancorata a destra.
A questo punto la situazione dovrebbe essere qualcosa di simile a questo:
Il diorama isometrico è completo, e possiamo procedere con la stilizzazione degli edifici speciali. Ne scegliamo tre, e per ognuno mostreremo un’icona png sulla facciata, cambiando la colorazione in hover del palazzo per allinearsi con il colore dell’icona.
Ho scelto tre icone dall’ottimo set “Colorful Flat Summer” (https://www.smashingmagazine.com/2014/05/summer-essentials-icon-set-freebie-eps-png-ai/) disegnato da Elena Genova per Smashing Magazine:
Una volta scaricato il set, copiamo le icone dentro la root del progetto e stilizziamo il primo palazzo, creando la classe “phone_icon”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | .phone_icon { &:hover { cursor: pointer; background-color: #f5bb3d !important; &:after, &:before { background-color: #f5bb3d !important; } } &:before { background-image: url(/phone.png); background-size: 80%; background-repeat: no-repeat; background-position: center; transform: rotateX(90deg) translateX(0) scaleY(-1) translateY(0px) translateZ(-50px); } } |
Niente di trascendentale: definiamo il colore del background all’hover copiandolo dall’icona tramite il color picker e impostiamo lo stesso per :after e :before; il blocco seguente setta l’icona scelta come background, con le relative opzioni: centrato, largo il 20%, senza ripetizioni. Unica accortezza: ripetiamo la trasformazione 3d del :before aggiungendo scaleY(-1) che “capovolgerà a specchio” l’elemento mostrando correttamente l’icona.
Il codice sass per le altre icone è il medesimo, con gli ovvi aggiustamenti di path, colore del background e parametri di trasformazione (è sempre necessario sovrascrivere interamente una trasformazione con più metodi, altrimenti verrà applicato l’ultimo dichiarato: “transform: scaleY(-1)” avrebbe sovrascritto la trasformazione iniziale).
Aggiungiamo quindi queste nuove classi agli edifici che vogliamo marcare come interattivi:
A questo punto, volendo utilizzare il diorama come interfaccia, è necessario renderlo più “parlante”, effetto che otterremo inserendo dei popup animati che verranno mostrati all’hover sugli edifici interattivi.
1 2 3 |
L’elemento “popup_container” servirà a creare uno spazio definito in cui animare il popup.
Aggiungiamo al file scss:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @keyframes wave { 50% { transform: translateY(2em); } } .popup_container { position: absolute; transform: rotate(-45deg) translateX(-50px) translateY(-120px); } .popup { width: 100px; height: 100px; background-color: rgb(214, 220, 226); position: absolute; border: 3px solid #68a9e8; border-radius: 5px; animation: wave 3s 1s ease-in-out infinite; box-shadow: inset 0 0 0 0.25em white; visibility: hidden; } |
Cominciamo creando l’animazione “wave” tramite la regola “keyframes”. E’ un loop che sposta il div sull’asse Y.
Poi impostiamo il container in posizionamento assoluto, adattando i parametri della trasformazione 3d.
In seguito stilizziamo graficamente il popup, e aggiungiamo l’animazione che abbiamo creato in precedenza.
Modifichiamo la classe “buildings” di default:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | .building { @include building(50px, 50px, 50px); &:hover { .popup { visibility: visible; } } } |
Per rendere visibile il popup all’hover.
E aggiungiamo la stilizzazione del popup nelle regole che definiscono i nostri palazzi speciali:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | .phone_icon { &:hover { cursor: pointer; background-color: #f5bb3d !important; &:after, &:before { background-color: #f5bb3d !important; } } &:before { background-image: url(/phone.png); background-size: 80%; background-repeat: no-repeat; background-position: center; transform: rotateX(90deg) translateX(0) scaleY(-1) translateY(0px) translateZ(-50px); } .popup { background-image: url(/phone.png); background-repeat: no-repeat; background-position: center; background-color: #f5bb3d !important; border: 3px solid #f5bb3d; } } |
Ripetendola per ogni regola e cambiando ovviamente i colori.
In caso di necessità, possiamo sovrascrivere lo stile del popup e il posizionamento della maschera a seconda della tipologia di edificio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | .large { @include building(110px, 50px, 200px); .popup_container { transform: rotate(-45deg) translateX(-80px) translateY(-220px); } .popup { width: 200px; height: 200px; } } |