mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-02-13 10:52:53 +00:00
237 lines
6.7 KiB
JavaScript
237 lines
6.7 KiB
JavaScript
/**
|
|
* @preserve AngularJS PDF viewer directive using pdf.js.
|
|
*
|
|
* https://github.com/akrennmair/ng-pdfviewer
|
|
*
|
|
* MIT license
|
|
*/
|
|
|
|
angular
|
|
.module("ngPDFViewer", [])
|
|
.factory("RecursionHelper", [
|
|
"$compile",
|
|
function($compile) {
|
|
return {
|
|
/**
|
|
* Manually compiles the element, fixing the recursion loop.
|
|
* @param element
|
|
* @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
|
|
* @returns An object containing the linking functions.
|
|
*/
|
|
compile: function(element, link) {
|
|
// Normalize the link parameter
|
|
if (angular.isFunction(link)) {
|
|
link = { post: link };
|
|
}
|
|
|
|
// Break the recursion loop by removing the contents
|
|
var contents = element.contents().remove();
|
|
var compiledContents;
|
|
return {
|
|
pre: link && link.pre ? link.pre : null,
|
|
/**
|
|
* Compiles and re-adds the contents
|
|
*/
|
|
post: function(scope, element) {
|
|
// Compile the contents
|
|
if (!compiledContents) {
|
|
compiledContents = $compile(contents);
|
|
}
|
|
// Re-add the compiled contents to the element
|
|
compiledContents(scope, function(clone) {
|
|
element.append(clone);
|
|
});
|
|
|
|
// Call the post-linking function, if any
|
|
if (link && link.post) {
|
|
link.post.apply(null, arguments);
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|
|
},
|
|
])
|
|
.directive("pdfpageviewer", [
|
|
function() {
|
|
return {
|
|
restrict: "E",
|
|
template: "<canvas></canvas>",
|
|
scope: {
|
|
onPageLoad: "=",
|
|
page: "=",
|
|
pdfDoc: "=",
|
|
},
|
|
controller: [
|
|
"$scope",
|
|
"$element",
|
|
function($scope, $element) {
|
|
$scope.scale = 1.0;
|
|
const canvas = $element.find("canvas")[0];
|
|
|
|
$scope.$watch("pdfDoc", (pdfDoc) => {
|
|
if (pdfDoc) {
|
|
$scope.renderPage($scope.page);
|
|
}
|
|
});
|
|
|
|
$scope.renderPage = async function(num) {
|
|
const page = await $scope.pdfDoc.getPage(num);
|
|
const ratio =
|
|
$element[0].clientWidth / page.getViewport(1.0).width;
|
|
|
|
const viewport = page.getViewport(ratio);
|
|
canvas.height = viewport.height;
|
|
canvas.width = viewport.width;
|
|
|
|
const ctx = canvas.getContext("2d");
|
|
await page.render({ canvasContext: ctx, viewport: viewport });
|
|
if ($scope.onPageLoad) {
|
|
$scope.$apply(function() {
|
|
$scope.onPageLoad({
|
|
page: $scope.page,
|
|
total: $scope.pdfDoc.numPages,
|
|
});
|
|
});
|
|
}
|
|
return true;
|
|
};
|
|
},
|
|
],
|
|
};
|
|
},
|
|
])
|
|
.directive("pdfviewer", [
|
|
"RecursionHelper",
|
|
function(RecursionHelper) {
|
|
var instance_id = null;
|
|
|
|
return {
|
|
restrict: "E",
|
|
template:
|
|
"<pdfpageviewer ng-repeat='p in [].constructor(pdfDoc.numPages) track by $index' page='$index + 1' pdf-doc='pdfDoc'></pdfpageviewer>",
|
|
scope: {
|
|
onPageLoad: "&",
|
|
loadProgress: "&",
|
|
src: "@",
|
|
id: "=",
|
|
},
|
|
compile: function(element) {
|
|
return RecursionHelper.compile(element);
|
|
},
|
|
controller: [
|
|
"$scope",
|
|
function($scope) {
|
|
$scope.pdfDoc = null;
|
|
$scope.scale = 1.0;
|
|
|
|
$scope.documentProgress = function(progressData) {
|
|
if ($scope.loadProgress) {
|
|
$scope.loadProgress({
|
|
state: "loading",
|
|
loaded: progressData.loaded,
|
|
total: progressData.total,
|
|
});
|
|
}
|
|
};
|
|
|
|
$scope.loadPDF = function(path) {
|
|
PDFJS.getDocument(path, null, null, $scope.documentProgress).then(
|
|
function(_pdfDoc) {
|
|
$scope.$apply(() => {
|
|
$scope.pdfDoc = _pdfDoc;
|
|
});
|
|
if ($scope.loadProgress) {
|
|
$scope.loadProgress({
|
|
state: "finished",
|
|
loaded: 0,
|
|
total: 0,
|
|
});
|
|
}
|
|
},
|
|
function(message, exception) {
|
|
console.log("PDF load error: " + message);
|
|
if ($scope.loadProgress) {
|
|
$scope.loadProgress({
|
|
state: "error",
|
|
loaded: 0,
|
|
total: 0,
|
|
});
|
|
}
|
|
}
|
|
);
|
|
};
|
|
|
|
$scope.$on("pdfviewer.nextPage", function(evt, id) {
|
|
if (id !== instance_id) {
|
|
return;
|
|
}
|
|
|
|
if ($scope.pageNum < $scope.pdfDoc.numPages) {
|
|
$scope.pageNum++;
|
|
$scope.renderPage($scope.pageNum);
|
|
}
|
|
});
|
|
|
|
$scope.$on("pdfviewer.prevPage", function(evt, id) {
|
|
if (id !== instance_id) {
|
|
return;
|
|
}
|
|
|
|
if ($scope.pageNum > 1) {
|
|
$scope.pageNum--;
|
|
$scope.renderPage($scope.pageNum);
|
|
}
|
|
});
|
|
|
|
$scope.$on("pdfviewer.gotoPage", function(evt, id, page) {
|
|
if (id !== instance_id) {
|
|
return;
|
|
}
|
|
|
|
if (page >= 1 && page <= $scope.pdfDoc.numPages) {
|
|
$scope.pageNum = page;
|
|
$scope.renderPage($scope.pageNum);
|
|
}
|
|
});
|
|
|
|
$scope.$watch("src", () => {
|
|
$scope.loadPDF($scope.src);
|
|
});
|
|
},
|
|
],
|
|
};
|
|
},
|
|
])
|
|
.service("PDFViewerService", [
|
|
"$rootScope",
|
|
function($rootScope) {
|
|
var svc = {};
|
|
svc.nextPage = function() {
|
|
$rootScope.$broadcast("pdfviewer.nextPage");
|
|
};
|
|
|
|
svc.prevPage = function() {
|
|
$rootScope.$broadcast("pdfviewer.prevPage");
|
|
};
|
|
|
|
svc.Instance = function(id) {
|
|
var instance_id = id;
|
|
|
|
return {
|
|
prevPage: function() {
|
|
$rootScope.$broadcast("pdfviewer.prevPage", instance_id);
|
|
},
|
|
nextPage: function() {
|
|
$rootScope.$broadcast("pdfviewer.nextPage", instance_id);
|
|
},
|
|
gotoPage: function(page) {
|
|
$rootScope.$broadcast("pdfviewer.gotoPage", instance_id, page);
|
|
},
|
|
};
|
|
};
|
|
|
|
return svc;
|
|
},
|
|
]);
|