以下の通りみたい。 moveable によるmouseによる移動、回転、拡大/縮小にも対応しています
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <input type="file" id="pdf_file" accept=".pdf"> <div id="image"> <img src=""> </div> <script src="//daybrush.com/moveable/release/latest/dist/moveable.min.js"> </script> <script src="//mozilla.github.io/pdf.js/build/pdf.js"></script> <script src="pdf2img.js"></script> <script> pdfjsLib.GlobalWorkerOptions.workerSrc = "//mozilla.github.io/pdf.js/build/pdf.worker.js"; document.querySelector("#pdf_file").addEventListener("change",(event)=>{ on_change_file_elm(event); }); let on_change_file_elm =async(event)=>{ if(event.target.files.length==0 ) return; let img_container = document.querySelector("#image"); while (img_container.firstChild) { img_container.removeChild(img_container.firstChild); } // 1ページ目のみ処理 let pdf_file = event.target.files[0]; const image = await pdf_to_img(pdf_file,144); let img_elm = document.createElement("img"); img_elm.src =URL.createObjectURL(image); img_container.append(img_elm); // mouseによるサイズ変更や回転等を可能に add_event_movable( img_elm ); event.target.value =""; }; let add_event_movable=(img_elm)=>{ const moveable = new Moveable(document.body, { target: document.querySelector("#image img"), draggable: true, resizable: true, keepRatio: true, rotatable: true }); moveable.on("drag", ({ target, transform }) => { target.style.transform = transform; }); moveable.on("resize", ({ target, width, height }) => { target.style.width = width + "px"; target.style.height = height + "px"; }); moveable.on("rotate", ({ target, transform }) => { target.style.transform = transform }); } let pdf_to_img=async(file,resolution)=>{ let ext = "png"; let type = "image/png"; const filename = file.name.replace(/\.\w+$/,ext); const DPI = resolution || 96; const pdfjsParams = {data: await file.arrayBuffer(), cMapPacked: true }; const pdf = await pdfjsLib.getDocument(pdfjsParams).promise; // page 1のみ処理 const page = await pdf.getPage(1); const viewParams = { scale: DPI / 96 }; const viewport = page.getViewport(viewParams); const canvas_height = viewport.height * viewParams.scale; const canvas_width = viewport.width * viewParams.scale; let done =()=>false; // chromeやfirefoxは OffscreenCanvasを使用 let canvas; if('OffscreenCanvas' in window){ canvas = new OffscreenCanvas(canvas_width,canvas_height); } else { canvas = document.createElement('canvas'); canvas.width = canvas_width; canvas.height = canvas_height; canvas.style.display = 'none'; document.body.append(canvas); // 後始末用のcall back done=()=>canvas.remove(); } // canvasにpageをレンダリング const renderParams = { canvasContext: canvas.getContext('2d'), transform: [ viewParams.scale, 0, 0, viewParams.scale, 0, 0], viewport: viewport, intent: "print" }; await page.render(renderParams).promise; // canvasに描画されたPDFをBlob(File)に変換 const fileParams = { 'lastModified': new Date().getTime(), type }; const rv = new File( [await blob_from_canvas(canvas,type)], filename, fileParams ); done(); return rv; } let blob_from_canvas=(canvas,type,quality)=>{ if(!type) type = 'image/png'; if(!quality) quality = '0.8'; if(canvas.constructor.name === 'OffscreenCanvas'){ return canvas.convertToBlob({ type,quality }); } return new Promise(function(resolve) { canvas.toBlob(resolve,type,quality); }); } </script> </body> </html>