<!DOCTYPE html>
<html>

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta charset="utf-8" />
    <title>PDF 预览、水印、缩放、旋转</title>

    <!-- <script src="https://npm.elemecdn.com/pdfjs-dist@2.5.570/build/pdf.min.js"></script> -->
    <script src="https://npm.elemecdn.com/pdfjs-dist@2.7.570/es5/build/pdf.min.js"></script>
</head>

<body>
    <h3 style="text-align:center">可拖拽 PDF文件打开,支持 #URL 打开链接</h3>
    <div class="nr-tool">
        <select class="nr-size">
            <option value="0.5">0.5 倍</option>
            <option value="0.75">0.75 倍</option>
            <option value="1.0" selected>缩放比例</option>
            <option value="1.5">1.5 倍</option>
            <option value="2.0">2 倍</option>
            <option value="4.0">4 倍</option>
        </select>
        <br/>
        <select class="nr-watermark">
            <option value="1">开启水印</option>
            <option value="0">关闭水印</option>
        </select>
        <br/>
        <select class="nr-spin">
            <option value="0">旋转角度</option>
            <option value="90">旋转 90</option>
            <option value="180">旋转 180</option>
            <option value="270">旋转 270</option>
        </select>
    </div>


    <div class="nr-pdf-viewer"></div>
</body>

</html>
var pv = {
    pdfViewer: document.querySelector(".nr-pdf-viewer"),
    pdfDocument: null,
    loadUrl: function (url) {
        pdfjsLib.getDocument(url).promise.then(function (pdfDocument) {
            pv.pdfDocument = pdfDocument;
            pv.renderDocument(pv.pdfDocument);
        }).catch(function (reason) {
            console.error(reason);
        })
    },
    renderDocument: function (pdfDocument) {
        pv.pdfViewer.innerHTML = "";

        //总页数
        let pageCount = pdfDocument.numPages;

        var nrwm = document.querySelector('.nr-watermark');

        //构建空页
        for (var i = 0; i < pageCount; i++) {

            //页
            let div = document.createElement("div");
            div.className = "nr-pdf-page";
            div.id = "nr-pdf-page-" + (i + 1);
            div.innerHTML = '<canvas></canvas>';

            //水印
            if (nrwm.value == "1") {
                div.appendChild(wm.two());
            }

            //换行
            let nl = document.createElement("div");
            nl.className = "nr-newline";

            pv.pdfViewer.appendChild(div);
            pv.pdfViewer.appendChild(nl);
        }

        for (let pageIndex = 1; pageIndex <= pageCount; pageIndex++) {

            pdfDocument.getPage(pageIndex).then(function (pdfPage) {
                let canvas = document.getElementById("nr-pdf-page-" + pageIndex).firstChild;

                const viewport = pdfPage.getViewport({ scale: document.querySelector('.nr-size').value * 1 });
                canvas.width = viewport.width;
                canvas.height = viewport.height;
                const ctx = canvas.getContext("2d");
                const renderTask = pdfPage.render({
                    canvasContext: ctx,
                    viewport,
                });
                return renderTask.promise;
            });

        }
    },
    base64ToUint8Array: function (base64) {
        var raw = atob(base64);
        var uint8Array = new Uint8Array(raw.length);
        for (var i = 0; i < raw.length; i++) {
            uint8Array[i] = raw.charCodeAt(i);
        }
        return uint8Array;
    },
    receiveFiles: function (fn) {
        //拖拽
        "dragleave dragenter dragover".split(' ').forEach(en => {
            document.addEventListener(en, function (e) {
                e.stopPropagation();
                e.preventDefault();
            })
        })
        document.addEventListener("drop", function (e) {
            e.preventDefault();

            var files = (e.dataTransfer || e.originalEvent.dataTransfer).files;
            if (files && files.length) {
                fn(files);
            }
        })
    }
}

pv.loadUrl("https://s1.netnr.com/2019/07/06/181724f50f.pdf");
pv.receiveFiles(function (files) {
    var file = files[0];
    if (file.type == "application/pdf") {
        var r = new FileReader();
        r.onload = function (e) {
            pv.loadUrl(pv.base64ToUint8Array(e.target.result.split(',').pop()));
        }
        r.readAsDataURL(file);
    }
});
window.onhashchange = function () {
    var url = location.hash.substring(1);
    if (url.includes("://")) {
        pv.loadUrl(url);
    }
}
document.querySelector('.nr-size').onchange = function () {
    pv.renderDocument(pv.pdfDocument);
}
document.querySelector('.nr-watermark').onchange = function () {
    pv.renderDocument(pv.pdfDocument);
}
document.querySelector('.nr-spin').onchange = function () {
    console.log(this.value)
    pv.pdfViewer.classList.remove("nr-spin-90")
    pv.pdfViewer.classList.remove("nr-spin-180")
    pv.pdfViewer.classList.remove("nr-spin-270")
    if (this.value != "0") {
        pv.pdfViewer.classList.add('nr-spin-' + this.value);
    }
}

var wm = {
    two: function () {
        var wmbox = document.createElement('div');
        wmbox.className = "wm wm2";
        wmbox.innerHTML = `
                            <table>
                                <tr>
                                    <td colspan="2"><img class="wm-icon" src="https://img11.360buyimg.com/ddimg/jfs/t1/172605/23/10640/69151/60a7aaa7Eb219c62e/73fcbb83d4a2db76.png" /><div class="wm-title">计量章CALIBRATION</div></td>
                                </tr>
                                <tr>
                                    <td>位置 LOCATION</td>
                                    <td></td>
                                </tr>
                                <tr>
                                    <td>计量结果 CAL RESULT</td>
                                    <td>合格PASS/不合格FAIL</td>
                                </tr>
                                <tr>
                                    <td>发布标签 DECAL ISSUED</td>
                                    <td>是YES/否NO</td>
                                </tr>
                                <tr>
                                    <td>系统更新 SYSTEM UPDATED</td>
                                    <td>是YES/否NO</td>
                                </tr>
                                <tr>
                                    <td>日期 DATE</td>
                                    <td></td>
                                </tr>
                                <tr>
                                    <td>签字 SIGNATURE</td>
                                    <td><div><img class="wm-sign" src="https://img10.360buyimg.com/ddimg/jfs/t1/196646/31/4138/28688/60a7aaa7E8a3d9042/c1f79bcc2afe5ebc.png" /></div></td>
                                </tr>
                            </table>
                            <div class="wm-footer">XFQA-D001-010(23/11/2018)</div>
                                        `;
        return wmbox;
    }
}
.nr-tool {
    position: fixed;
    top: 10%;
    right: 1.5%;
    z-index: 1;
    line-height: 2em;
}
.nr-pdf-viewer {
    text-align: center;
}

.nr-pdf-viewer .nr-pdf-page {
    position: relative;
    display: inline-block;
}

.nr-pdf-viewer .nr-pdf-page canvas {
    max-width: 100%;
    margin: 10px auto;
    border: 1px solid #ddd;
}

.nr-newline {
    clear: both;
}

.nr-spin-90 .nr-pdf-page {
    transform: rotate(90deg);
}
.nr-spin-180 .nr-pdf-page {
    transform: rotate(180deg);
}
.nr-spin-270 .nr-pdf-page {
    transform: rotate(270deg);
}

.wm {
    position: absolute;
    z-index: 1;
    top: 50px;
    right: 50px;
    overflow: hidden;
    pointer-events: none;
}

.wm2 {
    opacity: 0.5;
    max-width: 80%;
    color: #ff0000;
    font-weight: 600;
    font-size: 1.2rem;
    font-family: "宋体";
    margin: 15% 0 0 40%;
    letter-spacing: -2px;
    transform: rotate(-5deg);
    text-shadow: #ff0000 1px 0 0, #ff0000 0 1px 0, #ff0000 -1px 0 0,
        #ff0000 0 -1px 0;
}

@media screen and (max-width: 500px) {
    .wm2 {
        font-size: 1.1vw;
    }
}
.wm2 > table {
    border-collapse: collapse;
}
.wm2 > table tr td {
    text-align: left;
    position: relative;
    white-space: nowrap;
    padding: 3px 6px 0 3px;
    border: 5px solid #ff0000;
}

.wm2 .wm-icon {
    height: 25px;
}

.wm2 .wm-title {
    font-size: 2rem;
    text-align: center;
}

.wm2 .wm-sign {
    position: absolute;
    height: 150px;
    top: -50px;
}

.wm2 .wm-footer {
    text-align: left;
    padding-top: 10px;
    white-space: nowrap;
    letter-spacing: -2px;
}