1. Efekty reagujące na najechanie kursorem
1.1. Efekt „rozbijanego” tekstu
Efekt: nagłówek „rozsypuje się” przy najechaniu — powiększa się i lekko obraca, mocniej przyciągając uwagę użytkownika.
Cel: zrozumieć, jak użyć transformacji CSS i stanu :hover do budowy animowanych nagłówków / logotypów.
- Utwórz element HTML (np.
<p>lub<h2>) z klasąbreak-texti własnym tekstem. - W CSS ustaw dla
.break-texttransition: transform 0.5s ease-in-out;, aby animacja była płynna. - Dla
.break-text:hoverzastosujtransform: scale(1.5) rotate(15deg);, czyli powiększenie + obrót. - Poeksperymentuj z innymi wartościami
scale()irotate(), zachowując czytelność napisu.
Rozbij tekst przy najechaniu!
1.2. Falujący przycisk
Efekt: przycisk powiększa się, rozświetla i zmienia cień przy najechaniu, a po kliknięciu zmienia tekst. Cel: zaprojektować przycisk CTA, który reaguje na użytkownika i zachęca do interakcji.
- Dodaj przycisk
<button class="wave-button">Kliknij mnie!</button>. - W CSS ustaw gradientowe tło, zaokrąglone rogi i cień dla przycisku.
- Dla
.wave-button:hoverzastosuj lekkie powiększenie i jaśniejszy wygląd, aby zasymulować „podświetlenie”. - W JS dodaj obsługę
click, która zmienia tekst na np. „Dziękuję za kliknięcie!”.
1.3. Rozbłysk na obrazku
Efekt: miniatura grafiki przy najechaniu jaśnieje i lekko się rozmywa, co tworzy wrażenie rozbłysku. Cel: przećwiczyć użycie filtrów CSS do budowy efektów „preview” w galeriach i portfolio.
- Umieść obrazek z klasą
image-glow(np. miniaturę z ćwiczeń GIMP). - W CSS nadaj
.image-glowtransition: filter 0.3s ease;dla płynnej zmiany. - Dla
.image-glow:hoverużyjfilter: brightness(1.5) blur(2px);— zwiększa jasność i dodaje rozmycie. - Dostosuj parametry
brightness()iblur()do konkretnej grafiki, aby efekt nie był przesadzony.
2. Efekty 3D i ruch po ekranie
2.1. Obracająca się karta 3D
Efekt: karta obraca się w osi Y i pokazuje tylną stronę (front/back), jak fizyczna karta w dłoni. Cel: nauczyć się użycia perspektywy 3D, obrotów oraz ukrywania tylnej strony elementu.
- Stwórz strukturę:
<div class="card"> <div class="card-inner"> <div class="card-front">Przód</div> <div class="card-back">Tył</div> </div> </div> - Na
.cardustawperspective: 1000px;, a na.card-innertransform-style: preserve-3d;itransition: transform 0.5s;. - Dla
.card-fronti.card-backużyjbackface-visibility: hidden;, a.card-backobróć orotateY(180deg). - W CSS obróć
.card-innerorotateY(180deg)w stanie.card:hover, aby zobaczyć tył karty.
2.2. Tekst przesuwający się przez ekran
Efekt: tekst wjeżdża z lewej i wyjeżdża po prawej stronie ekranu, powtarzając się w pętli — jak pasek informacyjny.
Cel: przećwiczyć tworzenie animacji klatkowej @keyframes i jej zastosowanie do elementu.
- W HTML dodaj:
<div class="moving-text"> <span>Ten tekst leci!</span> </div> - Ustaw
.moving-textjako kontener zoverflow: hidden;i pozycją względną. - W CSS nadaj
spanpozycję absolutną i animacjęmove 5s infinite linear. - W
@keyframes moveprzesuńleftod-100%do100%, aby tekst przeleciał przez ekran. - Zmieniając czas trwania (np. 3 s, 10 s), sprawdź wpływ na czytelność komunikatu.
3. Efekty z użyciem JavaScript
3.1. Przyciągający się przycisk („magnes”)
Efekt: przycisk przesuwa się w stronę kursora, tworząc wrażenie przyciągania lub „uciekania” przed użytkownikiem. Cel: poznać odczytywanie pozycji myszy i dynamiczne ustawianie stylów za pomocą JavaScript.
- Dodaj:
<div class="magnetic-wrapper"> <button class="magnetic-button">Kliknij mnie!</button> </div> - W CSS ustaw
.magnetic-buttonjakoposition: absolute;wewnątrz wrappera. - W JS nasłuchuj
mousemovena.magnetic-wrapperi pobierz pozycję kursora względem wrappera. - Przesuwaj przycisk za pomocą
transform: translate(), dzieląc odległość (np. przez 4), aby ruch był delikatny. - Przetestuj zachowanie przy szybkim i wolnym ruchu myszy.
3.2. Tło reagujące na przewijanie
Efekt: im dalej przewiniesz stronę, tym jaśniejsze staje się tło pod treścią. Cel: zrozumieć, jak wykorzystać pozycję przewijania do sterowania wyglądem strony w czasie rzeczywistym.
- Upewnij się, że w dokumencie jest
<div class="scroll-background"></div>za treścią (position: fixed; z-index: -1;). - W JS dodaj nasłuch
scrollnawindowi pobierzwindow.scrollY. - Przeskaluj wartość przewinięcia do zakresu np. 0–120:
const value = Math.min(scrollY / 5, 120);. - Ustaw
backgroundColortła nargb(value, value, value), aby uzyskać efekt rozjaśniania. - Sprawdź, jak wygląda efekt na krótkiej i bardzo długiej stronie.
3.3. Pulsujące tło i rozszerzające się okno
Efekt: tło delikatnie pulsuje, a kwadratowe okno po kliknięciu powiększa się i zmienia kolor oraz tekst. Cel: połączyć animację CSS wykonywaną w pętli z reakcją na zdarzenie kliknięcia sterowaną przez JS.
- Warstwa
.pulse-backgroundma zdefiniowaną animację@keyframes pulse-bg— zmiana koloru w pętli. - Stwórz
<div class="expand-box">Kliknij mnie!</div>jako element interaktywny. - W CSS ustaw początkową szerokość, wysokość, kolor tła i
transitiondla wymiarów i koloru. - W JS trzymaj stan w zmiennej
expandedi w obsłudzeclickprzełączaj style (mały/duży) oraz tekst wewnątrz. - Dodaj własne modyfikacje: zaokrąglenie, cień, zmianę koloru tekstu przy rozmiarze powiększonym.
3.4. Licznik interakcji na stronie
Efekt: w ramce wyświetla się licznik, który rośnie za każdym razem, gdy użytkownik kliknie któryś z interaktywnych elementów. Cel: pokazać, jak przechowywać i aktualizować stan aplikacji w JS (zmienna + aktualizacja DOM).
- Dodaj
<div id="clickCounter" class="counter-badge">Kliknięcia: 0</div>w miejscu widocznym dla użytkownika. - W JS zbierz wybrane elementy (przyciski, karta, box) za pomocą
querySelectorAll. - Podłącz do nich obsługę zdarzenia
clicki po każdym kliknięciu zwiększ wartość licznika. - Zaktualizuj tekst wewnątrz
clickCounter, aby pokazać aktualną liczbę kliknięć. - Rozszerzenie: zapisz wartość w
localStorage, aby nie resetowała się po odświeżeniu strony.
4. Kod JavaScript użyty na tej stronie
Poniżej znajduje się kompletny skrypt obsługujący wszystkie efekty dynamiczne. Zadanie dla klasy: podziel ten kod na moduły (osobne funkcje) lub dopisz własny efekt korzystający z tych samych technik.
<script>
document.addEventListener("DOMContentLoaded", () => {
// 1. Rok w stopce
const yearSpan = document.getElementById("year");
if (yearSpan) {
yearSpan.textContent = new Date().getFullYear();
}
// 2. Pokaż / ukryj kod
const btn = document.getElementById("toggleCode");
const block = document.getElementById("codeBlock");
const icon = document.getElementById("codeIcon");
const label = document.getElementById("codeLabel");
if (btn && block && icon && label) {
btn.addEventListener("click", () => {
const visible = block.style.display === "block";
block.style.display = visible ? "none" : "block";
icon.textContent = visible ? "▾" : "▴";
label.textContent = visible
? "Pokaż / ukryj kod JavaScript"
: "Ukryj kod JavaScript";
});
}
// 3. Efekt rozbicia tekstu
document.querySelectorAll('.break-text').forEach(element => {
element.addEventListener('mouseenter', () => {
element.style.transform = 'scale(1.5) rotate(15deg)';
});
element.addEventListener('mouseleave', () => {
element.style.transform = 'scale(1) rotate(0deg)';
});
});
// 4. Falujący przycisk — zmiana napisu po kliknięciu
const waveButton = document.querySelector('.wave-button');
if (waveButton) {
waveButton.addEventListener('click', () => {
waveButton.textContent = 'Dziękuję za kliknięcie!';
});
}
// 5. Rozbłysk na obrazku
const imageGlow = document.querySelector('.image-glow');
if (imageGlow) {
imageGlow.addEventListener('mouseenter', () => {
imageGlow.style.filter = 'brightness(1.5) blur(2px)';
});
imageGlow.addEventListener('mouseleave', () => {
imageGlow.style.filter = 'brightness(1) blur(0)';
});
}
// 6. Efekt „magnesu” — przycisk delikatnie podąża za kursorem
const magneticWrapper = document.querySelector('.magnetic-wrapper');
const magneticButton = document.querySelector('.magnetic-button');
if (magneticWrapper && magneticButton) {
magneticWrapper.addEventListener('mousemove', (e) => {
const rect = magneticWrapper.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
magneticButton.style.transform = `translate(${x / 4}px, ${y / 4}px)`;
});
}
// 7. Tło reagujące na przewijanie
const scrollBg = document.querySelector('.scroll-background');
if (scrollBg) {
window.addEventListener('scroll', () => {
const scroll = window.scrollY || window.pageYOffset;
const value = Math.min(scroll / 5, 120);
scrollBg.style.backgroundColor = `rgb(${value}, ${value}, ${value})`;
});
}
// 8. Rozszerzające się okno przy kliknięciu
const expandBox = document.querySelector('.expand-box');
if (expandBox) {
let expanded = false;
expandBox.addEventListener('click', () => {
expanded = !expanded;
if (expanded) {
expandBox.style.width = '300px';
expandBox.style.height = '300px';
expandBox.style.backgroundColor = '#16a34a';
expandBox.textContent = 'Kliknij, aby zmniejszyć';
} else {
expandBox.style.width = '200px';
expandBox.style.height = '200px';
expandBox.style.backgroundColor = '#333';
expandBox.textContent = 'Kliknij mnie!';
}
});
}
// 9. Licznik interakcji
const counter = document.getElementById("clickCounter");
if (counter) {
let clicks = 0;
const clickable = document.querySelectorAll(
".wave-button, .magnetic-button, .expand-box, .card"
);
clickable.forEach(el => {
el.addEventListener("click", () => {
clicks++;
counter.textContent = "Kliknięcia: " + clicks;
});
});
}
});
</script>