上週六,產品經理釘釘發我一個騰訊公衆號的連接,說:「你知道這是怎麼實現的嗎?」css
經理說:「去搞下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
//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
這個思路是,先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了。在工做中,我老是容易跑偏旺哥的想法,不知道我此次有沒有跑偏,我也不敢問,也不敢說。若是你看到這篇文章,旺哥,在下方留言哈。😄