H5拖拽 构造拖拽及缩放 pdf展示
Posted new Object()
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H5拖拽 构造拖拽及缩放 pdf展示相关的知识,希望对你有一定的参考价值。
前言:
协助项目需要实现一个签名的功能。
功能说明:1.有文本签名和头像签名。2.头像签名需要实现可拖拽功能。3.需要展示的是pdf的文件并需要获取签名位于pdf文件的相对位置。
功能一:实现拖拽
思路:H5拖拽及构造函数实现拖拽及缩放
要点:1.需要设置拖拽元素属性
draggable="true"
2.可拖拽的元素设置ondragstart获取数据
3.对可放置拖拽元素的设置ondragover函数
默认地,无法将数据/元素放置到其他元素中。如果需要设置允许放置,我们必须阻止对元素的默认处理方式。
4.ondrop函数
设置放置后需要执行的方法。
1 /*H5拖拽并复制*/ 2 var moveDemo=null; 3 var _type; 4 var divs=document.querySelectorAll(".left_list li"); 5 var showBox=document.querySelector(".section_main_pdf"); 6 for(var i=0;i<divs.length;i++){ 7 divs[i].ondragstart=function(e){ 8 moveDemo=this.querySelector("img"); 9 _type=this.querySelector(\'.list_name\').innerText; 10 } 11 }; 12 showBox.ondragover =function(e){ 13 e.preventDefault(); 14 //console.log(\'x:\'+ e.pageX+\';y:\'+ e.pageY); 15 }; 16 showBox.ondrop=function(e){ 17 var _clone=moveDemo.cloneNode(); 18 this.append(_clone); 19 console.log(_clone); 20 _clone.className=\'dragIcon\'; 21 $(_clone).css({ 22 \'width\':\'100%\', 23 \'height\':\'100%\' 24 }).attr(\'draggable\',false); 25 $(_clone).wrap(\'<span class="img_outer"></span>\'); 26 if(_type==\'Signature\'){ 27 $(_clone).parent().css({ 28 \'position\':\'absolute\', 29 \'top\': e.pageY, 30 \'left\': e.pageX, 31 \'cursor\':\'move\', 32 \'display\':\'inline-block\', 33 \'border\':\'2px solid\' 34 }).append(\'<span class="iconResize" style="position:absolute;display: inline-block;width: 10px;height: 10px;\' + 35 \'cursor:se-resize;right:-5px;bottom:-5px;background-color:#fff;\' + 36 \'border:2px solid;border-radius:50%"></span>\').attr({ 37 \'data-icon\':\'signature\', 38 \'data-page\':config.defaultPage 39 }); 40 } 41 else if(_type==\'PIN\'){ 42 $(_clone).parent().css({ 43 \'position\':\'absolute\', 44 \'top\': e.pageY, 45 \'left\': e.pageX, 46 \'cursor\':\'move\', 47 \'display\':\'inline-block\', 48 \'border\':\'2px solid\' 49 }).attr({ 50 \'data-icon\':\'pin\', 51 \'data-page\':config.defaultPage 52 }); 53 } 54 };
功能二:构造拖拽及缩放函数
思路:通过获取鼠标事件及元素位置
1 /*构造拖拽及缩放函数*/ 2 $(document).mousemove(function(e) { 3 if (!!this.move) { 4 var posix = !document.move_target ? {\'x\': 0, \'y\': 0} : document.move_target.posix, 5 callback = document.call_down || function() { 6 $(this.move_target).css({ 7 \'top\': e.pageY - posix.y, 8 \'left\': e.pageX - posix.x 9 }); 10 }; 11 callback.call(this, e, posix); 12 } 13 }).mouseup(function(e) { 14 if (!!this.move) { 15 var callback = document.call_up || function(){}; 16 callback.call(this, e); 17 $.extend(this, { 18 \'move\': false, 19 \'move_target\': null, 20 \'call_down\': false, 21 \'call_up\': false 22 }); 23 } 24 });
备注于2017/7/26
而在拖拽过程中,由于说拖拽中也要限制不能拖拽出canvas画布外,于是又在构造函数这里添加了判断实现不可拖拽出canvas
附带如下代码:
1 $(document).mousemove(function(e) { 2 if (!!this.move) { 3 var posix = !document.move_target ? {\'x\': 0, \'y\': 0} : document.move_target.posix, 4 callback = document.call_down || function() { 5 var _toTop=e.pageY-posix.y, 6 _toLeft=e.pageX-posix.x; 7 8 /*获取canvas左下角位置*/ 9 var canvasHigh=$("#canvas").height();//pdf高 10 var canvasWid=$("#canvas").width();//pdf宽 11 var canvasPosTop=$("#canvas").offset().top;//pdf距离顶部 12 var canvasPosBottom=$("#canvas").offset().top+canvasHigh;//pdf底部距离顶部 13 var canvasPosLeft=$("#canvas").offset().left;//pdf距离左边 14 var canvasPosRight=canvasPosLeft+canvasWid;//pdf右边距离左边 15 16 if(_toTop < canvasPosTop){ 17 _toTop = canvasPosTop 18 } 19 if(_toTop > (canvasPosBottom - $(this.move_target).height()) ){ 20 _toTop = (canvasPosBottom - $(this.move_target).height()) 21 } 22 if(_toLeft < canvasPosLeft){ 23 _toLeft = canvasPosLeft 24 } 25 if(_toLeft > (canvasPosRight - $(this.move_target).width()) ){ 26 _toLeft =(canvasPosRight - $(this.move_target).width()) 27 } 28 29 $(this.move_target).css({ 30 \'top\': _toTop ,//e.pageY - posix.y, 31 \'left\': _toLeft//e.pageX - posix.x 32 }); 33 }; 34 callback.call(this, e, posix); 35 } 36 })
功能三:pdf展示
要点:引入pdf.js和pdf.worker.js进行API解析和核心解析
说明:1.pdf.js不能打开本地文件,需要服务器启动
2.需要Firefox下运行报错才有提示(firefox的pdf解析)
1 var loadingTask=PDFJS.getDocument(config.url); 2 loadingTask.promise.then( 3 function getPdf(pdf){ 4 pdf.getPage(config.defaultPage).then( 5 function getPage(page){ 6 var scale=1; 7 var viewport=page.getViewport(scale); 8 var canvas=document.getElementById(\'canvas\'); 9 var context=canvas.getContext(\'2d\'); 10 canvas.height=config.outerHigh; 11 canvas.width=config.outerWid; 12 var renderContext={ 13 canvasContext:context, 14 viewport:viewport 15 }; 16 page.render(renderContext); 17 }, 18 function pageError(msg){ 19 console.log(msg); 20 } 21 ) 22 }, 23 function pdfError(msg){ 24 alert(msg); 25 } 26 );
备注于2017/7/26
由于pdf文件的大小各异,于是进行了如下调整,是canvas展示的pdf进行缩放显示
调整上段代码后的结果:
1 var loadingTask=PDFJS.getDocument(config.url); 2 loadingTask.promise.then( 3 function getPdf(pdf){ 4 pdf.getPage(config.defaultPage).then( 5 function getPage(page){ 6 var scale=1; 7 var viewport=page.getViewport(scale); 8 var canvas=document.getElementById(\'canvas\'); 9 var context=canvas.getContext(\'2d\'); 10 var ch2vh=(config.outerHigh/viewport.height).toFixed(2), 11 cw2vw=(config.outerWid/viewport.width).toFixed(2); 12 if(ch2vh < cw2vw){ 13 viewport=page.getViewport(ch2vh); 14 }else{ 15 viewport=page.getViewport(cw2vw); 16 } 17 canvas.height=config.outerHigh; 18 canvas.width=config.outerWid; 19 var renderContext={ 20 canvasContext:context, 21 viewport:viewport 22 }; 23 page.render(renderContext); 24 }, 25 function pageError(msg){ 26 console.log(msg); 27 } 28 ) 29 }, 30 function pdfError(msg){ 31 alert(msg); 32 } 33 );
汇总:
1.签名js文件
备注:在交付的时候那边发现了在ie下拖拽时获取的图片有问题,然后又来找到了我,经过一轮的调试(ps:ie调试真不爽),
发现获取字符串时候,ie好像默认添加了空格符,所以进不了if语句,现见if判断调整为:
if(
(_type).toLowerCase().trim()==\'signature\'
)
elseif同理。
再则ie报错不支持append(),所以将this.append()调整为this.appendChild()。
(备注:调整于2017/07/05)
1 $(function(){ 2 3 /*H5拖拽并复制*/ 4 var moveDemo=null; 5 var _type; 6 var divs=document.querySelectorAll(".left_list li"); 7 var showBox=document.querySelector(".section_main_pdf"); 8 for(var i=0;i<divs.length;i++){ 9 divs[i].ondragstart=function(e){ 10 moveDemo=this.querySelector("img"); 11 _type=this.querySelector(\'.list_name\').innerText; 12 } 13 }; 14 showBox.ondragover =function(e){ 15 e.preventDefault(); 16 //console.log(\'x:\'+ e.pageX+\';y:\'+ e.pageY); 17 }; 18 showBox.ondrop=function(e){ 19 var _clone=moveDemo.cloneNode(); 20 this.append(_clone); 21 console.log(_clone); 22 _clone.className=\'dragIcon\'; 23 $(_clone).css({ 24 \'width\':\'100%\', 25 \'height\':\'100%\' 26 }).attr(\'draggable\',false); 27 $(_clone).wrap(\'<span class="img_outer"></span>\'); 28 if(_type==\'Signature\'){ 29 $(_clone).parent().css({ 30 \'position\':\'absolute\', 31 \'top\': e.pageY, 32 \'left\': e.pageX, 33 \'cursor\':\'move\', 34 \'display\':\'inline-block\', 35 \'border\':\'2px solid\' 36 }).append(\'<span class="iconResize" style="position:absolute;display: inline-block;width: 10px;height: 10px;\' + 37 \'cursor:se-resize;right:-5px;bottom:-5px;background-color:#fff;\' + 38 \'border:2px solid;border-radius:50%"></span>\').attr({ 39 \'data-icon\':\'signature\', 40 \'data-page\':config.defaultPage 41 }); 42 } 43 else if(_type==\'PIN\'){ 44 $(_clone).parent().css({ 45 \'position\':\'absolute\', 46 \'top\': e.pageY, 47 \'left\': e.pageX, 48 \'cursor\':\'move\', 49 \'display\':\'inline-block\', 50 \'border\':\'2px solid\' 51 }).attr({ 52 \'data-icon\':\'pin\', 53 \'data-page\':config.defaultPage 54 }); 55 } 56 }; 57 58 /*构造拖拽及缩放函数*/ 59 $(document).mousemove(function(e) { 60 if (!!this.move) { 61 var posix = !document.move_target ? {\'x\': 0, \'y\': 0} : document.move_target.posix, 62 callback = document.call_down || function() { 63 $(this.move_target).css({ 64 \'top\': e.pageY - posix.y, 65 \'left\': e.pageX - posix.x 66 }); 67 }; 68 callback.call(this, e, posix); 69 } 70 }).mouseup(function(e) { 71 if (!!this.move) { 72 var callback = document.call_up || function(){}; 73 callback.call(this, e); 74 $.extend(this, { 75 \'move\': false, 76 \'move_target\': null, 77 \'call_down\': false, 78 \'call_up\': false 79 }); 80 } 81 }); 82 83 /*实例化*/ 84 $(document).on(\'mousedown\',\'.img_outer\',function(e){ 85 var offset=$(this).offset(); 86 this.posix={ 87 \'x\': e.pageX-offset.left, 88 \'y\': e.pageY-offset.top 89 }; 90 $.extend(document,{ 91 \'move\':true, 92 \'move_target\':this 93 }); 94 }); 95 $(document).on(\'mousedown\',\'.iconResize\',function(e){ 96 var that=this; 97 var posix = { 98 \'w\': $(this).parent().width(), 99 \'h\': $(this).parent().height(), 100 \'x\': e.pageX, 101 \'y\': e.pageY 102 }; 103 $.extend(document, {\'move\': true, \'call_down\': function(e) { 104 $(that).parent().css({ 105 \'width\': Math.max(30, e.pageX - posix.x + posix.w), 106 \'height\': Math.max(30, e.pageY - posix.y + posix.h) 107 }); 108 }}); 109 return false; 110 }); 111 112 113 //获取选中元素 114 $(document).on(\'click\',\'.img_outer\',function(e){ 115 $(".img_outer").removeClass("active"); 116 var _active=$(this).hasClass("active"); 117 if(_active){ 118 $(this).removeClass("active"); 119 }else{ 120 $(this).addClass("active"); 121 } 122 }); 123 124 /*渲染PDF*/ 125 /* var _container=$(".section_main_pdf"); 126 PDFJS.workerSrc=\'js/pdf.worker.js\'; 127 128 var config={ 129 //url:\'txt/userAgreeDoc.pdf\',//pdf路径 130 url:\'txt/webpack.pdf\', 131 outerHigh:_container.height(),//容器高 132 outerWid:_container.width(),//容器宽 133 defaultPage:1,//默认第一页 134 totalPage:6//总页数 135 };*/ 136 137 renderPdf(); 138 /*上一页*/ 139 $("input.page_pre").on(\'click\',function(){ 140 if(config.defaultPage>1){ 141 --config.defaultPage; 142 $(".page_num_cur").text(config.defaultPage); 143 renderPdf(); 144 } 145 }); 146 /*下一页*/ 147 $("input.page_next").on(\'click\',function(){ 148 if(config.defaultPage<config.totalPage){ 149 ++config.defaultPage; 150 $(".page_num_cur").text(config.defaultPage); 151 renderPdf(); 152 } 153 }); 154 /*GO*/ 155 $("input.page_go_val").on(\'click\',function(){ 156 var _val=$("input.page_val").val(); 157 if(_val>0 && _val<=config.totalPage){ 158 config.defaultPage=parseInt(_val);//pdf不会自动转换字符串为数字 159 console.log(config.defaultPage); 160 $(".page_num_cur").text(_val); 161 renderPdf(); 162 } 163 }); 164 165 function renderPdf(){ 166 var loadingTask=PDFJS.getDocument(config.url); 167 loadingTask.promise.then( 168 function getPdf(pdf){ 169 pdf.getPage(config.defaultPage).then( 170 function getPage(page){ 171 var scale=1; 172 var viewport=page.getViewport(scale); 173 var canvas=document.getElementById(\'canvas\'); 174 var context=canvas.getContext(\'2d\'); 175 canvas.height=config.outerHigh; 176 canvas.width=config.outerWid; 177 var renderContext={ 178 canvasContext:context, 179 viewport:viewport 180 }; 181 page.render(renderContext); 182 }, 183 function pageError(msg){ 184 console.log(msg); 185 } 186 ) 187 }, 188 function pdfError(msg){ 189 alert(msg); 190 } 191 ); 192 193 //对不在当前页面的签名进行隐藏或显示 194 var lists=$(".section_main_pdf .img_outer"); 195 for(var i=0;i<lists.length;i++){ 196 if(lists.eq(i).data(\'page\')==config.defaultPage){ 197 lists.eq(i).css({ 198 \'visibility\':\'visible\' 199 }); 200 }else{ 201 lists.eq(i).css({ 202 \'visibility\':\'hidden\' 203 }); 204 } 205 } 206 } 207 }); 208 209 //选择头像 210 $(document).on(\'change\',\'#selectUser\',function(e){ 211 //通过字符串拼接选中值来实现切换图片 212 var _val=$(this).find(\'option:selected\').val(); 213 var _imgVal=$(".img_outer.active"); 214 if(_val==\'spouse\'){ 215 _imgVal.find(\'img\').attr({ 216 \'src\':\'images/pin.png\' 217 }); 218 _imgVal.attr(\'data-id\',_val); 219 } 220 }); 221 222 //保存信息 223 $(document).on(\'click\',\'#saveMsg\',function(e){ 224 /*获取canvas左下角位置*/ 225 var canvasHigh=$("#canvas").height();//pdf高 226 var canvasWid=$("#canvas").width();//pdf宽 227 //console.log(\'canvasHigh:\'+canvasHigh); 228 var canvasPosTop=$("#canvas").offset().top;//pdf距离顶部 229 var canvasPosBottom=$("#canvas").offset().top+canvasHigh;Element,el-dialog弹出层拖拽及拉伸、双击全屏