Skip to content

Commit 1423d1f

Browse files
authored
feat(PdfReader): add width observer function (#743)
* refactor: 删除不使用的样式 * refactor: 增加 loadPdf 方法 * feat(PdfReader): add width observer function * chore: bump version 10.0.4-beta03
1 parent 7223519 commit 1423d1f

6 files changed

Lines changed: 141 additions & 82 deletions

File tree

src/components/BootstrapBlazor.PdfReader/BootstrapBlazor.PdfReader.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>10.0.4-beta02</Version>
4+
<Version>10.0.4-beta03</Version>
55
</PropertyGroup>
66

77
<PropertyGroup>

src/components/BootstrapBlazor.PdfReader/PdfReader.razor

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,36 @@
33
@inherits BootstrapModuleComponentBase
44

55
<div @attributes="@AdditionalAttributes" id="@Id" class="@ClassString" style="@StyleString">
6-
<div class="bb-view-toolbar">
7-
@if (ShowToolbar)
8-
{
9-
<div class="bb-view-title">
6+
@if (ShowToolbar)
7+
{
8+
<div class="bb-view-toolbar">
9+
<div class="bb-view-group bb-view-title">
1010
@if (EnableThumbnails)
1111
{
1212
<div class="bb-view-icon bb-view-bar" title="@Localizer["ToggleSidebar"]"><i class="fa-solid fa-bars"></i></div>
1313
}
1414
<span class="bb-view-subject">@_docTitle</span>
1515
</div>
1616
<div class="@ViewBodyString">
17-
<input type="text" class="bb-view-num" @bind="CurrentPageString" /><span class="bb-view-slash">/</span>
18-
<div class="bb-view-pagesCount"></div>
19-
<div class="bb-view-divider"></div>
20-
<div class="bb-view-icon bb-page-minus" title="@Localizer["ZoomOut"]"><i class="fa-solid fa-fw fa-minus"></i></div>
21-
<input type="text" class="bb-view-scale-input" @bind="CurrentScaleString" />
22-
<div class="bb-view-icon bb-page-plus" title="@Localizer["ZoomIn"]"><i class="fa-solid fa-fw fa-plus"></i></div>
23-
<div class="bb-view-scale">
17+
<div class="bb-view-group bb-view-group-page">
18+
<input type="text" class="bb-view-num" @bind="CurrentPageString" /><span class="bb-view-slash">/</span>
19+
<div class="bb-view-pagesCount"></div>
20+
</div>
21+
<div class="bb-view-group bb-view-group-scale">
22+
<div class="bb-view-divider"></div>
23+
<div class="bb-view-icon bb-page-minus" title="@Localizer["ZoomOut"]"><i class="fa-solid fa-fw fa-minus"></i></div>
24+
<input type="text" class="bb-view-scale-input" @bind="CurrentScaleString" />
25+
<div class="bb-view-icon bb-page-plus" title="@Localizer["ZoomIn"]"><i class="fa-solid fa-fw fa-plus"></i></div>
26+
</div>
27+
<div class="bb-view-group bb-view-group-rotate">
2428
<div class="bb-view-divider"></div>
2529
<div class="bb-view-icon btn-group">
2630
<button type="button" class="btn bb-view-fit-height" title="@Localizer["FitHeight"]" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)"><i class="fa-solid fa-fw fa-arrows-left-right-to-line fa-rotate-90"></i></button>
2731
<button type="button" class="btn bb-view-fit-width" title="@Localizer["FitWidth"]" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)"><i class="fa-solid fa-fw fa-arrows-left-right-to-line"></i></button>
2832
<button type="button" class="btn dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
2933
<span class="visually-hidden">Toggle Dropdown</span>
3034
</button>
31-
<div class="dropdown-menu dropdown-menu-end">
35+
<div class="dropdown-menu dropdown-menu-end shadow">
3236
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageActual)">@Localizer["PageActual"]</div>
3337
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageWidth)">@Localizer["FitWidth"]</div>
3438
<div class="dropdown-item" @onclick="() => SetFitMode(PdfReaderFitMode.PageHeight)">@Localizer["FitHeight"]</div>
@@ -38,7 +42,7 @@
3842
<div class="bb-view-icon bb-view-fit-rotate" title="@Localizer["RotateRight"]" @onclick="RotateRight"><i class="fa-solid fa-fw fa-rotate-right"></i></div>
3943
</div>
4044
</div>
41-
<div class="bb-view-controls">
45+
<div class="bb-view-group bb-view-controls">
4246
@if (ShowDownload)
4347
{
4448
<div class="bb-view-icon bb-view-download" title="@Localizer["Download"]" @onclick="OnDownload"><i class="fa-solid fa-fw fa-arrow-right-to-bracket fa-rotate-90"></i></div>
@@ -51,7 +55,7 @@
5155
<button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown">
5256
<i class="@MoreButtonIcon"></i>
5357
</button>
54-
<div class="dropdown-menu shadow dropdown-menu-end bb-view-dropdown-menu">
58+
<div class="dropdown-menu shadow dropdown-menu-end">
5559
@if (ShowTwoPagesOneView)
5660
{
5761
<div class="dropdown-item dropdown-item-pages">
@@ -79,8 +83,8 @@
7983
</div>
8084
</div>
8185
</div>
82-
}
83-
</div>
86+
</div>
87+
}
8488
<div class="bb-view-main">
8589
@if (EnableThumbnails)
8690
{

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public partial class PdfReader
135135
.AddClassFromAttributes(AdditionalAttributes)
136136
.Build();
137137

138-
private string? ViewBodyString => CssBuilder.Default("bb-view-body")
138+
private string? ViewBodyString => CssBuilder.Default("bb-view-group bb-view-toolbar-main")
139139
.AddClass("fit-width", FitMode == PdfReaderFitMode.PageHeight)
140140
.Build();
141141

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@
2727
--bs-dropdown-link-active-color: var(--bs-dropdown-color);
2828
}
2929

30-
.bb-view-title {
30+
.bb-view-group {
3131
display: flex;
3232
align-items: center;
3333
flex-wrap: nowrap;
34+
}
35+
36+
.bb-view-title {
3437
padding: 0 1rem;
3538
}
3639

@@ -69,26 +72,22 @@
6972
padding-inline-end: .5rem;
7073
}
7174

72-
.bb-view-body {
75+
.bb-view-toolbar-main {
76+
justify-content: center;
7377
flex: 1;
7478
min-width: 0;
7579
width: 1%;
76-
display: flex;
77-
flex-wrap: nowrap;
78-
align-items: center;
79-
justify-content: center;
80-
background-color: var(--bb-toolbar-background-color);
8180
}
8281

83-
.bb-view-body.fit-width .bb-view-fit-height {
82+
.bb-view-toolbar-main.fit-width .bb-view-fit-height {
8483
display: none;
8584
}
8685

87-
.bb-view-body.fit-width .bb-view-fit-width {
86+
.bb-view-toolbar-main.fit-width .bb-view-fit-width {
8887
display: block;
8988
}
9089

91-
.bb-view-body .bb-view-fit-width {
90+
.bb-view-toolbar-main .bb-view-fit-width {
9291
display: none;
9392
}
9493

@@ -125,9 +124,6 @@
125124
}
126125

127126
.bb-view-controls {
128-
display: flex;
129-
align-items: center;
130-
justify-content: center;
131127
padding: 0 1rem;
132128
}
133129

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js

Lines changed: 110 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,10 @@ export async function init(id, invoke, options) {
2020
return;
2121
}
2222

23-
const loadingTask = pdfjsLib.getDocument(options);
24-
loadingTask.onProgress = function (progressData) {
25-
26-
};
27-
28-
loadingTask.onPassword = function (updatePassword, reason) {
29-
if (reason === pdfjsLib.PasswordResponses.NEED_PASSWORD) {
30-
31-
}
32-
else if (reason === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) {
33-
34-
}
35-
};
36-
37-
const container = el.querySelector(".bb-view-container");
38-
const eventBus = new pdfjsViewer.EventBus();
39-
const pdfViewer = new pdfjsViewer.PDFViewer({
40-
container,
41-
eventBus
42-
});
43-
44-
addEventListener(el, pdfViewer, eventBus, invoke, options);
45-
46-
const pdfDocument = await loadingTask.promise;
47-
pdfViewer.setDocument(pdfDocument);
23+
const pdfViewer = await loadPdf(el, invoke, options);
24+
const observer = setObserver(el);
4825

49-
Data.set(id, { el, pdfViewer });
26+
Data.set(id, { el, pdfViewer, observer });
5027
}
5128

5229
export function setScaleValue(id, value) {
@@ -86,6 +63,107 @@ export function resetThumbnails(id) {
8663
}
8764
}
8865

66+
const loadPdf = async (el, invoke, options) => {
67+
const loadingTask = pdfjsLib.getDocument(options);
68+
loadingTask.onProgress = function (progressData) {
69+
70+
};
71+
72+
loadingTask.onPassword = function (updatePassword, reason) {
73+
if (reason === pdfjsLib.PasswordResponses.NEED_PASSWORD) {
74+
75+
}
76+
else if (reason === pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) {
77+
78+
}
79+
};
80+
81+
const container = el.querySelector(".bb-view-container");
82+
const eventBus = new pdfjsViewer.EventBus();
83+
const pdfViewer = new pdfjsViewer.PDFViewer({
84+
container,
85+
eventBus
86+
});
87+
88+
addEventListener(el, pdfViewer, eventBus, invoke, options);
89+
90+
const pdfDocument = await loadingTask.promise;
91+
pdfViewer.setDocument(pdfDocument);
92+
93+
return pdfViewer;
94+
}
95+
96+
const setObserver = el => {
97+
const title = el.querySelector(".bb-view-title");
98+
const subject = el.querySelector(".bb-view-subject");
99+
const groupPage = el.querySelector(".bb-view-group-page");
100+
const groupScale = el.querySelector(".bb-view-group-scale");
101+
const groupRotate = el.querySelector(".bb-view-group-rotate");
102+
const controls = el.querySelector(".bb-view-controls");
103+
104+
el.widths = [subject.offsetWidth, groupRotate.offsetWidth, groupScale.offsetWidth, groupPage.offsetWidth, controls.offsetWidth];
105+
106+
const increaseSpace = toolbar => {
107+
if (controls.classList.contains('d-none')) {
108+
if (title.offsetWidth + el.widths[4] + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth < toolbar.offsetWidth) {
109+
controls.classList.remove("d-none");
110+
}
111+
}
112+
else if (groupPage.classList.contains('d-none')) {
113+
if (title.offsetWidth + el.widths[3] + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth < toolbar.offsetWidth) {
114+
groupPage.classList.remove("d-none");
115+
}
116+
}
117+
else if (groupScale.classList.contains('d-none')) {
118+
if (title.offsetWidth + el.widths[2] + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth < toolbar.offsetWidth) {
119+
groupScale.classList.remove("d-none");
120+
}
121+
}
122+
else if (groupRotate.classList.contains('d-none')) {
123+
if (title.offsetWidth + el.widths[1] + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth < toolbar.offsetWidth) {
124+
groupRotate.classList.remove("d-none");
125+
}
126+
}
127+
else if (subject.classList.contains("d-none")) {
128+
if (title.offsetWidth + el.widths[0] + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth < toolbar.offsetWidth) {
129+
subject.classList.remove("d-none");
130+
}
131+
}
132+
}
133+
const decreaseSpace = toolbar => {
134+
while (title.offsetWidth + groupPage.offsetWidth + groupScale.offsetWidth + groupRotate.offsetWidth + controls.offsetWidth > toolbar.offsetWidth) {
135+
if (subject.classList.contains("d-none") === false) {
136+
subject.classList.add("d-none");
137+
}
138+
else if (groupRotate.classList.contains('d-none') === false) {
139+
groupRotate.classList.add("d-none");
140+
}
141+
else if (groupScale.classList.contains('d-none') === false) {
142+
groupScale.classList.add("d-none");
143+
}
144+
else if (groupPage.classList.contains('d-none') === false) {
145+
groupPage.classList.add("d-none");
146+
}
147+
else if (controls.classList.contains('d-none') === false) {
148+
controls.classList.add("d-none");
149+
}
150+
}
151+
}
152+
153+
const observer = new ResizeObserver(entries => {
154+
const toolbar = el.querySelector(".bb-view-toolbar");
155+
if (toolbar === null) {
156+
return;
157+
}
158+
159+
decreaseSpace(toolbar);
160+
increaseSpace(toolbar);
161+
});
162+
163+
observer.observe(el);
164+
return observer;
165+
}
166+
89167
const addEventListener = (el, pdfViewer, eventBus, invoke, options) => {
90168
eventBus.on("pagesinit", async () => {
91169
if (options.fitMode) {
@@ -303,9 +381,14 @@ const printPdf = url => {
303381
}
304382

305383
export function dispose(id) {
384+
const { el, observer } = Data.get(id);
306385
Data.remove(id);
307386

308-
const el = document.getElementById(id);
387+
if (observer) {
388+
observer.disconnect();
389+
observer = null;
390+
}
391+
309392
if (el) {
310393
const minus = el.querySelector(".bb-page-minus");
311394
const plus = el.querySelector(".bb-page-plus");

src/components/BootstrapBlazor.PdfReader/wwwroot/css/pdf_viewer.css

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -141,30 +141,6 @@
141141
margin-inline: 5px;
142142
}
143143

144-
.pdfViewer .page.loadingIcon::after {
145-
position: absolute;
146-
top: 0;
147-
left: 0;
148-
content: "";
149-
width: 100%;
150-
height: 100%;
151-
background: url("images/loading-icon.gif") center no-repeat;
152-
display: none;
153-
transition-property: display;
154-
transition-delay: var(--loading-icon-delay);
155-
z-index: 5;
156-
contain: strict;
157-
}
158-
159-
.pdfViewer .page.loading::after {
160-
display: block;
161-
}
162-
163-
.pdfViewer .page:not(.loading)::after {
164-
transition-property: none;
165-
display: none;
166-
}
167-
168144
.pdfPresentationMode .pdfViewer {
169145
padding-bottom: 0;
170146
}

0 commit comments

Comments
 (0)