基于React封裝一個層次模糊效果的容器組件
繪制H5頁面時,模糊效果(或稱為毛玻璃效果)被廣泛用于增強(qiáng)用戶界面的美觀性和層次感。這種效果不僅可以吸引用戶的注意,還能提供視覺上的分隔,而不完全阻擋背后的內(nèi)容。基于此,本文封裝一個React組件,該組件能夠在容器上實(shí)現(xiàn)層次化的模糊效果,使得開發(fā)者可以輕松地在其項目中應(yīng)用并自定義這種設(shè)計風(fēng)格。
先放效果圖:


需求分析
該組件需要滿足以下幾個基本需求:
- 可自定義模糊層數(shù):組件應(yīng)允許用戶設(shè)置模糊效果的層數(shù),以便于調(diào)整模糊效果的精度和深度。
- 可自定義模糊強(qiáng)度:用戶應(yīng)能夠設(shè)置模糊的最大強(qiáng)度,以控制最外層的模糊程度。
- 可自定義容器尺寸和形狀:包括容器的高度和邊框圓角半徑。
- 自定義類名:允許用戶添加自定義類名,以便于在外部CSS文件中進(jìn)一步樣式定制。
構(gòu)建過程
基于上述需求,我們設(shè)計了HcBlurBox組件。下面是構(gòu)建此組件的具體步驟:
1. 設(shè)置組件接收的Props
首先,我們定義組件能夠接收的props,包括:
accuracy(模糊層數(shù))radius(邊框圓角半徑)height(容器高度)maxBlur(最大模糊值)ratio(高度比率)className(自定義類名)
2. 計算模糊層樣式
對于每一個模糊層,我們根據(jù)傳入的accuracy、maxBlur和ratio來動態(tài)計算其高度和模糊度。使用Array(accuracy).fill(0).map來創(chuàng)建指定數(shù)量的模糊層,并為每層應(yīng)用以下樣式規(guī)則:
- 高度(
height):根據(jù)ratio和accuracy計算得出的每層的高度百分比。 - 模糊效果(
backdropFilter):使用CSS的blur()函數(shù),根據(jù)層的順序和maxBlur來動態(tài)計算模糊度。
3. 條件渲染
為了確保組件的靈活性和健壯性,我們在沒有提供height屬性時讓組件返回null,以避免渲染不必要的DOM元素。
4. 應(yīng)用樣式和自定義類名
最后,我們將計算得到的樣式應(yīng)用到每個模糊層上,并通過${className}模板字符串將用戶提供的自定義類名添加到容器div上,以實(shí)現(xiàn)進(jìn)一步的樣式自定義。
完整代碼展示
import React from "react";
import "./index.less";
/**
* 創(chuàng)建一個具有層次模糊效果的容器組件。
*
* @component
* @param {Object} props - 組件接收的props。
* @param {number} [props.accuracy=2] - 精度,決定模糊層的數(shù)量。
* @param {number} [props.radius=5] - 模糊層的邊框圓角半徑。
* @param {number} props.height - 容器的高度,必須提供。
* @param {number} [props.maxBlur=12.5] - 最大模糊值。
* @param {number} [props.ratio=100] - 高度比率,用于計算每個模糊層的高度百分比。
* @param {string} [props.className=''] - 容器的自定義類名。
* @returns {ReactElement|null} 返回一個模糊效果的React組件,如果沒有提供高度,則返回null。
*
* @example
* <HcBlurBox height={100} accuracy={3} maxBlur={15} className="custom-class" />
*/
const HcBlurBox = (props) => {
const {
accuracy = 2,
radius = 5,
height,
maxBlur = 12.5,
ratio = 100,
className = '',
} = props;
// 如果沒有提供高度,則不渲染組件
if(!height) return null;
return (
<div className={`hc-blur-box-container ${className}`}>
{Array(accuracy).fill(0).map(
(v, i) => {
const step = i + 1;
const _height = ratio - (100 / accuracy) * i; // 計算每個模糊層的高度百分比
const blur = `blur(${(maxBlur / accuracy) * step}px)`; // 根據(jù)精度和步驟計算模糊效果
// 如果計算得到的高度小于2倍的height,則不渲染該層
if (2 * radius > _height * height / 100) return null;
return (
<div
key={i} // 添加key以滿足React列表渲染的要求
className="hc-blur-box"
style={{
height: `${_height}%`, // 設(shè)置模糊層的高度
backdropFilter: blur, // 應(yīng)用模糊效果
borderBottomLeftRadius: radius, // 設(shè)置邊框圓角半徑
borderBottomRightRadius: radius,
}}
/>
)
}
)}
</div>
)
}
export default HcBlurBox;
.hc-blur-box-container {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
.hc-blur-box {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
backdrop-filter: blur(2.5px);
mask: linear-gradient(to top, rgb(0, 0, 0) 50%, rgba(0, 0, 0, 0.8) 70%, rgba(0, 0, 0, 0) 100%);
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.64) 100%);
z-index: 1;
border: none ;
}
}
通過HcBlurBox組件,開發(fā)者可以輕松在其React項目中實(shí)現(xiàn)具有層次模糊效果的容器,大大豐富了界面的視覺效果和用戶體驗。此組件的靈活性和可定制性,使其能夠適應(yīng)各種設(shè)計需求。
兼容方案
上述代碼雖然能夠完成最終效果,但是有的瀏覽器不支持mask css屬性,這個時候,只需要通過絕對定位和父容器等大的div去模擬mask的效果就可以了。以下的代碼是兼容組件,當(dāng)然你喜歡的話可以將兩個組件融合成一個。
兼容組件
import React from "react";
import "./index.less"; // 引入樣式文件
const DoubleLayeredDiv = () => {
return (
<div className="container">
{[...Array(10).keys()].map((index) => (
<div
key={index}
className={`background-image img${index + 1}`}
style={{
background-position-y: -10*(index+1);
filter: `blur(${index+1}px)`;
bottom: -10*(index+1);
}}
></div>
))}
<div className="gradient-overlay"></div>
<div className="content">Your Content Here</div>
</div>
);
};
export default DoubleLayeredDiv;
對應(yīng)的樣式文件 (index.less)
.container {
margin: auto;
margin-top: 200px;
position: relative;
width: 400px;
height: 600px;
overflow: hidden;
border-radius: 30px;
box-shadow: 0 0 20px 0px;
background-image: url('./page1.jpg');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.background-image {
width: 100%;
height: 600px;
background-image: url('./page1.jpg');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: absolute;
left: 0;
z-index: 1;
}
.gradient-overlay {
width: 100%;
height: 500px;
background-image: linear-gradient(to top, black, transparent);
position: absolute;
bottom: 0;
left: 0;
z-index: 2;
}
.content {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 3;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 20px;
}
兼容backdrop-filter
雖然現(xiàn)代瀏覽器普遍支持CSS的backdrop-filter屬性來實(shí)現(xiàn)模糊效果,但是并非所有瀏覽器都支持(特別是舊版瀏覽器)。對于不支持backdrop-filter屬性的瀏覽器,我們可以采取以下兼容性方案:
- 使用多層圖片疊加:如上述組件所示,通過創(chuàng)建多個帶有不同模糊度的圖層(使用
filter: blur()),我們可以在不支持backdrop-filter的環(huán)境下模擬出類似的視覺效果。 - 使用靜態(tài)模糊背景圖片:為了進(jìn)一步兼容那些連
filter屬性也不支持的古老瀏覽器,可以預(yù)先生成一張模糊的背景圖片,并在需要時作為備選方案使用。 - 優(yōu)雅降級:對于極端的兼容性需求,可以考慮在不支持模糊效果的瀏覽器中簡單隱藏這些效果,保留基本的內(nèi)容展示。這可以通過JavaScript檢測特定CSS屬性的支持情況來實(shí)現(xiàn)。
總之,雖然完全的跨瀏覽器兼容性往往難以實(shí)現(xiàn),但通過巧妙地利用CSS和JavaScript,仍然可以為大多數(shù)用戶提供接近設(shè)計意圖的體驗,同時為那些使用舊瀏覽器的用戶提供可接受的備選方案。
到此這篇關(guān)于基于React封裝一個層次模糊效果的容器組件的文章就介紹到這了,更多相關(guān)React層次模糊容器組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React如何實(shí)現(xiàn)像Vue一樣將css和js寫在同一文件
這篇文章主要介紹了React如何實(shí)現(xiàn)像Vue一樣將css和js寫在同一文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
react?路由權(quán)限動態(tài)菜單方案配置react-router-auth-plus
這篇文章主要為大家介紹了react路由權(quán)限動態(tài)菜單方案react-router-auth-plus傻瓜式配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
react 下拉框內(nèi)容回顯的實(shí)現(xiàn)思路
這篇文章主要介紹了react 下拉框內(nèi)容回顯,實(shí)現(xiàn)思路是通過將下拉框選項的value和label一起存儲到state中, 初始化表單數(shù)據(jù)時將faqType對應(yīng)的label查找出來并設(shè)置到Form.Item中,最后修改useEffect,需要的朋友可以參考下2024-05-05
React?UI組件庫之快速實(shí)現(xiàn)antd的按需引入和自定義主題
react入門學(xué)習(xí)告一段路,下面這篇文章主要給大家介紹了關(guān)于React?UI組件庫之快速實(shí)現(xiàn)antd的按需引入和自定義主題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
詳解React中setState回調(diào)函數(shù)
這篇文章主要介紹了詳解React中setState回調(diào)函數(shù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06

