react實現(xiàn)頁面水印效果的全過程
前言
1.為什么選用svg 而不是cavans?
因為cavans 在高分辨率屏幕下,需要根據(jù) devicePixelRatio做寬高的適配,不然就會很模糊,而svg是矢量圖,原生支持各種分辨率,不會產(chǎn)生模糊的情況。
1.使用示例
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import WaterMarkContent from './components/WaterMarkContent'
import App from './App'
ReactDOM.render(
<React.StrictMode>
<WaterMarkContent>
<App />
</WaterMarkContent>
</React.StrictMode>,
document.getElementById('root')
)

2.實現(xiàn)過程
- 構(gòu)造一個水印圖
- 將水印圖鋪滿整個容器
- 水印組件:支持子組件內(nèi)容插槽
構(gòu)造一個svg 的水印圖
const { text = 'waterMark', fontSize = 16, fillOpacity = '0.2', fillColor = '#000' } = props
const res = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="180px" height="180px" viewBox="0 0 180 180">
<text x="-100" y="-30" fill='${fillColor}' transform = "rotate(-35 220 -220)" fill-opacity='${fillOpacity}' font-size='${fontSize}'> ${text}</text>
</svg>`
由上面的代碼,我們可以得到一個svg xml 的字符串,接下來我們將它變成url 資源
const blob = new Blob([res], {
type: 'image/svg+xml',
})
const url = URL.createObjectURL(blob)
由此,我們就得到了一個svg 的資源地址,現(xiàn)在我們將它用于div 的背景圖當中
<div
style={{
position: 'absolute',
width: '100%',
height: '100%',
backgroundImage: `url(${url})`,
top: 0,
left: 0,
zIndex: 999,
pointerEvents: 'none', //點擊穿透
}}
></div>
至此,我們很輕松的得到了一個鋪滿水印的div,下面我們將代碼整合,并封裝成組件。
3.組件代碼
import React from 'react'
import { ReactNode, useMemo } from 'react'
type svgPropsType = {
text?: string
fontSize?: number
fillOpacity?: number
fillColor?: string
}
const SvgTextBg = (props: svgPropsType) => {
const { text = 'waterMark', fontSize = 16, fillOpacity = '0.2', fillColor = '#000' } = props
const res = `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="180px" height="180px" viewBox="0 0 180 180">
<text x="-100" y="-30" fill='${fillColor}' transform = "rotate(-35 220 -220)" fill-opacity='${fillOpacity}' font-size='${fontSize}'> ${text}</text>
</svg>`
const blob = new Blob([res], {
type: 'image/svg+xml',
})
const url = URL.createObjectURL(blob)
return (
<div
style={{
position: 'absolute',
width: '100%',
height: '100%',
backgroundImage: `url(${url})`,
top: 0,
left: 0,
zIndex: 999,
pointerEvents: 'none', //點擊穿透
}}
></div>
)
}
type propsType = {
children?: ReactNode
} & Partial<svgPropsType>
const WaterMarkContent = (props: propsType) => {
const { text, fontSize, fillOpacity, fillColor } = props
const memoInfo = useMemo(
() => ({
text,
fontSize,
fillOpacity,
fillColor,
}),
[text, fontSize, fillOpacity, fillColor]
)
return (
<div style={{ position: 'relative', width: '100%', height: ' 100%' }}>
{props.children}
<SvgTextBg {...memoInfo} />
</div>
)
}
export default WaterMarkContent
總結(jié)
到此這篇關(guān)于react實現(xiàn)頁面水印效果的文章就介紹到這了,更多相關(guān)react實現(xiàn)頁面水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決React報錯React.Children.only expected to rece
這篇文章主要為大家介紹了React報錯React.Children.only expected to receive single React element child分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01

