Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
capdiem committed Aug 15, 2024
1 parent e92936c commit 79eb211
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 115 deletions.
205 changes: 106 additions & 99 deletions src/Masa.Blazor.JS/src/proxies/pdf.js/mobile-viewer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import {
build, getDocument, GlobalWorkerOptions, InvalidPDFException, MissingPDFException,
PDFDocumentProxy, shadow, UnexpectedResponseException, version
PDFDocumentProxy, UnexpectedResponseException, version
} from "pdfjs-dist";
import * as pdfjsViewer from "pdfjs-dist/legacy/web/pdf_viewer.mjs";

const MAX_CANVAS_PIXELS = 0; // CSS-only zooming.
const TEXT_LAYER_MODE = 0; // DISABLE
const MAX_IMAGE_SIZE = 1024 * 1024;
// const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
// const CMAP_PACKED = true;

const DEFAULT_SCALE_DELTA = 1.1;
const MIN_SCALE = 0.25;
const MAX_SCALE = 10.0;
const DEFAULT_SCALE_VALUE = "auto";

class PDFViewerApplication {
Expand All @@ -24,24 +17,73 @@ class PDFViewerApplication {
eventBus: any;
value: number;
l10n: pdfjsViewer.GenericL10n;
root: HTMLElement;
previous: HTMLElement;
next: HTMLElement;
zoomInBtn: HTMLElement;
zoomOutBtn: HTMLElement;
container: HTMLDivElement;
viewerDiv: HTMLElement;
pagination: HTMLElement;
maxCanvasPixels: number;
startDistance = 0;

_zoomIn = () => this.zoomIn();

_zoomOut = () => this.zoomOut();

_previousClick = () => this.page--;

_nextClick = () => this.page++;

_touchstart = (e: TouchEvent) => {
if (e.touches.length === 2) {
this.startDistance = getDistance(e.touches);
console.log("touchstart startDistance", this.startDistance);
e.preventDefault();
}
};

_touchmove = (e: TouchEvent) => {
if (e.touches.length === 2) {
const currentDistance = getDistance(e.touches);
if (Math.abs(currentDistance - this.startDistance) > 10) {
const scaleChange = currentDistance / this.startDistance;
this.startDistance = currentDistance;
const origin = getCenter(e.touches);
if (scaleChange > 1) {
this.zoomIn(origin);
} else {
this.zoomOut(origin);
}
}

e.preventDefault();
}
};

_wheel = (e: WheelEvent) => {
if (e.ctrlKey) {
e.preventDefault();

const origin = [e.clientX, e.clientY];

if (e.deltaY < 0) {
this.zoomIn(origin);
} else {
this.zoomOut(origin);
}
}
};

constructor(root: HTMLElement) {
this.root = root;
this.previous = root.querySelector(".previous");
this.next = root.querySelector(".next");
this.zoomInBtn = root.querySelector(".zoomIn");
this.zoomOutBtn = root.querySelector(".zoomOut");
this.container = root.querySelector(".viewerContainer");
constructor(container: HTMLDivElement, maxCanvasPixels: number) {
this.container = container;
this.maxCanvasPixels = maxCanvasPixels;
this.previous = container.querySelector(".previous");
this.next = container.querySelector(".next");
this.zoomInBtn = container.querySelector(".zoomIn");
this.zoomOutBtn = container.querySelector(".zoomOut");
this.viewerDiv = this.container.firstElementChild as HTMLElement;
this.pagination = root.querySelector(".pagination");
this.pagination = container.querySelector(".pagination");

this.pdfLoadingTask = null;
this.pdfDocument = null;
Expand Down Expand Up @@ -166,33 +208,20 @@ class PDFViewerApplication {
this.pdfViewer.currentPageNumber = val;
}

_zoomIn = () => this.zoomIn();
_zoomOut = () => this.zoomOut();
_previousClick = () => this.page--;
_nextClick = () => this.page++;

zoomIn(ticks = undefined) {
let newScale = this.pdfViewer.currentScale;
do {
newScale = Number((newScale * DEFAULT_SCALE_DELTA).toFixed(2));
newScale = Math.ceil(newScale * 10) / 10;
newScale = Math.min(MAX_SCALE, newScale);
} while (--ticks && newScale < MAX_SCALE);
this.pdfViewer.currentScaleValue = newScale.toFixed(2);
zoomIn(origin: any[] = null) {
this.pdfViewer.updateScale({
scaleFactor: 1.1,
origin,
});
}

zoomOut(ticks = undefined) {
let newScale = this.pdfViewer.currentScale;
do {
newScale = Number((newScale / DEFAULT_SCALE_DELTA).toFixed(2));
newScale = Math.floor(newScale * 10) / 10;
newScale = Math.max(MIN_SCALE, newScale);
} while (--ticks && newScale > MIN_SCALE);
this.pdfViewer.currentScaleValue = newScale.toFixed(2);
zoomOut(origin: any[] = null) {
this.pdfViewer.updateScale({
scaleFactor: 0.9,
origin,
});
}

previousPage() {}

initUI() {
const eventBus = new pdfjsViewer.EventBus();
this.eventBus = eventBus;
Expand All @@ -209,7 +238,7 @@ class PDFViewerApplication {
eventBus,
linkService,
l10n: this.l10n,
maxCanvasPixels: MAX_CANVAS_PIXELS,
maxCanvasPixels: this.maxCanvasPixels,
textLayerMode: TEXT_LAYER_MODE,
});
this.pdfViewer = pdfViewer;
Expand All @@ -224,54 +253,30 @@ class PDFViewerApplication {
eventBus.on("pagesinit", () => {
// We can use pdfViewer now, e.g. let's change default scale.
pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
this.pagination.textContent = `${pdfViewer.currentPageNumber} / ${this.pagesCount}`;
if (this.pagination) {
this.pagination.textContent = `${pdfViewer.currentPageNumber} / ${this.pagesCount}`;
}
});

eventBus.on(
"pagechanging",
(evt) => {
const page = evt.pageNumber;
const numPages = this.pagesCount;
this.pagination.textContent = `${page} / ${numPages}`;
if (this.pagination) {
this.pagination.textContent = `${page} / ${numPages}`;
}
},
true
);

// container.firstElementChild.addEventListener(
// "touchstart",
// (e: TouchEvent) => {
// if (e.touches.length === 2) {
// this.startDistance = this.getDistance(e.touches);
// console.log("touchstart startDistance", this.startDistance);
// e.preventDefault();
// }
// },
// { passive: false }
// );

// container.firstElementChild.addEventListener(
// "touchmove",
// (e: TouchEvent) => {
// if (e.touches.length === 2) {
// const currentDistance = this.getDistance(e.touches);
// console.log("touchmove currentDistance", currentDistance);
// const scaleChange = currentDistance / this.startDistance;
// console.log(
// "old this.pdfViewer.currentScaleValue",
// this.pdfViewer.currentScaleValue
// );
// this.pdfViewer.currentScaleValue *= scaleChange;
// console.log(
// "new this.pdfViewer.currentScaleValue",
// this.pdfViewer.currentScaleValue
// );
// this.startDistance = currentDistance;

// e.preventDefault();
// }
// },
// { passive: false }
// );
this.container.addEventListener("touchstart", this._touchstart, {
passive: false,
});

this.container.addEventListener("touchmove", this._touchmove, {
passive: false,
});

this.viewerDiv.addEventListener("wheel", this._wheel);
this.previous &&
Expand All @@ -281,26 +286,9 @@ class PDFViewerApplication {
this.zoomOutBtn && this.zoomOutBtn.addEventListener("click", this._zoomOut);
}

startDistance = 0;

_wheel = (e: WheelEvent) => {
if (e.ctrlKey) {
e.preventDefault();
if (e.deltaY < 0) {
this.zoomIn();
} else {
this.zoomOut();
}
}
};

getDistance(touches) {
const dx = touches[0].pageX - touches[1].pageX;
const dy = touches[0].pageY - touches[1].pageY;
return Math.sqrt(dx * dx + dy * dy);
}

destroy() {
this.container.removeEventListener("touchstart", this._touchstart);
this.container.removeEventListener("touchmove", this._touchstart);
this.viewerDiv.removeEventListener("wheel", this._wheel);

this.previous &&
Expand All @@ -312,8 +300,27 @@ class PDFViewerApplication {
}
}

function init(root: HTMLElement, url: string) {
const pdfViewerApp = new PDFViewerApplication(root);
function getCenter(touches: TouchList) {
const centerX = (touches[0].clientX + touches[1].clientX) / 2;
const centerY = (touches[0].clientY + touches[1].clientY) / 2;
return [centerX, centerY];
}

function getDistance(touches: TouchList) {
const dx = touches[0].pageX - touches[1].pageX;
const dy = touches[0].pageY - touches[1].pageY;
return Math.sqrt(dx * dx + dy * dy);
}

function init(
viewerContainer: HTMLDivElement,
url: string,
maxCanvasPixels: number = 0
) {
const pdfViewerApp = new PDFViewerApplication(
viewerContainer,
maxCanvasPixels
);

GlobalWorkerOptions.workerSrc = new URL(
"./pdf.worker.min.js",
Expand Down
9 changes: 5 additions & 4 deletions src/Masa.Blazor/Components/Pdfjs/MPdfMobileViewer.razor
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
@namespace Masa.Blazor
@inherits MasaComponentBase

<div class="m-pdf-mobile-viewer" @ref="Ref">
<div class="viewerContainer">
<div class="viewer pdfViewer"></div>
<div class="@GetClass()" style="@GetStyle()" id="@Id" @ref="Ref" @attributes="@Attributes">
<div class="viewer pdfViewer"></div>

@if (!HideToolbar)
{
<footer>
@GenBtn("previous", "mdi-arrow-up")
@GenBtn("next", "mdi-arrow-down")
<div class="pagination"></div>
@GenBtn("zoomOut", "mdi-magnify-minus-outline")
@GenBtn("zoomIn", "mdi-magnify-plus-outline")
</footer>
</div>
}
</div>

@code {
Expand Down
29 changes: 28 additions & 1 deletion src/Masa.Blazor/Components/Pdfjs/MPdfMobileViewer.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,41 @@ public partial class MPdfMobileViewer : MasaComponentBase
[EditorRequired]
public string? Url { get; set; }

[Parameter]
public bool HideToolbar { get; set; }

/// <summary>
/// The maximum supported canvas size in
/// total pixels, i.e.width* height. Use `-1` for no limit, or `0` for
/// CSS-only zooming.
/// </summary>
[Parameter]
[MasaApiParameter(0)]
public long MaxCanvasPixels { get; set; } = 0;

private IJSObjectReference? _jsObjectReference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);

if (firstRender)
{
await JsModule.Init(Ref, Url);
_jsObjectReference = await JsModule.Init(Ref, Url, MaxCanvasPixels);
}
}

private static Block Block => new Block("m-pdf-mobile-viewer");
private ModifierBuilder BlockModifierBuilder = Block.CreateModifierBuilder();

protected override IEnumerable<string?> BuildComponentClass()
{
yield return BlockModifierBuilder.Add("has-toolbar", !HideToolbar).AddClass("viewerContainer").Build();
}

protected override async ValueTask DisposeAsyncCore()
{
await _jsObjectReference.TryInvokeVoidAsync("destroy");
}
}

29 changes: 24 additions & 5 deletions src/Masa.Blazor/Components/Pdfjs/MPdfMobileViewer.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
display: none !important;
}

.m-pdf-mobile-viewer .viewerContainer {
.m-pdf-mobile-viewer {
position: absolute;
overflow: auto;
width: 100%;
height: 100%;
}

.m-pdf-mobile-viewer .viewer {
/* overflow: hidden; */
left: 0;
--page-margin: 0 auto;
--page-border: 8px solid transparent;
}

.m-pdf-mobile-viewer canvas {
Expand Down Expand Up @@ -116,3 +115,23 @@
text-align: center;
margin: auto 0;
}

.m-pdf-mobile-viewer footer > .pagination {
flex: 3;
}

.m-pdf-mobile-viewer ::deep .pdfViewer .canvasWrapper > canvas {
width: inherit !important;
}

.m-pdf-mobile-viewer--has-toolbar {
--pdfViewer-padding-bottom: 36px;
}

.m-page-stack-item__content .m-pdf-mobile-viewer--has-toolbar {
--pdfViewer-padding-bottom: calc(36px + var(--m-page-stack-item-bar-height));
}

.m-page-stack-item__content .container .m-pdf-mobile-viewer--has-toolbar {
--pdfViewer-padding-bottom: calc(36px + 12px + var(--m-page-stack-item-bar-height));
}
Loading

0 comments on commit 79eb211

Please sign in to comment.