import React, { useEffect, useRef } from "react";
import html2canvas from "html2canvas";
const default_style = {
position: "absolute",
left: "-100%",
top: "-100%",
transform: "rotate(-15deg)",
color: "rgba(0,0,0,.06)",
fontSize: "14px",
};
const observerOption = {
childList: true,
attributes: true,
subtree: true,
attributeFilter: ["style"],
attributeOldValue: true,
};
const watermarkCanvas = { current: null };
function Watermark(props) {
const {
styleObj = default_style,
text = "我是水印",
parentId,
density = "50px 30px",
} = props;
const nodeRef = useRef();
const parentNodeRef = useRef();
useEffect(() => {
parentNodeRef.current = parentId
? document.querySelector(`#${parentId}`)
: nodeRef.current.parentNode;
parentNodeRef.current.style.backgroundAttachment = `fixed`;
parentNodeRef.current.style.backgroundPosition = `top center`;
if (watermarkCanvas.current) {
loadMark();
} else {
html2canvas(nodeRef.current, { scale: 1 }).then((canvas) => {
watermarkCanvas.current = canvas.toDataURL("image/png");
loadMark();
});
}
const MutationObserver =
window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver;
const watermarkDom = new MutationObserver(observerCallback);
watermarkDom.observe(parentNodeRef.current, observerOption);
}, []);
const loadMark = () => {
if (watermarkCanvas.current) {
parentNodeRef.current.style.backgroundImage = `url(${watermarkCanvas.current})`;
}
};
const observerCallback = () => {
loadMark();
};
return watermarkCanvas.current ? (
<div ref={(watermarkText) => (nodeRef.current = watermarkText)} />
) : (
<div
style={{ ...styleObj, padding: density }}
ref={(watermarkText) => (nodeRef.current = watermarkText)}
>
{text}
</div>
);
}
export default Watermark;
import React from "react";
import Watermark from "@/components/public/Watermark/Watermark";
interface IUserInfo {
name: string;
englishName: string;
originId: number;
}
export interface IProps {
userInfo: IUserInfo;
}
const Index: React.FC<IProps> = props => {
const { userInfo } = props;
return (
<div>
<div>我是内容</div>
{userInfo.name && (
<Watermark
text={`${userInfo.name} ${userInfo.englishName} - ${userInfo.originId}`}
/>
)}
</div>
);
};
export default Index;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义