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弹出层拖拽及拉伸、双击全屏

一款简单的缩放拖拽图片控件

h5-拖拽接口

简单拖拽即生成网页 VvvebJs

js仿百度地图拖拽缩放添加图层功能(原创)

H5 拖拽操作