console
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.staticfile.net/pdf.js/3.9.179/pdf.worker.js';
(function(){
var vew = $('#id-page'),
upl = document.getElementById('i_file'),
now = document.getElementById('s_now'), v_n = 1,
bp = document.getElementById('b_pre'),
bn = document.getElementById('b_next'),
isc = $('#i_scale'),
total = document.getElementById('s_total'), v_t = 1;
var pdfData;
function pdf_view(){
var scale = isc.val(), loadingTask = pdfjsLib.getDocument(pdfData);
vew.html('<span>加载pdf...</span>');
upl.disabled = true;
loadingTask.promise.then(function(pdf) {
vew.html('');
total.innerText = v_t = pdf.numPages;
now.innerText = v_n = 1;
bp.disabled = true; bn.disabled = v_t == 1;
for(let i = 1; i <= v_t; i ++){
pdf.getPage(i).then(function(page) {
var canvas = document.createElement('canvas');
var viewport = page.getViewport({scale: scale});
canvas.id = 'pdf-v-'+i;
canvas.height = viewport.height; canvas.width = viewport.width;
var renderContext = { canvasContext: canvas.getContext('2d'), viewport: viewport };
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
vew.append(canvas); if(i>=v_t){ upl.disabled = false; }
});
});
}
}, function (err) { vew.text(JSON.stringify(err)); });
}
let b_s = false;
vew.on('scroll', function(evn) {
if(b_s){ return; }
var el = evn.target, p = parseInt((el.scrollHeight-el.clientHeight)/v_t),
v = parseInt(el.scrollTop/p)+1;
if(v_n == v || v > v_t){ return; }
now.innerText = v_n = v;
});
function nextPage(ind = 1){
var v = v_n + ind; if(1 > v || v > v_t){ return; }
now.innerText = v_n = v;
bp.disabled = v == 1; bn.disabled = v == v_t;
b_s = true; setTimeout(()=>{ b_s = false; },500);
setTimeout(()=>{
document.getElementById('pdf-v-'+v).scrollIntoView({behavior:'smooth'});
},100)
}
isc.on('change',function(event){ pdf_view(); })
isc.on('wheel',function(event){})
bp.addEventListener('click', function(event) { nextPage(-1); })
bn.addEventListener('click', function(event) { nextPage(1); })
upl.addEventListener('change', function(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) { pdfData = e.target.result; pdf_view(); };
reader.onerror = function(err) { vew.text(JSON.stringify(err)); };
}
});
pdfData = {data: atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G')};
pdf_view();
function screenImg(viewId,canvasId){
const vid = $(viewId), h_up = $('#cross-up'), h_down = $('#cross-down');
const vsc = $(canvasId), v2d = vsc[0].getContext('2d');
vid.on('mousemove', function(evn) {
h_up.css({'left': (evn.clientX-55) + 'px','top': (evn.clientY-55) + 'px'});
h_down.css({'left': evn.clientX + 'px','top': evn.clientY + 'px'});
h_up.html('x:'+evn.clientX+'<br>y:'+evn.clientY);
});
let ot = {x:0, y:0, w:1, h:1, t:0, l:0,ox:0,oy:0}, screening = false, canvas;
let sc = $('#screen-id'), scp = sc.find('span');
var clearCanvas = function(){
if(!canvas){ return; }
screening = false;
canvas.off('mousemove');
canvas == undefined;
}
vid.on('mouseout', clearCanvas);
vid.on('mouseup', clearCanvas);
let upd = function (){
sc.css({width: ot.w + 'px', height: ot.h + 'px', left: ot.l + 'px', top: ot.t + 'px'});
}
vid.on('mousedown',function(env){
let tg = $(env.target);
if(!tg.is('canvas')){ return; }
canvas = tg;
screening = true;
ot.x = env.clientX; ot.y = env.clientY; ot.ox = env.offsetX; ot.oy = env.offsetY;
tg.on('mousemove',function(e){
if(!screening){ return; }
let cx = e.clientX, cy = e.clientY;
if( cx >= ot.x ){ ot.w = cx - ot.x ; ot.l = ot.x; }else{ ot.w = ot.x - cx ; ot.l = cx; }
if( cy >= ot.y ){ ot.h = cy - ot.y ; ot.t = ot.y; }else{ ot.h = ot.y - cy ; ot.t = cy; }
upd();
let x = cx >= ot.x?ot.ox:e.offsetX, y = cy >= ot.y?ot.oy:e.offsetY;
v2d.clearRect(0, 0, vsc.width(), vsc.height());
vsc.attr({width: ot.w, height: ot.h});
v2d.drawImage(canvas[0], x, y, ot.w, ot.h, 0, 0, ot.w, ot.h);
scp.text('w:'+ot.w+',y:'+ot.h);
})
sc.css('display', 'block');
});
sc.find('button').on('click',function(){
var imgURL = vsc[0].toDataURL({format: "image/png", quality:1});
var dlLink = document.createElement('a');
dlLink.download = '图片下载-'+ (new Date().getTime()) + '.png';
dlLink.href = imgURL;
document.body.appendChild(dlLink);
dlLink.click();
document.body.removeChild(dlLink);
});
}
screenImg('#id-page','#view_screen');
})()
<div>
<input type="file" id="i_file" accept="application/pdf" placeholder="请选择PDF文件"/>
<button type="button" id="b_pre">上一页</button>
当前:<span id="s_now">1</span>/<span id="s_total">1</span>
<button type="button" id="b_next">下一页</button>
<input type="number" id="i_scale" min="0.5" max="5" step="0.1" value="1.5">缩放</input>
</div>
<div id="id-page" class="page-view">预览区域</div>
<div>
<canvas id="view_screen" width="300" height="200" style="border: 1px solid black;"/>
</div>
<div>
<div id="cross-up" class="crosshair hair-up" style="left: -45px;top: 30px;"></div>
<div id="cross-down" class="crosshair hair-down" style="left: 10px;top: 85px;"></div>
<div id="screen-id" class="screen-div" style="width: 0px;height: 0px;">
<span style="top:-22px;position:absolute;color:red"></span>
<div style="bottom:-25px;position:absolute;min-width:50px">
<button type="button">下载</button>
</div>
</div>
</div>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.page-view {
border: 1px solid black;
width: 95%;
height: 60%;
overflow: auto;
padding: 5px;
}
canvas {
margin: 5px 0;
}
.crosshair {
position: absolute;
width: 55px;
height: 55px;
background-color: transparent;
pointer-events: none;
z-index: 1000;
}
.hair-up {
color: gray;
text-align-last: right;
border-right: 1px dashed gray;
border-bottom: 1px dashed gray;
}
.hair-down {
border-left: 1px dashed gray;
border-top: 1px dashed gray;
}
.screen-div {
position: absolute;
width: 0px;
height: 0px;
display: none;
z-index: 1000;
background-color: transparent;
pointer-events: none;
border: 1px dashed red;
}