Costruisci un diorama con CSS3 e HTML5, aiutato dal potere di SASS, NodeJS e Gulp (parte 3 di 3)

Tempo di lettura stimato:7 minuti

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;

}

&nbsp;

.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;

}

&nbsp;

.b2 {

top: 180px;

height: 300px;

}

&nbsp;

.b3 {

left: 300px;

width: 180px;

height: 120px;

}

&nbsp;

.b4 {

top: 180px;

left: 300px;

width: 180px;

height: 180px;

}

&nbsp;

.b5 {

top: 420px;

left: 300px;

width: 180px;

height: 60px;

}

&nbsp;

 

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
<div class="block b5">

<div class="building palegoldenrod"></div>

<div class="building medium"></div>

<div class="building bisque"></div>

</div>

<div class="road"><div class="traffic_line"></div></div>

 

 

 

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;

&nbsp;

.traffic_line {

border: 2px dashed white;

top: 40%;

position: relative;

width: 98%;

}

&nbsp;

}

 

 

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
 

<div class="road horizontal_top"><div class="traffic_line"></div>

<div class="road vertical"><div class="traffic_line"></div>

<div class="road horizontal_bottom"><div class="traffic_line"></div>

 

 

 

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
&nbsp;

.horizontal_top {

top: 120px;

}

&nbsp;

.horizontal_bottom {

top: 360px;

width: $platform_side /2 -45px;

right: 0;

}

&nbsp;

 

 

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 {

&amp;:hover {

cursor: pointer;

background-color: #f5bb3d !important;

&amp;:after, &amp;:before {

background-color: #f5bb3d !important;

}

}

&nbsp;

&amp;: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);

}

}

&nbsp;

 

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:

 

1
<div class="building large bisque mail_icon"></div>

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
<div class="building large bisque mail_icon"><div class="popup_container"><div class="popup"></div></div></div>

 

 

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
&nbsp;

@keyframes wave {

50% { transform: translateY(2em); }

}

&nbsp;

.popup_container {

position: absolute;

transform: rotate(-45deg) translateX(-50px) translateY(-120px);

}

&nbsp;

.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;

}

&nbsp;

 

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);

&nbsp;

&amp;:hover {

.popup {

visibility: visible;

}

}

}

&nbsp;

 

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 {

&amp;:hover {

cursor: pointer;

background-color: #f5bb3d !important;

&amp;:after, &amp;:before {

background-color: #f5bb3d !important;

}

}

&nbsp;

&amp;: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);

}

&nbsp;

.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);

&nbsp;

.popup_container {

transform: rotate(-45deg) translateX(-80px) translateY(-220px);

}

&nbsp;

.popup {

width: 200px;

height: 200px;

}

}

&nbsp;

&nbsp;