今天要來做的是圖片模糊加載,圖片一開始是很模糊的,隨著加載率從0%~100%的過程中,會越來越清楚,最後進入焦點,而加載文字的部分則會慢慢淡出
1.一張你喜歡的圖片,要做為背景用
知識點 | 使用說明 |
---|---|
Background 背景 | 設定背景圖片格式 |
Filter濾鏡效果 | 圖片的模糊處理 |
calc() 計算函數 | 計算模糊範圍 |
知識點 | 使用說明 |
---|---|
querySelector() | 獲取HTML元素 |
setInterval() / clearInterval() | 抓取加載%數的範圍 |
innerText | 把加載文字渲染在畫面上 |
<div class="bg"></div>
<!-- 加載文字-->
<div class="loading-text">0%</div>
div.bg {
/* <background-image> <background-repeat> <background-position> / <background-size>*/
background: url("...") no-repeat 50% 50% / cover;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
filter: blur(30px);
}
background是有關背景圖片的各個屬性集合,關於background的順序並沒有一個很明確的標準,可以參考stackoverflow上的這篇文章
background-position
設為50% 50%也等於center center,如果兩個值都一樣,可以只寫一個background-position
和background-size
之間會用『/』去區隔彼此
這裡主要就是設定背景圖片的大小、位子...,並利用filter:blur(PX)
去做模糊效果,數字越大越模糊,如果沒有填入,預設是0
加載文字
.loading-text {
font-size: 50px;
color: white;
}
若以上都設定好呈現如下,好像沒有戴上眼鏡的世界一樣模糊
不過我們會看到周圍會有一圈白邊,如果我想要讓白邊的範圍不要那麼大,稍微內縮,可以怎麼做呢??
以下程式碼只擷取有修改過的部分,我們為了把白邊範圍內縮一點,所以把top和left設定為"負數",所以它就會往視窗上方以及左方移動,這點應該沒有問題,不過如果只設這樣並不夠,那我右邊和下面的白框還是沒有內縮啊~該怎麼辦呢?
其實有兩種解法,第一種就是很直覺的把right
和bottom
設為-30px,不過還有更精簡的寫法,就是底下這種寫法
calc取自英文calculator的前面四個字,意思是計算,所以 calc(mathematical expression)
通常拿來做數值的運算,而且運算的數值"不需要"相同單位,我可以「 px + % 」或是「 % - px - em」等,彈性相當大,不過若運算子中間沒有空格格開(如:「 px+% 」),整個效果就會不見,這也是我在實作的過程意外發現的bug
div.bg {
top: -30px;
left: -30px;
width: calc(100vw + 60px);
height: calc(100vh + 60px);
}
let loadText = document.querySelector(".loading-text");
let bg = document.querySelector(".bg");
let load = 0;
let int = setInterval(blurring, 30); //每30毫秒執行一次blurring這個函式
function blurring() {
load++;
console.log(load);
//記得clearInterval()
if (load > 99) {
clearInterval(int);
}
}
你可以試著把clearInterval()
註解看看,打開Dev tool就會看到一串無限的數字再跑 @ @ ,所以務必要記得clearInterval()!!這樣一來它的範圍只會被我們限縮在0~100,而我們要利用這個結論去讓加載文字可以從0%~100%去跑
繼續加上下面這一段,我們要把剛剛load的數字渲染到畫面上
loadText.innerText = `${load}%`;
呈現會如下圖,算是完成1/3了
我們在最一開始的完成版看到,隨著加載率的上升,除了圖片越來越清楚外,%數則會慢慢淡出,接下來我們要來實作%數慢慢淡出這一段
這可以說是此賽pjoject的重頭戲,參考了sackoverflow上的一篇文章來完成,它是一個要把一個數字範圍應設到另一個數字範圍的function,恩..聽不懂沒關係,直接看底下程式碼更清楚,這用法也是我第一次看到,先附上stackoverflow的文章map a range of numbers to another range of numbers
%數的淡出
0% ➔ opacity:1;
100% ➔ opacity:0;
利用opacity去控制
loadText.style.opacity = scale(load, 0, 100, 1, 0); //加載數字(load)0-100的透明度為1-0
// 以下取自stackoverflow
function scale(number, inMin, inMax, outMin, outMax) {
return ((number - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
}
設定好後,呈現如下,我們讓數字慢慢淡出了,完成2/3了ヽ(✿゚▽゚)ノ
圖片的模糊程度
跟%數的淡出其實是同理
bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)`;//加載數字(load)0-100的圖片的模糊程度為blur(30px)➔blur(0px)
若以上都設定好,就全部完成啦~
在此附上codepen連結 https://codepen.io/hangineer/pen/zYjqMMj
另外也可以不使用stackoverflow的那個function,有更簡潔的方法
圖片取自50 Projects In 50 Days - HTML, CSS & JavaScript FAQ
本篇用到了calc()
、setInterval()
與 clearInterval()
、數字範圍變化的function等,各個知識點的釐清很重要,另外也在底下補充了一些常混淆的觀念
[補充]
談談 JavaScript 的 setTimeout 與 setInterval
JavaScript innerHTML 與 innerText 的差異
關於javaScript的Expression和Statement
若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!明天見
50 Projects In 50 Days - HTML, CSS & JavaScript
CSS Background-position
w3School CSS filter
map a range of numbers to another range of numbers
[補充]
設在背景圖片中的 filter: blur(30px);
是可以省略的
因為後來透過以下這段javaScript去控制了
// 圖片的模糊程度
bg.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px
function scale(number, inMin, inMax, outMin, outMax) {
return ((number - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
}