網頁自定義進度條動畫(Process Bar Animate)【一】

    網路上有很多進度條的寫法,原本Html就有進度條的 語法 ,再加上一些CSS的 美化 ,就可以做出符合大多數人想像的進度條。再不然還可以用 Jquery UIJquery plugin ,還有別忘了Bootstrap的進度條,應有盡有。

    那為什麼選擇那麼多,還要特別自己研究呢?

    原因是因為設計師設計出來的UI既不是圓的進度條也不是長條的進度條,而是不規則形狀的進度條。(原本是只擺一張圖在上面的)

    剛開始設計師的想法很簡單,改進度條的%數?那我就再出一張圖就好啦!可是總不可能每次都剛好有空幫客戶出圖吧?而且客戶還是需要在後台修改數據來更新進度條的,那這樣也不可能在他們要更新進度條的時候就來聯絡我們修改圖吧?因此就開始了程式設計師(我)三天的研究之路......

    其實我一開始的想法也很簡單,哎呀,我們這個網站是用Bootstrap做的嘛!那我去改Bootstartp的進度條css就好啦!把設計師做出來的UI做個遮罩!

<style>
.process{
	clip-path:...;
}
</style>

    結果因為形狀太複雜,所以我先遭受到了第一個難關,找位置找到快瘋掉。後來我查到資料,clip-path屬性是從svg來的。哎呀,這就好說了,我們的設計師是用AI出圖的,於是我請設計師幫我把進度條轉存成svg給我,然後再看它的程式碼。

    看svg的程式碼只要用記事本就可以,或是用正在打程式的各個軟體都行。

    設計圖的svg導出是path屬性畫的,於是我就開開心心的把數據複製到css裡面。然後、然後就壞掉了......

    而且也沒辦法做rwd的部分,既然如此就只能找別的方法了...!【如果有人會請告訴我做法!】我又繼續踏上了尋找寫自定義進度條的新方法之路。


    我找到的第二種方式是利用這個套件,真說我差點成功了,差點。

    說差點成功的原因是,它的動畫只能跑一次,之後我想用jquery.animate()跑第二次的時候就卡住了,程式有顯示完成這個動畫,但是實際上並沒有跑出來。目前我還沒有找到解決方法,於是只能忍痛放棄...

    不需要重播動畫的人應該使用這個套件就可以了,稍微簡單講解一下這個套件,因為它沒有build js檔,所以還可以看到底是什麼原理做的,感謝開發者,讚嘆開發者。

主要看以下幾個屬性:

data-percent >> 百分比
data-animation >> 動畫總時數(毫秒)
data-color >> 進度條顏色
class="progressIcon" >> 偵測要做動畫的class

    大家很常用的icon大多都是svg檔,通常會用<i>包起來,當然也有些人會用<span>,理所當然的直接用svg也是沒有問題的。
(下面的程式碼是我擷取套件範例的index.html裡的程式碼)

<!-- with <i>, id and data-class for apply style, (font Size for resize this <i>) -->
<i id="myId" data-class="myClass" data-percent="80" data-color="#ff5733" data-animation="1500" style="font-size: 156px;" class="fab fa-html5 progressIcon"></i>
<!-- data-percent for percent, data-color for color : accept hexa, rgb...-->
<i data-class="myClass" data-percent="70" data-color="rgb(168, 255, 51)" data-animation="3000" style="font-size: 156px;" class="fab fa-css3 progressIcon"></i>
<!-- data-animation for duration animation in ms -->
<span data-percent="50" data-color="rgba(168, 255, 51, 0.5)" data-animation="1500" style="font-size: 48px;" class="bi bi-arrow-down-square-fill progressIcon"></span>
<svg data-percent="50" data-color="#ff5733" xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor" class="bi bi-alarm-fill progressIcon" viewBox="0 0 16 16">
	<path d="M6 .5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1H9v1.07a7.001 7.001 0 0 1 3.274 12.474l.601.602a.5.5 0 0 1-.707.708l-.746-.746A6.97 6.97 0 0 1 8 16a6.97 6.97 0 0 1-3.422-.892l-.746.746a.5.5 0 0 1-.707-.708l.602-.602A7.001 7.001 0 0 1 7 2.07V1h-.5A.5.5 0 0 1 6 .5zm2.5 5a.5.5 0 0 0-1 0v3.362l-1.429 2.38a.5.5 0 1 0 .858.515l1.5-2.5A.5.5 0 0 0 8.5 9V5.5zM.86 5.387A2.5 2.5 0 1 1 4.387 1.86 8.035 8.035 0 0 0 .86 5.387zM11.613 1.86a2.5 2.5 0 1 1 3.527 3.527 8.035 8.035 0 0 0-3.527-3.527z" />
</svg>

    它的原理是這樣,你必須先在你要做動畫的i/span/svg上加上class progressIcon,然後再寫幾個基本的data。【↑↑參照上面的表↑↑

    當然別忘記在html掛上process.js!js抓到progressIcon的css之後,就會開始跑迴圈,先在要成為進度條的物件外面包一個div,刪掉物件身上的class progressIcon,再把progressIcon丟到div的class裡。幫div加上相對定位,設定display:table。【display:table也不一定要,視個人需求看要不要留著】
(下面的程式碼是我擷取套件範例的process.js裡的程式碼)

    $('.progressIcon').each(function(){
        
        let divProgress = $('
').css({'position': 'relative', 'display' : 'table'}).addClass("progressIcon"); $(this).removeClass('progressIcon'); $(this).wrap(divProgress); ... });

    複製一個進度條物件,把原本進度條物件上的class複製到複製體上。在進度條本體上加上絕對定位,並且把圖層上調,在複製體上調整不透明度設定display:block。【display:block一樣不一定需要,應該是跟上面div的table是整套的】把複製體放到本體的下面。
(下面的程式碼是我擷取套件範例的process.js裡的程式碼)

    $('.progressIcon').each(function(){
        
			...
            
        //clonner l'icon pour le mettre en fond
        let cloneGray = $(this).clone().addClass($(this).attr('class'));
        $(this).css({"position" : "absolute", "color" : $(this).data("color"), 'z-index' : 2});
        cloneGray.css({'opacity': '0.15', 'display': 'block'});
        $(this).after(cloneGray);

			...

    });

    抓取本體上的data-animation,如果數值大於0,則進入下一個判斷,不然就是直接顯示進度條的位置。【進度條的呈現是放在本體上的,複製體會變成底圖的概念】下一個判斷是如果你的進度條物件是在使用者可以看到的地方,就馬上進做動畫的function,如果不是,就加一個class animationProgress。
(下面的程式碼是我擷取套件範例的process.js裡的程式碼)

    $('.progressIcon').each(function(){
        
			...
            
        //déclancher une animation ou pas
        let animation = parseInt($(this).data("animation"))
        if (animation > 0){
            if ($(this).offset().top > $(window).scrollTop() && $(this).offset().top < $(window).scrollTop()+$(window).height()) anim($(this));
            else $(this).addClass("animationProgress");
        } else {
            $(this).css('clip-path', `inset(0% ${100-parseInt($(this).data("percent"))}% 0% 0%)`);
        }

    });

    接下來是做動畫的function,變數elem承接了當下要做動畫的進度條本體,先設本體的clip-path【讓它在最左邊】,之後進jquery的animate的事件。

someValue>>把data-percent的數據轉成整數,做成自定義變數
duration>>把data-animation的數據轉成整數,設成動畫總時數(毫秒)
step>>在這個function裡擺入自定義變數someValue,並且每格朝向目標的數值前進(動畫本體)

    將進度條本體拉到最左邊的數值是100%,所以要跑到指定的百分比當然要是100-someValue,最後在做這個動畫之前會delay0.8秒。
(下面的程式碼是我擷取套件範例的process.js裡的程式碼)

 function anim(elem){
        $(elem).css('clip-path', `inset(0% 100% 0% 0%)`).animate({someValue: parseInt($(elem).data("percent"))}, {
            duration: parseInt($(elem).data("animation")),
            step: function(someValue) {$(elem).css('clip-path', `inset(0% ${100-someValue}% 0% 0%)`)}
        }).delay(800);
    }

    當使用者在上下滑動網頁時,判斷有沒有animationProgress的class,如果有的話,確認進度條是不是在畫面中,在畫面中就進做動畫的function,並且拿掉animationProgress的class。
(下面的程式碼是我擷取套件範例的process.js裡的程式碼)

    $(window).scroll(function () {
        $('.animationProgress').each(function(){
            if ($(this).offset().top > $(window).scrollTop() && $(this).offset().top < $(window).scrollTop()+$(window).height()){
                anim($(this));
                $(this).removeAttr('class', 'animationProgress');
            }
        })
    });

    以上就是jquery progress-bars-svg-image套件的講解。接下來的部分就等下一篇文章再繼續吧!


Written by 樂水

留言

這個網誌中的熱門文章

Bootstrap 4 旋轉木馬用滑鼠左右滑動切換圖片

網頁自定義進度條動畫(Process Bar Animate)【二】