原理不复杂,但是说起来可能比较啰嗦。
图片背景
首先我们需要知道,CSS 可以为一个元素设置图片背景,例如下面这段代码:
<div style="background-image: url(/assets/ChiliPowder-20240606233038-qme6rlm.png);height:400px">/assets/ChiliPowder-20240606233038-qme6rlm.png</div>
上面这段代码定义了一个带有图片背景的 div
元素,很容易想到,如果我们有一张水印图片,就可以在我们要添加水印的元素后面加上这个背景。
例如下面这样:
<div style="background-image: url(/assets/1719628922704-20240629104229-vk3477u.jpg);background-size:200px;height:400px;font-size:xxx-large;color:pink">如果你扫描下面二维码就会发现它是我们的支付宝收款码</div>
但是这样只能使用现成的图片作为背景,那么有什么办法能够快速生成一个图片背景呢?
svg 的 foreignElement
SVG (Scalable Vector Graphics) 提供了丰富的图形绘制功能,可以用来生成各种复杂的图形和图像。使用 SVG 的 foreignObject
元素,我们可以在 SVG 图形中嵌入 HTML 或 XHTML 内容,从而实现复杂的图片背景效果。
下面是一个简单的示例,演示如何使用 SVG 的 foreignObject
元素来生成带有文本内容的图片背景:
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px; background: lightgrey;">
<p>这是一个嵌入的HTML段落。</p>
</div>
</foreignObject>
</svg>
在这个示例中,我们创建了一个 400x200 像素的 SVG 画布,并在其中嵌入了一个带有背景颜色和文本内容的 HTML div
元素。这种方法允许我们使用 CSS 来控制嵌入内容的样式,从而实现丰富的图片背景效果。
动态生成背景图片
使用 SVG 和 foreignObject
元素,我们还可以动态生成背景图片。例如,我们可以使用 JavaScript 来创建带有自定义文本内容的 SVG 图像,并将其作为背景应用到页面元素中。下面是一个简单的例子:
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Dynamic SVG Background</title>
<style>
#watermark {
width: 100%;
height: 200px;
background-size: cover;
background-repeat: no-repeat;
}
</style><div id="watermark">这里是一些文本内容。</div><script>
function generateSVGBackground(text) {
const svg = `
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px; background: lightgrey;">
<p>${text}</p>
</div>
</foreignObject>
</svg>
`;
return `data:image/svg+xml;base64,${btoa(svg)}`;
}
const backgroundImage = generateSVGBackground('这是一个动态生成的水印文本');
document.getElementById('watermark').style.backgroundImage = `url(${backgroundImage})`;
</script>
在这个示例中,我们定义了一个 generateSVGBackground
函数,该函数接受一个文本参数,并返回一个包含该文本内容的 SVG 图像的 Base64 编码字符串。然后,我们将生成的背景图片应用到 div
元素上,最终实现动态生成背景图片的效果。
实现导出时的复杂水印
只要动态地将这张背景图片添加到思源的图片导出界面里面,就可以实现复杂水印了.
下面这段代码利用 SACPublishHelpper 插件实现了一个新的特殊代码块,当界面加载时,使用语言名为 siyuan-export-watermark
的代码块将会为导出图片功能添加水印:
{
name: "siyuan-export-watermark",
baseLang: "html",
options: {
onregistered: (element, container, content) => {
加载代码块内容("siyuan-export-watermark", async (block) => {
const svgContent = `
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200">
<foreignObject width="180" height="180" >
<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:20px; color: gray;">
${block.content}
</div>
</foreignObject>
</svg>
`;
const encodedSVG = encodeURIComponent(svgContent);
const dataURL = `url("data:image/svg+xml;utf8,${encodedSVG}")`;
const css = `.export-img>.protyle-wysiwyg.protyle-wysiwyg--attr::before{
content:"";
background-image:${dataURL};
background-repeat: repeat;
background-size:25%;
width:100%;
height:100%;
position:absolute;
z-index:1000
}`
const style =document.createElement('style')
style.textContent=css
document.head.appendChild(style)
})
}
}
}
这个发布站点的水印是这样定义的,你可以尝试导出图片来查看它的效果:
<div style="color: pink; opacity: 0.2; font-size: 20px; font-family: Arial;text-align:center">publish.ccsjhn.com 椽承设计</div>
完整效果可以参考 www.ccsjhn.com/?id=20240628023554-snpa1ac
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于