WP plugin (1) – zachęta do zostawienia komentarza…

Zdarza się, że używając WordPressa (a także każdego innego narzędzia do budowy strony) dokonujemy czasem zmian, które nie są widoczne na pierwszy oka rzut (a chcielibyśmy powiadomić o nich użytkowników). W moim przypadku było tak z uruchomieniem na jednej ze stron systemu komentarzy Disqus, Facebook, Google+ -obok istniejącego WordPress’owego.

Pomyślałem, że dobrym sposobem będzie wykonanie okienka informującego o tym.

No i nie chodziło mi o

alert("Patrzcie wszyscy!");

Opiszę budowę pluginu do WordPressa, wraz ze stroną ustawień.

Zapraszam do lektury.

Zabawę zacząłem od Netbeans i utworzenia projekty HTML+CSS+JS, który następnie przeniosłem do WP.

Idea była taka, aby oprócz okienka z treścią słowno obrazkową pokazały się również ikonki mediów społecznościowych, …no aby nie były całkiem statyczne – raczej figlarne, aby okienko nie utrudniało zbytnio życia (czyli pokazało się raz danemu użytkownikowi, wzbudzając raczej niedopowiedzenie i ciekawość niż przesyt).

Zobaczcie tutaj, czyste HTML+CSS+JS (no dobra, trochę jQuery też).

fragmenty:

        <!-- ======================== WikS.eu -Plum ===================================== -->
        <div id="wikseu_plum" style="display: none;"> <!-- div-outer, który zniszczymy po wszystkim -->
            <div id="wikseu_plum_outer">  <!-- div, który pomoże w wyśrodkowaniu -->
                <div id="wikseu_plum_middle">  <!-- div, który pomoże w wyśrodkowaniu -->
                    <div id="wikseu_plum_inner">  <!-- div, który pomoże w wyśrodkowaniu -->
                        <div id="wikseu_plum_popup"> <!-- div po którym biegają ikonki -->
                            <table id="wikseu_plum_table"> 
                                <tr>
                                    <td style="width: 75px;">
                                        <img src="img/lupa_wiatrak_onl4.gif">
                                    </td>
                                    <td id="wikseu_plum_td">
                                        <h4>Hey, miło Cię widzieć !<br>Pozwól -zabiorę chwilkę i tylko raz</h4>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="2">
                        <button id="wikseu_plum_close" style="display: none;">ok</button>
                                    </td>
                                </tr>
                            </table>
                        </div> <!-- div po którym biegają ikonki -->
                        <!-- socjal ikonki -->
                        <img class="wikseu_plum_icon" src="img/discus36.png">
                        <img class="wikseu_plum_icon" src="img/faceb36.png">
                        <img class="wikseu_plum_icon" src="img/goog36.png">
                        <!-- <img class="wikseu_plum_icon" src="img/twi36.png"> -->
                        <img class="wikseu_plum_icon" src="img/wp36.png">
                    </div> <!-- div, który pomoże w wyśrodkowaniu -->
                </div> <!-- div, który pomoże w wyśrodkowaniu -->
            </div> <!-- div, który pomoże w wyśrodkowaniu -->
        </div> <!-- div, który zniszczymy po wszystkim -->
        <script src="js/wikseu_plum.js"></script> 
        <!-- ======================== WikS.eu -Plum ===================================== -->

czyli kolka DIV do wyśrodkowania wszystkiego w pionie i poziomie, a także do zniszczenia po wszystkim, w środku prosta tabelka z obrazkiem GIF (dzięki czemu może być ruchomy – w tym przypadku wiatrak), treść, przycisk OK i ikony socjal-mediów.

tutaj można zobaczyć jak to wygląda bez CSS i JavaScript

.. CSS: – głównie wyrównanie i kolory
i JavaScript…
…która musi wszystko zdynamizować, a mianowicie poruszyć ikony tak jak sobie to wyobraziłem. Wędrują z krawędzi ekranu, później w okolicy okienka są aktywne, na koniec toczą się jak kule bilardowe a po chwili wypadają na boki poddając się grawitacji.
No i jeszcze trzeba zapamiętać w ciasteczku cookie, że już się prezentowaliśmy…

JavaScript będzie w kawałkach:

// gdy załaduje się strona:
$(document).ready(function(){
    // pobierz Cookie -gdy jest:
    var plum_comment = getCookie("plum_comment");
    // sprawdź, czy pobrano lub czy to tryb developerski:
    if ( !plum_comment || dev_mode === true ) {
        // pokaż DIVa -plum
        var div = document.getElementById('wikseu_plum');
        div.style.display = 'table';

…czyli startujemy po załadowaniu dokumentu, pobieramy Cookie aby wiedzieć czy już się prezentowaliśmy, jeśli nie lub jeśli jest to tryb dev to startujemy z okienkiem – do tej pory było ukryte, teraz je pokazujemy..

// ustal położenie startowe ikonek
icon_l = document.getElementsByClassName("wikseu_plum_icon");
for (var icon_index = 0; icon_index < icon_l.length; icon_index++) {
    icons[icon_index] = [
        icon_l[icon_index], 
        - oico_warea/2, // top
        (icon_l.length - 1 - icon_index) * oico_warea, // left
        0  // angle-rotate
    ];
    // id="plum0"
    icons[icon_index][0].id = 'plum' + icon_index;
    icons[icon_index][0].style.top = icons[icon_index][1] + 'px';
    icons[icon_index][0].style.left = icons[icon_index][2] + 'px';
}        
// pobierz rozmiary diva:
var div_ramka_el = document.getElementById("wikseu_plum_popup");
div_ramka = [
    div_ramka_el,
    parseInt(div_ramka_el.offsetTop),
    parseInt(div_ramka_el.offsetLeft),
    parseInt(div_ramka_el.offsetTop + div_ramka_el.offsetHeight),
    parseInt(div_ramka_el.offsetLeft + div_ramka_el.offsetWidth)
];

… ustalamy położenie ikonek socjal-mediów na krawędzi zewnętrznego DIV, budujemy tablicę z obiektów ikon i ich parametrów -dzięki czemu łatwiej będzie nam wykonywać obliczenia na współrzędnych ich położenia,
pobieramy także rozmiary i położenie okienka na komputerze użytkownika, aby wiedzieć gdzie ikonki mają się poruszać.

// ukaż treść wnętrza diva:
$("#wikseu_plum_popup").fadeIn(1000);
$(".wikseu_plum_icon").each(function(index) {
    $(this).delay(400*index).fadeIn(1000);
}).each(function(index) {
    icons[index][1] = div_ramka[1] + 1; // Top
    $(this).animate({
        top: icons[index][1] + 'px',
        speed: 'slow'
    },
    function() {
        parolle(index);
    });
});
reload_popup_content();

…ukazujemy treść, kolejno ikonki z odstępem 0,4sekundy, uruchamiamy procesy toczenia się w kierunku górnej krawędzi okienka (parolle) oraz przeładowania treści tekstowej okna (reload_popup_content)
Przy odczycie i zapisie cookie używałem funkcji opisanych tutaj: https://www.w3schools.com/js/js_cookies.asp

Proces ikonkowy „parolle(index)”:

** start obrotu ikonkami
 * 
 * @param {type} index
 * @returns {undefined}
 */
function parolle(index) {
    
    var step = 1 + 0.5 * index;
    mid_arolle(index, step);
}

/** środek funkcji obrotu ikonkami
 * 
 * @param {type} index
 * @param {type} step
 * @param {type} angle
 * @returns {undefined}
 */
function mid_arolle(index, step=0, angle=0) {

    icons[index][3] = angle; // zapisz kąt i ustaw:
    icons[index][0].style.webkitTransform = "rotate(" + icons[index][3] + "deg)";
    // zapisz położenie-left i ustaw:
    // przed prawą krawędzią ramki:
    icons[index][2] = div_ramka[4] - 360 + angle - (oico_warea * (1 + index));
    icons[index][0].style.left = icons[index][2] + 'px';
    // wykonaj kroczek obrotu:
    if (!break_actions) {
        if (angle < 360) {
            angle += step;
            setTimeout(function() {
                mid_arolle(index, step, angle);
            }, 2);        
        }else{
            shake(index, angle, time_shakesum_mslike, spadaj2);
        }
    }
}

to w istocie dwie funkcje – startująca proces (parolle) oraz kontynująca go (mid_arolle)
kontynuacja zaś to kolejne kroki przesunięcia ( style.left = ) oraz obrotu ( style.webkitTransform = „rotate(” )
I na koniec uruchomienie następnego procesu, nazwanego ‚shake’
W wyobrażeniu to tak: ikonki pojawiły się, przetoczyły na swoje miejsca (kolejność) po prawej stronie górnej krawędzi okienka i teraz shake – zaczną się trząść…

/** drgaj ikonami przez określony czas
 * 
 * @param {type} index
 * @param {type} angle
 * @param {type} timerest
 * @param {type} mfunk
 * @returns {undefined}
 */
function shake(index, angle, timerest, mfunk=null) {

    var deltatime_shake = 3; // szybkość drgań ikonek
    // drgnij:
    icons[index][0].style.top = (icons[index][1] - 1 + 2 * Math.random()) + 'px';
    icons[index][0].style.left = (icons[index][2] - 1 + 2 * Math.random()) + 'px';
    icons[index][0].style.webkitTransform = "rotate(" + (icons[index][3] 
            + 20 * Math.random() - 10) + "deg)";
    // ile zostało jeszcze szasu drgań:
    timerest = timerest - deltatime_shake;
    // ...i raz jeszcze:
    if (!break_actions) {
        if (timerest > 0) {
            setTimeout(function() {
                shake(index, angle, timerest, mfunk);
            }, deltatime_shake);
        }else{
            // odpal funkcję następną, gdy jest
            if(mfunk) {
                // spadanko na dolna krawedz
                mfunk(index);
            }
        }
    }
}

Drgania ikonek -losowo wzdłuż osi X i Y +/-1px oraz obrót wokół oso +/-10stopni. Całość przez określony czas, później wywołanie kolejnej funkcji – spadania na dolną krawędź

/** przemieszcza ikonki w dół
 * - spadają nad dolną krawędź diva
 * @param {type} index
 * @param {type} mfunk
 * @returns {undefined}
 */
function spadaj2(index, mfunk=null) {
    
    icons[index][1] = div_ramka[3] - 43;
    $(icons[index][0]).animate({
        top: icons[index][1] + 'px',
        speed: 'slow'
        }, function() {
            // odpal funkcję następną, gdy jest
            wolno_tocz_sie(index);
        }
    );
}

Po spadku, kolejna funkcja – wolno_tocz_sie(index). Funkcja ta powoduje przesuwanie i obracanie wokół osi ikonek, sprawiając wrażenie toczenia się po dolnej krawędzi okienka, od lewej do prawej strony -z odbijaniem, przy losowo ustalonej prędkości dla każdej z ikon.

/** dalej toczą się indywidualnie od lewej do prawej
 * 
 * @param {type} index
 * @param {type} speed
 * @param {type} gravitation
 * @returns {undefined}
 */
function wolno_tocz_sie(index, speed=null, gravitation=0) {

    var delay_rollover = 5;
    if (speed === null) {
        speed = 0.5 + 2 * Math.random();
    }
    if (!break_actions) {
        // jeśli przekroczyłby granice ramki:
        if (icons[index][2] < div_ramka[2] 
                || icons[index][2] > div_ramka[4] - oico_warea) {
            // i są te granice:
            if (!no_border) {
                speed = -speed;
[...]
            }                
        }
        // oblicz i ustaw położenie-left:
        icons[index][2] = icons[index][2] - speed;
        icons[index][0].style.left = (icons[index][2]) + 'px';
        // oblicz i ustaw kąt obrotu:
        icons[index][3] = icons[index][3] - speed * 2;
        icons[index][0].style.webkitTransform = "rotate(" + icons[index][3] + "deg)";
        // ...i tak dalej:
        setTimeout(function() {
            wolno_tocz_sie(index, speed, gravitation);
        }, delay_rollover);
    }
}

…tak więc odbijają się z lewa na prawo do momentu aż …?
Aż:

 no_border == true

Czyli do momentu aż znikną granice, co wtedy? (to jest właśnie w miejscu trzykropka, zobaczmy:)

// ach, tu już jest Schengen!
// ustaw Cookie:
setCookie("plum_comment", '1', 365);
// porusz się także w dół (już nie zapamiętuj -olać):
icons[index][0].style.top = (icons[index][1] + gravitation) + 'px';
// ustaw przyspieszenie i prędkość opadania
var acceleration = 0.05;
if (gravitation === 0) {
    gravitation = 1;
}
gravitation = gravitation * (1 + acceleration);
// czy odleciał już sporo?
if(gravitation > 100) {
    // tak, odleciał, ale...
    if (gravitation < 150) {
        // ale nie tak bardzo daleko, -zaniknij stopniowo:
        icons[index][0].style.opacity = 1 - (gravitation-100)/50;
    }else{
        // już bardzo daleko odleciał - zaniknij całkowicie:
        icons[index][0].style.display = 'none';
        icons[index][1] = null; // zapamiętaj że go już nie ma
        // sprawdź, czy wszystkie zaniknęły:
        var something_exist = false;
        for(var i = 0; i < icon_l.length; i++) {
            if(icons[i][1] !== null) { // to co zapamiętałeś powyżej
                something_exist = true; // nie, coś jeszcze nie zanikło
            }
        }
        // czy wszystkie już zaniknięte?
        if (!something_exist) {
            // tak, wszystkie -zaniknij teraz okno właściwe
            $('#wikseu_plum').fadeOut('fast', 
                // gdy okno zaniknie, usuń element DIV-plum
                function(){    
                    var elem = document.getElementById('wikseu_plum');
                    elem.parentNode.removeChild(elem);                                
                }
                        );
        }
    }
}

…czytam komentarze w kodzie i właściwie wszystko w nich opisałem 🙂
Po zniknięciu wszystkich ikonek zniszcz głównego DIV, aby nie zaśmiecał treści…

Pozostał jeszcze do opisania proces przeładowania treści okna:

/** przeładowanie zawartości HTML diva okienka plum
 * 
 * @returns {undefined}
 */
function reload_popup_content() {
    // element, do którego należy wrzucać treść:
    var content_el = document.getElementById('wikseu_plum_td');
    // czy wrzucano już coś?
    if (popup_text_showed_id >= 0) {
        if (popup_text_showed_id < popup_text_list.length) {
            // cykl: fadeOut --> reload --> fadeIn
            // ukryj dotychczasową treść, 
            $("#wikseu_plum_td").fadeOut('fast', function() {
                // gdy ukryta --> wrzuć nową treść:
                content_el.innerHTML = popup_text_list[popup_text_showed_id];
                // i ukaż
                $("#wikseu_plum_td").fadeIn('slow');
                // cyknij ID dla następnej treści:
                popup_text_showed_id = popup_text_showed_id + 1;
            });
        }else{
            // po ostatniej ukaż przycisk 
            // i ew ustaw timeout dla samoczynnego jego przyciśnięcia
            $('#wikseu_plum_close').click(function(){
                no_border = true;
                return; // bo gdybyprzycisk był wcześniej to nie kontynuj pokazu
            });
            // samoczynne Schengen po 5 sekundach
            setTimeout(function() {
                no_border = true;
            }, time_self_schengen_ms);
        }
    }else{
        // jeszcze nic nie wrzucano:
//        $("#wikseu_plum_popup").fadeIn(500);
        popup_text_showed_id = 0;
    }
    /// ...i znów -po czasie pewnym
    setTimeout(function() {
        reload_popup_content();
    }, time_one_reloaded_ms);
}

…i też komentarze zawierają sporo…

o wyśrodkowaniu wszystkiego CSS można przeczytać tutaj

zaś całość prezentuje się tak

Ok, pora teraz przenieść to do WordPressa, budując plugin i jego ustawienia, z myślą aby można go wykorzystać w przyszłości także do innych zabaw.

dalej…

Loading Disqus Comments ...
Loading Facebook Comments ...

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *