Auto-sync enabled

FlatlyPage

Version 1.0.0 • 54 files • 724.77 KB
extensions/scroll_to_top/main.php
<?php
function scroll_to_top_frontend() {
    echo '
    <button id="scrollToTopBtn" aria-label="Scroll to top">
        <div class="btn-shine"></div>
        <svg class="progress-ring" viewBox="0 0 58 58">
            <circle class="progress-ring__circle" stroke="rgba(255,255,255,0.1)" stroke-width="2" fill="transparent" r="24" cx="29" cy="29"/>
            <circle id="scrollProgress" class="progress-ring__circle--active" stroke="white" stroke-width="2" fill="transparent" r="24" cx="29" cy="29"/>
        </svg>
        <div class="btn-icon">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
                <path class="arrow-path" d="m18 15-6-6-6 6"/>
            </svg>
        </div>
    </button>';

    echo '<style>
        #scrollToTopBtn {
            position: fixed;
            bottom: 30px;
            right: 30px;
            z-index: 9999;
            width: 58px;
            height: 58px;
            background: #000;
            color: #fff;
            border: 1px solid rgba(255, 255, 255, 0.15);
            border-radius: 18px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            opacity: 0;
            visibility: hidden;
            transform: translateY(30px) scale(0.7);
            transition: opacity 0.4s, visibility 0.4s, transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.3s;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            overflow: hidden;
            -webkit-tap-highlight-color: transparent;
        }

        /* Responsywność dla telefonów */
        @media (max-width: 768px) {
            #scrollToTopBtn {
                width: 46px;
                height: 46px;
                bottom: 20px;
                right: 20px;
                border-radius: 14px;
            }
            #scrollToTopBtn .btn-icon svg {
                width: 18px;
                height: 18px;
            }
        }

        .progress-ring {
            position: absolute;
            top: 0; left: 0;
            width: 100%;
            height: 100%;
            transform: rotate(-90deg);
            pointer-events: none;
        }

        .progress-ring__circle--active {
            stroke-dasharray: 150.8;
            stroke-dashoffset: 150.8;
            transition: stroke-dashoffset 0.1s linear;
        }

        .btn-shine {
            position: absolute;
            top: -50%; left: -50%;
            width: 200%; height: 200%;
            background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 60%);
            opacity: 0;
            transition: opacity 0.3s;
            pointer-events: none;
        }

        #scrollToTopBtn:hover .btn-shine {
            opacity: 1;
            animation: shineMove 1.5s infinite linear;
        }

        @keyframes shineMove {
            0% { transform: translate(-100%, -100%); }
            100% { transform: translate(50%, 50%); }
        }

        .btn-icon { z-index: 2; transition: transform 0.3s ease; }

        #scrollToTopBtn .arrow-path {
            stroke-dasharray: 20;
            stroke-dashoffset: 20;
            transition: stroke-dashoffset 0.5s ease 0.2s;
        }

        #scrollToTopBtn.show {
            opacity: 1;
            visibility: visible;
            transform: translateY(0) scale(1);
        }

        #scrollToTopBtn.show .arrow-path { stroke-dashoffset: 0; }

        #scrollToTopBtn:hover {
            background: #111;
            box-shadow: 0 15px 35px rgba(0,0,0,0.5);
        }

        #scrollToTopBtn:active { transform: scale(0.9) !important; }

        #scrollToTopBtn.at-footer {
            opacity: 0;
            transform: translateY(40px) scale(0.5);
            pointer-events: none;
        }
    </style>';

    echo '<script>
    document.addEventListener("DOMContentLoaded", function() {
        const btn = document.getElementById("scrollToTopBtn");
        const progressCircle = document.getElementById("scrollProgress");
        const footer = document.querySelector("footer");
        if (!btn || !progressCircle) return;

        const circumference = 2 * Math.PI * 24;

        const handleScroll = () => {
            const scrollY = window.scrollY;
            const windowHeight = window.innerHeight;
            
            let maxScroll;
            if (footer) {
                maxScroll = (footer.offsetTop) - windowHeight + (window.innerWidth <= 768 ? 20 : 30);
            } else {
                maxScroll = document.documentElement.scrollHeight - windowHeight;
            }

            let scrollPercent = scrollY / maxScroll;
            scrollPercent = Math.min(Math.max(scrollPercent, 0), 1);
            progressCircle.style.strokeDashoffset = circumference - (scrollPercent * circumference);

            if (scrollY > 200) {
                btn.classList.add("show");
            } else {
                btn.classList.remove("show");
            }

            if (footer) {
                const footerRect = footer.getBoundingClientRect();
                if (footerRect.top < windowHeight - 10) {
                    btn.classList.add("at-footer");
                } else {
                    btn.classList.remove("at-footer");
                }
            }
        };

        document.addEventListener("mousemove", (e) => {
            if (window.innerWidth <= 768 || !btn.classList.contains("show") || btn.classList.contains("at-footer")) return;
            const rect = btn.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;
            const distance = Math.hypot(e.clientX - centerX, e.clientY - centerY);

            if (distance < 100) {
                const x = (e.clientX - centerX) * 0.25;
                const y = (e.clientY - centerY) * 0.25;
                btn.style.transform = `translate(${x}px, ${y}px) scale(1.05)`;
            } else {
                btn.style.transform = "";
            }
        });

        window.addEventListener("scroll", handleScroll, { passive: true });
        window.addEventListener("resize", handleScroll);
        btn.addEventListener("click", () => {
            window.scrollTo({ top: 0, behavior: "smooth" });
        });
        
        handleScroll();
    });
    </script>';
}