Kiedy Trinity wypowiadała słowa o białym króliku, nie miała chyba świadomości, że jest możliwe śledzenie kursora myszy w czystym CSS. No cóż, film nie jest nowy i bracia, a raczej siostry Wachowskie nie przewidywały scenariusza, w którym wyjście z Matrixa będzie możliwe bez użycia JavaScript. Gdyby wiedziały o czym będzie dzisiejszy wpis, kolejna część nazywała by się pewnie "Matrix - Revelations".
Własny matrix.
Pierwszym działaniem w celu wydostania się ze złudnej rzeczywistości, będzie utworzenie własnej siatki, która pokryje całą naszą stronę. Siatkę będą stanowić elementy ułożone kolejno kolumnami i wierszami. Gęstość siatki, czyli ilość wierszy i kolumn będzie wpływała na precyzję śledzenia kursora. Im gęściej tym dokładniej, ale nie przesadzajmy. Dla naszego eksperymentu utworzymy siatkę 5x5 niezależnie od rozdzielczości, czyli ta będzie działać lepiej na mniejszych rozdzielczościach (bo gęściej się upakuje).
html,
body {
height: 100%;
margin: 0;
}
/* kontener na pełną wysokość */
#container {
height: 100%;
}
/* elementy po 20%
szerokości i wysokości,
czyli siatka 5x5
*/
#container div {
width: 20%;
height: 20%;
float: left;
/* a to tylko po to,
aby wyświetlić
tekst w środku
*/
display: flex;
align-items: center;
justify-content: center;
}
+
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
<div>25</div>
</div>
Generał Sibling i załogant Hover.
Mając siatkę elementów wykorzystamy pseudoklasę :hover oraz selektor ~ (general sibling). Musimy jeszcze dodać do wnętrza #container jakiś element, który będzie podążał za myszą. Zasada działania jest prosta: w zależności od tego, nad którym elementem siatki jest kursor myszy, tam ustawiamy nasz obiekt. Reguła CSS będzie wyglądać tak: pole_siatki_o_numerze_x:hover~span. Obiekt będziemy pozycjonować za pomocą właściwości left oraz top. Jeśli więc kursor jest nad pierwszym polem siatki, to obiekt ustawiamy na: left:10% oraz top:10% (skoro wymiary pola 20%x20%, to jego środek jest właśnie w 10%,10%). Jeśli nad ostatnim, to: left:90% oraz top:90%. Żeby przy poruszaniu myszy obiekt nie wyglądał jak pionek skaczący po planszy szachownicy, dodamy mu właściwość transition, dzięki temu będzie płynnie przemieszczał się od komórki do komórki.
Do poprzedniego CSS dodajemy:
#container span {
position: absolute;
left: 0;
top: 0;
transform: translate(-50%, -50%);
background: #f00;
width: 20px;
height: 20px;
transition: all 0.5s ease;
/*tą właściwość dodajemy,
aby obiekt nie odbierał
zdarzeń od myszy kiedy na niego
najedziemy (a odbierał je element
siatki)
*/
pointer-events: none;
}
/* ustalamy left dla obiektu
względem kolumn
*/
#container div:nth-of-type(1):hover~span,
#container div:nth-of-type(6):hover~span,
#container div:nth-of-type(11):hover~span,
#container div:nth-of-type(16):hover~span,
#container div:nth-of-type(21):hover~span {
left: 10%;
}
#container div:nth-of-type(2):hover~span,
#container div:nth-of-type(7):hover~span,
#container div:nth-of-type(12):hover~span,
#container div:nth-of-type(17):hover~span,
#container div:nth-of-type(22):hover~span {
left: 30%;
}
#container div:nth-of-type(3):hover~span,
#container div:nth-of-type(8):hover~span,
#container div:nth-of-type(13):hover~span,
#container div:nth-of-type(18):hover~span,
#container div:nth-of-type(23):hover~span {
left: 50%;
}
#container div:nth-of-type(4):hover~span,
#container div:nth-of-type(9):hover~span,
#container div:nth-of-type(14):hover~span,
#container div:nth-of-type(19):hover~span,
#container div:nth-of-type(24):hover~span {
left: 70%;
}
#container div:nth-of-type(5):hover~span,
#container div:nth-of-type(10):hover~span,
#container div:nth-of-type(15):hover~span,
#container div:nth-of-type(20):hover~span,
#container div:nth-of-type(25):hover~span {
left: 90%;
}
/* a tu ustalamy top dla obiektu
względem wierszy
*/
#container div:nth-of-type(1):hover~span,
#container div:nth-of-type(2):hover~span,
#container div:nth-of-type(3):hover~span,
#container div:nth-of-type(4):hover~span,
#container div:nth-of-type(5):hover~span {
top: 10%;
}
#container div:nth-of-type(6):hover~span,
#container div:nth-of-type(7):hover~span,
#container div:nth-of-type(8):hover~span,
#container div:nth-of-type(9):hover~span,
#container div:nth-of-type(10):hover~span {
top: 30%;
}
#container div:nth-of-type(11):hover~span,
#container div:nth-of-type(12):hover~span,
#container div:nth-of-type(13):hover~span,
#container div:nth-of-type(14):hover~span,
#container div:nth-of-type(15):hover~span {
top: 50%;
}
#container div:nth-of-type(16):hover~span,
#container div:nth-of-type(17):hover~span,
#container div:nth-of-type(18):hover~span,
#container div:nth-of-type(19):hover~span,
#container div:nth-of-type(20):hover~span {
top: 70%;
}
#container div:nth-of-type(21):hover~span,
#container div:nth-of-type(22):hover~span,
#container div:nth-of-type(23):hover~span,
#container div:nth-of-type(24):hover~span,
#container div:nth-of-type(25):hover~span {
top: 90%;
}
Pamiętaj o dodaniu SPAN do #container.
Neo, nie zasypiaj!
Nic nie stoi na przeszkodzie, aby sztuczkę wykorzystać w inny sposób. Nie musimy przecież przesuwać obiektu do środka komórki siatki, ale możemy delikatnie modyfikować jego położenie, a uzyskany efekt bardziej przypominał śledzenie. Trafiłeś kiedyś na skrypt w JS, gdzie oczy postaci z kreskówki śledziły kursor? Po co nam JS!
Do przeczytania w kolejnej części zmagań z rzeczywistością!
Przydatne linki:
Obrazek, z którego twarz została przerysowana do CSS.