Efekty interaktywne — CSS + JavaScript

Zbiór efektów najechania, animacji i prostych interakcji do wykorzystania w stronach WWW, menu, banerach i mini‑grach.

Cel lekcji

Po co są efekty interaktywne?

Efekty hover, kliknięcia i animacje tła to tzw. mikrointerakcje — krótkie reakcje interfejsu na działania użytkownika. Informują, że coś się dzieje (np. przycisk został kliknięty), pomagają w nawigacji i poprawiają UX, jeśli są użyte z umiarem.

Poziom: 4 klasa technikum (TI)
Technologie: HTML, CSS3, JavaScript

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.

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.

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.

Obrazek z efektem rozbłysku

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.

Przód karty
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.

Ten tekst leci!

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.

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.

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.

Kliknij mnie!

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

Kliknięcia: 0

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>