diff --git a/src/BootstrapBlazor.Server/Components/Samples/Watermarks.razor b/src/BootstrapBlazor.Server/Components/Samples/Watermarks.razor index 363b12df64e..96a827d89f2 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Watermarks.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Watermarks.razor @@ -7,6 +7,9 @@
+ @((MarkupString)Localizer["WatermarkDescription"].Value) +
<Layout></Layout>
+<Watermark IsPage="true" Text="BootstrapBlazor" FontSize="20" Color="#ddd" Rotate="-45" Gap="40"></Watermark>
diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 6a3ca8729c3..bc17c834253 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -7017,7 +7017,8 @@ "WatermarkTitle": "Watermark", "WatermarkIntro": "Add specific text or patterns to the page", "WatermarkNormalTitle": "Basic usage", - "WatermarkNormalIntro": "Use the Text property to set a string to specify the watermark text" + "WatermarkNormalIntro": "Use the Text property to set a string to specify the watermark text", + "WatermarkDescription": "

How to add a watermark globally

You can add a watermark component to the template page MainLayout and set IsPage=\"true\"

" }, "BootstrapBlazor.Server.Data.AttributeItem": { "Name": "Name", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index fb44eb5ed32..aa2ff96ebde 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -7017,7 +7017,8 @@ "WatermarkTitle": "Watermark 水印组件", "WatermarkIntro": "在页面上添加文本或图片等水印信息", "WatermarkNormalTitle": "基础用法", - "WatermarkNormalIntro": "使用 Text 属性设置一个字符串指定水印内容" + "WatermarkNormalIntro": "使用 Text 属性设置一个字符串指定水印内容", + "WatermarkDescription": "

全局增加水印实现方法

可以在模板页 MainLayout 中加水印组件并设置 IsPage=\"true\" 即可

" }, "BootstrapBlazor.Server.Data.AttributeItem": { "Name": "参数", diff --git a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.cs b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.cs index 3a05127aa6d..fb7fb15002e 100644 --- a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.cs +++ b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.cs @@ -53,7 +53,14 @@ public partial class Watermark [Parameter] public int? Gap { get; set; } + /// + /// 获得/设置 是否为整页面水印 默认 false + /// + [Parameter] + public bool IsPage { get; set; } + private string? ClassString => CssBuilder.Default("bb-watermark") + .AddClass("is-page", IsPage) .AddClassFromAttributes(AdditionalAttributes) .Build(); @@ -65,6 +72,11 @@ protected override void OnParametersSet() base.OnParametersSet(); Text ??= "BootstrapBlazor"; + + if(IsPage && ChildContent is not null) + { + throw new InvalidOperationException($"{nameof(IsPage)} is true, {nameof(ChildContent)} cannot be set."); + } } /// @@ -95,6 +107,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) Color, Rotate, Gap, - ZIndex + ZIndex, + IsPage }; } diff --git a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.js b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.js index cb24dfc3015..50fe80f35a1 100644 --- a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.js +++ b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.js @@ -71,7 +71,8 @@ const createWatermark = watermark => { fontSize: 16, text: 'BootstrapBlazor', rotate: -40, - color: '#0000004d' + color: '#0000004d', + zIndex: '9999' }; for (const key in options) { @@ -90,31 +91,40 @@ const createWatermark = watermark => { div.style.opacity = '1'; div.style.position = 'absolute'; div.style.inset = '0'; - div.style.zIndex = '9999'; div.classList.add("bb-watermark-bg"); + if (options.zIndex === void 0) { + options.zIndex = defaults.zIndex; + } + div.style.zIndex = options.zIndex; + const mark = el.querySelector('.bb-watermark-bg'); if (mark) { mark.remove(); } - el.appendChild(div); + if (bg.isPage) { + document.body.appendChild(div); + } + else { + el.appendChild(div); + } options.bg = bg; requestAnimationFrame(() => monitor(watermark)); } const monitor = watermark => { - const { el, options, ob } = watermark; + const { el, options } = watermark; if (el === null) { return; } - if (el.children.length !== 2) { + if (options.isPage === false && el.children.length !== 2) { clearWatermark(watermark); return; } - const mark = el.children[1]; + const mark = options.isPage ? el.children[0] : el.children[1]; if (mark.className !== 'bb-watermark-bg') { clearWatermark(watermark); return; @@ -138,7 +148,7 @@ const monitor = watermark => { clearWatermark(watermark); return; } - if (zIndex !== '9999') { + if (zIndex !== options.zIndex) { clearWatermark(watermark); return; } @@ -198,6 +208,6 @@ const getWatermark = props => { return { base64: canvas.toDataURL(), size: canvasSize, - styleSize: canvasSize / devicePixelRatio, + styleSize: canvasSize / devicePixelRatio }; } diff --git a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.scss b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.scss index d2f97f6c411..9c175374e91 100644 --- a/src/BootstrapBlazor/Components/Watermark/Watermark.razor.scss +++ b/src/BootstrapBlazor/Components/Watermark/Watermark.razor.scss @@ -1,3 +1,10 @@ -.bb-watermark { +.bb-watermark { position: relative; + + &.is-page { + position: fixed; + inset: 0; + z-index: 9999; + pointer-events: none; + } } diff --git a/src/BootstrapBlazor/wwwroot/modules/utility.js b/src/BootstrapBlazor/wwwroot/modules/utility.js index 98576bdd756..f824177237d 100644 --- a/src/BootstrapBlazor/wwwroot/modules/utility.js +++ b/src/BootstrapBlazor/wwwroot/modules/utility.js @@ -801,7 +801,7 @@ const deepMerge = (obj1, obj2, skipNull = true) => { } else { const value = obj2[key]; - if (skipNull && value === null) { + if (skipNull && (value === null || value === void 0)) { continue; } obj1[key] = obj2[key]; diff --git a/test/UnitTest/Components/WatermarkTest.cs b/test/UnitTest/Components/WatermarkTest.cs index 7ed8c8effcf..44dd4fa250b 100644 --- a/test/UnitTest/Components/WatermarkTest.cs +++ b/test/UnitTest/Components/WatermarkTest.cs @@ -22,6 +22,17 @@ public void Watermark_Ok() }); cut.MarkupMatches("
Test
"); - cut.SetParametersAndRender(); + var ex = Assert.ThrowsAny(() => cut.SetParametersAndRender(pb => + { + pb.Add(a => a.IsPage, true); + })); + Assert.Equal($"IsPage is true, ChildContent cannot be set.", ex.Message); + + cut.SetParametersAndRender(pb => + { + pb.Add(a => a.IsPage, true); + pb.Add(a => a.ChildContent, (RenderFragment?)null); + }); + cut.MarkupMatches("
"); } }