產品經理說的SVG

上週六,產品經理釘釘發我一個騰訊公衆號的連接,說:「你知道這是怎麼實現的嗎?」css

svg
我心裏第一個蹦出的想法是:用filter的grayscale(%),再加個transition過分不就行了🤔。不,確定不是我想的這麼簡單。接着我回答:「不知道。」

經理說:「去搞下SVG,之後能夠用這個寫動畫,這樣的話,就不用 JS、CSS這麼麻煩了。」html

當我去了解並看手冊學習事後,我心裏更加充滿疑問。SVG的優勢是圖像不會失幀不會不清晰,它的清晰度適合任何屏幕分辨率;比起gif、jpeg、png文件要小不少但缺點是:不是全部的瀏覽器都支持,即老版的瀏覽器,老版的手機是不支持的。SVG有點像我上學那會玩的CAD,用座標點畫圖。這圖一點一點畫出來?不可能,這怎麼可能一個座標點一個座標點描繪出來,只爲了一個圖片點擊變亮的動畫??web

而後我回去打開連接,F12 打開一看,原來是用了2張圖片,一張暗的,一張明亮的圖片。當點擊時,用animate把暗的圖片opacity掉,這時肉眼就只看到明亮的圖片。這時,我想吐血,爲啥我不一開始就F12,😔。瀏覽器

<section style="height: 0px;">
        <svg data-copyright="GL" style="display: inline-block;width: 100%;vertical-align: top;background-position: 0% 0%;background-repeat: no-repeat;background-size:100% 100%;background-attachment: scroll;background-image: url(6402.png);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;" viewBox="0 0 1080 720"></svg>
</section>
<svg data-copyright="GL" style="transform: scale(1);display: inline-block;width: 100%;vertical-align: top;background-size: 100% 100%;background-attachment: scroll;background-image: url(640.png);background-position: 0% 0%;background-repeat: no-repeat no-repeat;" viewBox="0 0 1080 720">
    <animate attributeName="opacity" begin="click" dur="3000s" keyTimes="0;0.001;1" values="1;0;0" fill="freeze" restart="whenNotActive"></animate>
</svg>
複製代碼

我想換一種思路實現這個點擊圖片變亮,用最開始想的filter的grayscale(%),再加個transition過分bash

先附上效果圖ide

click

//css
.imgN{
    width: 300px;
    filter: grayscale(100%);
}
.imgactive{
    transition: all 1s ease-in-out;
    filter: grayscale(0);
}

//html
<div class="img" ><img class="imgN" src="6402.png" alt=""></div>
<script>
    document.querySelector('.imgN').addEventListener('click',function(){
        document.querySelector('.imgN').classList.toggle('imgactive')
    })
</script>
複製代碼

不用點擊,改用hover就更簡單了。svg

//css就搞定了
.fourimg img{
    width: 300px;
    filter: grayscale(100%);
    transition: all 1s ease-in-out;
}
.fourimg img:hover{
   
    filter: grayscale(0);
}
//html
<div class="fourimg">
    <img src="6402.png" alt="">
</div>
複製代碼

既然知道了SVG,不來點實際性的實操學習,不靠譜,不踏心。而後我就去了嗶哩嗶哩找了個視頻教程跟着實操下,來附上嗶哩嗶哩做者的連接www.bilibili.com/video/BV1fJ…oop

使用SVG實現絲滑流暢的上傳按鈕動畫學習

老規矩,先附上效果圖flex

button

這個思路是,先html用svg畫出圓形、打勾、箭頭、豎線以及虛線,接着css寫樣式以及動畫,最後用js切換uploaded和uploading兩個類,以及控制上傳進度條。附上最終代碼:

//html
<main>
    <div class="upload-button uploaded">
        <svg class="arrow" width='40' height='40' viewBox='0 0 40 40'>
            <circle cx='50%' cy='50%' r='19' fill='none' stroke='#fff' stroke-width='2'></circle>
            <polyline class="arrow-top" points='6,20 20,6 34,20' fill='none' stroke='#fff' stroke-width='2'></polyline>
            <line class="middle-line" x1='50%' y1='7' x2='50%' y2='34' stroke='#fff' stroke-width='2'></line>
            <polyline class="checkmark" points='8,20 18,30 30,12' fill='none' stroke='#fff' stroke-width='2'></polyline>
        </svg>
        <div class="progress-bar"></div>
    </div>
</main>

//css
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "PingFang SC","Microsoft Yahei","sans-serif";
}
main{
    display: flex;
    align-items: center;
    justify-content: center;
    background: #222f3e;
    height: 100vh;
}
.upload-button{
    width: 180px;
    height: 60px;
    background-image: linear-gradient(160deg,#0093e9,#80d0c7);
    border-radius: 8px;
    cursor: pointer;
    box-shadow: 0 2px 10px rgb(0,147,233,0.28);

    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.upload-button .checkmark{
    opacity: 0;
}
.upload-button .progress-bar{
    position: absolute;
    /* width: 50%; */
    height: 2px;
    background-image: linear-gradient(45deg,#85ffbd,#fffb7d);
    bottom: 0;
    left: 0;
    border-radius: 4px;
}
.upload-button.uploading .middle-line{
    stroke-dasharray: 4 3;
    animation: 0.8s linear dashloop infinite;
}
.upload-button.uploading circle{
    animation: 1.5s linear blink infinite;
}

.upload-button.uploaded .arrow-top{
    animation: 1s linear arrowTransform forwards;
}

.upload-button.uploaded .checkmark{
    opacity: 1;
    stroke-dasharray: 100 100;
    stroke-dashoffset: 100;
    animation: 1s linear checkmarkTransform forwards 0.5s;
}

.upload-button.uploaded .middle-line{
    transform: 0.3s linear;
    opacity: 0;
}

@keyframes dashloop{
    from{
        stroke-dashoffset: 0;
    }
    to{
        stroke-dashoffset: 7;
    }
}
@keyframes blink{
    from{
        opacity: 1;
    }
    50%{
        opacity: 0.5;
    }
    to{
        opacity: 1;
    }
}

@keyframes arrowTransform{
    from{
        stroke-dasharray: 100 100;
        stroke-dashoffset: 0;
    }
    to{
        stroke-dasharray: 100 100;
        stroke-dashoffset: -100;
    }
}
@keyframes checkmarkTransform{
    from{
        stroke-dasharray: 100 100;
        stroke-dashoffset: 100;
    }
    to{
        stroke-dasharray: 100 100;
        stroke-dashoffset: 0;
    }
}

//js
var uploadButton = document.querySelector('.upload-button');
var progressBar = document.querySelector('.upload-button .progress-bar');

let width = uploadButton.getBoundingClientRect().width;
let uploadTime=5000;

uploadButton.addEventListener('click',function(){
    uploadButton.classList.remove('uploaded');
    uploadButton.classList.add('uploading');

    setTimeout(function(){
        uploadButton.classList.replace('uploading','uploaded');
    },uploadTime);

    //進度條
    let star = null;
    // timestamp 動畫開始的時間戳
    function grow(timestamp){
        if(!star) star = timestamp;

        let progress = timestamp - star; //距離開始時過去了多少毫秒做爲進度

        //根據 progress 按比例算出 該增長多少寬度 給進度條
        // Math.min 若是 寬度超出 按鈕的寬度,就直接等於 按鈕的寬度
        // width * (progress / uploadTime) 過去的毫秒 比上 總的毫秒  再 乘以 按鈕寬度 就能算出 當前進度條時多少寬度
        progressBar.style.width=`${Math.min(width * (progress / uploadTime),width)}px`;


        //若是進度尚未到達 uploadTime ,則繼續調用 requestAnimationFrame ,直到大於等於 uploadTime
        if(progress < uploadTime){
            window.requestAnimationFrame(grow);
        }
    }

    window.requestAnimationFrame(grow);
})
複製代碼

嗯,我想旺哥(產品經理)的想法是:用svg作動畫。但一整個下來,我也沒以爲svg的動畫比js,css簡易多,是否是我想的太多,哈哈哈😄,確定是我懶,不想去搞svg了。在工做中,我老是容易跑偏旺哥的想法,不知道我此次有沒有跑偏,我也不敢問,也不敢說。若是你看到這篇文章,旺哥,在下方留言哈。😄

相關文章
相關標籤/搜索