成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔

Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔

熱門標簽:平?jīng)龅貓D標注位置怎么弄 如何獲取地圖標注客戶 電話機器人黑斑馬免費 機器人外呼系統(tǒng)存在哪些能力 只辦理400電話 高德地圖標注地點糾錯 拓展地圖標注 南昌仁和怎么申請開通400電話 電話機器人電銷系統(tǒng)掙話費

前言

電子簽名通俗來說就是通過技術(shù)手段實現(xiàn)在電子文檔上加載電子形式的簽名,其作用類似于紙質(zhì)合同上的手寫簽名或加蓋的公章。雖然電子簽名多年來合法性一直遭到質(zhì)疑,但其在企業(yè)工作流審批、請柬、單據(jù)保全等場景應用廣泛,最近的項目中就有這樣一個手寫簽名并生成PDF文件的需求。

實現(xiàn)思路

  • 使用canvas來實現(xiàn)手寫簽名的功能,然后將canvas轉(zhuǎn)化為圖片,貼在簽名的位置;
  • 將整個需要生成文檔的dom區(qū)域使用html2canvas插件轉(zhuǎn)成一張大圖;
  • 使用JsPDF插件將上述圖片生成PDF文檔;
  • 對于文件內(nèi)容較多的情況,需要合理選擇分頁位置;

生成簽名

1. 在tsx中定義canvas畫布

<canvas className={styles.canvas} ref={canvasDom} width="350" height="150" />

注意:Canvas的寬高必須要使用內(nèi)聯(lián)樣式定義,這是因為Canvas標簽有自己的默認寬高300px×150px。它內(nèi)聯(lián)樣式定義的width和height是繪畫區(qū)域(畫布)實際寬度和高度,繪制的圖形都是在這個上面。如果在style外鏈文件中定義其width和height,那么這個width和height是Canvas在瀏覽器中被渲染的高度和寬度。如果Canvas中沒有直接定義width和height沒或值不正確,就會被設(shè)置成默認值{width:300px,height:150px}。所以,如果你在style中外鏈文件中設(shè)置了canvas {width: 200px; height: 200px;},卻沒有直接在canvas上定義畫布寬高,那么此時你輸出canvas.height 值依舊為150,canvas.width值依舊為300。也就是一塊150×300的畫布在200×200的區(qū)域渲染,因而圖片會出現(xiàn)拉伸、變形等現(xiàn)象。

2. 定義簽名函數(shù)

const writing = (
    beginX: number,
    beginY: number,
    stopX: number,
    stopY: number,
    ctx: any,
  ) => {
    ctx.beginPath();  // 開啟一條新路徑
    ctx.globalAlpha = 1;  // 設(shè)置圖片的透明度
    ctx.lineWidth = 3;  // 設(shè)置線寬
    ctx.strokeStyle = 'red';  // 設(shè)置路徑顏色
    ctx.moveTo(beginX, beginY);  // 從(beginX, beginY)這個坐標點開始畫圖
    ctx.lineTo(stopX, stopY);  // 定義從(beginX, beginY)到(stopX, stopY)的線條(該方法不會創(chuàng)建線條)
    ctx.closePath();  // 創(chuàng)建該條路徑
    ctx.stroke();  // 實際地繪制出通過 moveTo() 和 lineTo() 方法定義的路徑。默認顏色是黑色。
  };

3. 注冊監(jiān)聽事件

 let beginX: number, beginY: number;
    const canvas: HTMLCanvasElement = canvasDom.current;
    const ctx = canvas.getContext('2d');
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    canvas.addEventListener('touchstart', function(event: any) {
      event.preventDefault(); // 阻止在canvas畫布上簽名的時候頁面跟著滾動
      beginX = event.touches[0].clientX - this.offsetLeft; 
      beginY = event.touches[0].pageY - this.offsetTop;
    });
    canvas.addEventListener('touchmove', (event: any) => {
      event.preventDefault(); // 阻止在canvas畫布上簽名的時候頁面跟著滾動
      event = event.touches[0];
      let stopX = event.clientX - canvas.offsetLeft;
      let stopY = event.pageY - canvas.offsetTop;
      writing(beginX, beginY, stopX, stopY, ctx);
      beginX = stopX; // 這一步很關(guān)鍵,需要不斷更新起點,否則畫出來的是射線簇
      beginY = stopY;
    });

注意

  • 在注冊“touchstart”和“touchmove”事件時,需要阻止默認事件,否則頁面會跟著手勢上下滑動。
  • 移動端的每個觸摸事件對象中都包括了touches這個屬性,它用于描述位于屏幕上的所有手指的一個列表,獲取當前事件對象我們習慣性的使用event = event.touches[0],而在PC端則不需要這么操作。
  • offsetLeft值跟offsetTop值跟父級元素沒關(guān)系,而是跟其上一級的定位元素(除position:static外的所有定位如fixed,relative,absolute元素)有關(guān)系。若上一級定位元素都沒有除position:staice外的定位,則這個偏移量是相對于body而言的。

需要理清移動端事件對象的幾個屬性,⏬

clientX/clientY: 觸摸位置距離當前body可視區(qū)域的x,y坐標;
pageX/pageY: 對于整個頁面來說,觸摸位置距離body左上角的x,y坐標,包括被scrollTop和scrollLeft的值;
screenX/screenY: 觸摸位置距離顯示器左邊和頂部的x,y距離。
所以,在獲取結(jié)束點坐標的時候,如果當前頁面沒有出現(xiàn)滾動條,使用clientY和pageY計算差別不大,如果頁面比較長,出現(xiàn)了滾動條,那么就必須要使用pageY來計算。clientX同理,但是移動端通常橫向滾動的場景不多,所以用clientX來計算即可。

在簽名(touchmove)這個動作過程中,我們需要不斷的更新起點位置,否則畫出來是這樣🔽


 

其實這個原理和微積分很相似,線段本質(zhì)上就是由無窮多個小線段組成,宏觀一點來看可以把線段當成一個個長度很小的小線段首尾相連構(gòu)成。所以我一直覺得編程編到最后就是考驗一個人的數(shù)學能力,交并集、邏輯思維、算法等都能看到數(shù)學的身影。最后生成簽名如下:

生成PDF文檔

html2canvas是一款將HTML代碼轉(zhuǎn)換成Canvas的插件,因此需要用一個div包裹住需要打印的內(nèi)容區(qū)域,獲得這個dom節(jié)點。

html2Canvas(dom, {
    allowTaint: true,
    width: dom.offsetWidth, //設(shè)置獲取到的canvas寬度
    height: dom.offsetHeight, //設(shè)置獲取到的canvas高度
    x: 0, //頁面在水平方向滾動的距離
    y: 0, //頁面在垂直方向滾動的距離
   })

注意:此處需要設(shè)置width和height及x,y,否則當頁面內(nèi)容只有一頁的時候沒有問題,但是若頁面內(nèi)容有很多頁的時候,就會出現(xiàn)生成的圖片只有一小部分有內(nèi)容的現(xiàn)象。問題就出現(xiàn)在這個配置參數(shù)上,若沒有設(shè)置寬高,則默認只取當前視口的內(nèi)容,丟棄掉其他超出當前視口的內(nèi)容。
設(shè)置打印參數(shù):

const print = () => {
    let dom: HTMLElement = pdfDom.current;
    html2Canvas(dom, {
      allowTaint: true,
      width: dom.offsetWidth, //設(shè)置獲取到的canvas寬度
      height: dom.offsetHeight, //設(shè)置獲取到的canvas高度
      x: 0, //頁面在水平方向滾動的距離
      y: 0, //頁面在垂直方向滾動的距離
    }).then((canvas: HTMLCanvasElement) => {
      let canvasWidth = canvas.width;
      let canvasHeight = canvas.height;
      let pageHeight = (canvasWidth / 592.28) * 841.89; // 一頁A4 pdf能顯示的canvas高度
      let imgWidth = 595.28; // 設(shè)置圖片寬度和A4紙寬度相等
      let imgHeight = (592.28 / canvasWidth) * canvasHeight;//等比例換算成A4紙的高度
      let totalHeight = imgHeight; // 需要打印的圖片總高度,初始狀態(tài)和圖片高度相等
      let pageData = canvas.toDataURL('image/png', 1.0);
      let PDF = new JsPDF('p', 'pt', 'a4', true);
      if (totalHeight < pageHeight) { //
        PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight); // 從頂部開始打印
      } else {
        let top = 0;   // 打印初始區(qū)域
        while (totalHeight > 0) {
          PDF.addImage(pageData, 'JPEG', 0, top, imgWidth, imgHeight);  // 從圖片頂部往下top位置開始打印
          totalHeight -= pageHeight;
          top -= 841.89;
          if (totalHeight > 0) {
            PDF.addPage();
          }
        }
      }
      PDF.save('test.pdf');
    });
  };

選擇分頁位置

按照上述步驟生成了一份PDF文檔,但是當PDF頁數(shù)有很多的時候,會有這樣的問題⏬

 

可以看到,分頁的時候從這段文字這里懶腰截斷了。這顯然不是我們想要看到的效果,如何解決這個問題呢?🤔

PDF文檔頁數(shù)較少的情況

可以在開發(fā)測試的時候預先在將要分頁的地方插入一個padding,就是提前預留分頁位置

PDF文檔頁數(shù)較多

對于這種情況,筆者嘗試遍歷要打印的dom節(jié)點的子節(jié)點,將每一頁所能打印的dom節(jié)點高度累加,若超過了頁面所能承載的最大高度,則將最后一個節(jié)點增加padding,打印完畢將樣式還原。這種方法因為要計算每個dom節(jié)點的高度,非常耗性能,也要求頁面dom元素的顆粒度較細,否則會出現(xiàn)一個頁面有大塊空白,完全無法模擬出word生成pdf的那種效果,所以就不展開討論了。

到此這篇關(guān)于Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔的文章就介紹到這了,更多相關(guān)canvas電子簽名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!

標簽:漯河 永州 棗莊 池州 青島 遼源 新疆 西藏

巨人網(wǎng)絡(luò)通訊聲明:本文標題《Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔》,本文關(guān)鍵詞  Html5,基于,canvas,實現(xiàn),電子,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔》相關(guān)的同類信息!
  • 本頁收集關(guān)于Html5基于canvas實現(xiàn)電子簽名并生成PDF文檔的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    www.com欧美| 久久香蕉精品| 一本一本久久a久久精品牛牛影视| 久久亚洲综合色| 韩国v欧美v日本v亚洲| 国产日产精品一区二区三区四区的观看方式| 精品无码人妻一区二区三| 成人亚洲精品777777ww| 国产特级嫩嫩嫩bbb| 午夜视频在线观看一区二区三区| 久久久人人人| 资源网第一页久久久| 黄色毛片免费| 亚洲午夜久久| 国产精品视频一区在线观看| 97成人在线观看视频| 手机在线中文字幕| 99热这里只有精品8| 香蕉久久夜色| 国产精品一国产精品| sese在线播放| 亚洲欧美一区二区三区四区五区| 日本中文字幕中出在线| 国产视频91在线| 日韩亚洲国产欧美| 成年免费插网| 欧美自拍偷拍第一页| 国产精品亚洲欧美导航| 男女午夜激烈无遮挡| 最新日韩精品| 成人在线免费网站| 欧美激情第一页在线观看| 国产精品久久一区二区三区不卡| 小泽玛利亚一区| 亚洲综合视频在线观看| 精品一区二区三区四| 欧美亚洲在线| 国产免播放器视频| 国产美女www爽爽爽| 国产乱淫av麻豆国产免费| 欧美亚洲另类小说| 在线欧美激情| 日本网站在线看| 免费a视频在线观看| 免费成人在线看| 五月天亚洲视频| 性欧美videos另类hd| jizz久久精品永久免费| 男人天堂网在线视频| 日韩伦人妻无码| 欧美 日韩 中文字幕| 欧美午夜精品一区二区蜜桃| 区一区二区三区中文字幕| 亚洲视频在线免费看| 久草视频在线观| 色老汉一区二区三区| 亚洲一区中文字幕在线| 国产91精品看黄网站在线观看| 国产不卡视频一区二区三区| 久久精品无码av| 黄色小说在线播放| aaaaaaa大片免费看| 成人精品一区二区三区| **孕交吃奶水一级毛片| 国产偷久久久精品专区| 毛片av免费在线观看| 日韩欧美在线视频一区二区| 日韩高清影视在线观看| gogo人体一区| 成年人视频在线观看免费| 精品视频一区 二区 三区| 国产欧美久久久久久| 久久人人97超碰国产公开结果| 91视频在线看| 国偷自产av一区二区三区麻豆| 日韩欧美一区免费| 色视频www在线播放国产成人| 精一区二区三区| 欧美丰满少妇人妻精品| 亚洲美女久久久| 亚洲日本伊人| v天堂中文在线| 蜜桃av一区二区三区| 福利视频午夜| 五十度飞在线播放| 91xxxxx| 91九色精品国产一区二区| 国产综合一区二区| 一本一本久久a久久精品牛牛影视| 亚洲不卡一卡2卡三卡4卡5卡精品| 久久99国产精品久久99大师| 国语自产精品视频在线看抢先版结局| 超碰免费在线97| 国产永久免费高清在线观看视频| 亚洲天堂网站在线| 欧美性videos| 亚洲一区三区| 精品丰满少妇一区二区三区| 国产sm在线观看| 综合久久给合久久狠狠狠97色| 欧美性xxxxxbbbbbb精品| 少妇高潮久久久久久潘金莲| 亚洲男人影院| 日韩av网站导航| 成人动漫在线免费观看| 欧美成人精品在线播放| 久久九九电影| 中文字幕码精品视频网站| 欧美gay男男猛男无套| 久久天天躁日日躁| 国产精品8888| 九九九九九九精品任你躁| 成人污污视频| 亚洲欧美自偷自拍| 国产在线视频不卡| 伦理电影国产精品| 久久这里只有精品23| 天天干天天干天天干天天干天天干| 69久久夜色精品国产69蝌蚪网| 亚洲人成网77777色在线播放| 免费在线观看a视频| 草色在线视频| 一区视频二区视频| 国产欧美综合一区| 天天精品视频| 在线一区二区三区| 理论片在线观看理伦片| 亚洲丝袜在线视频| 国产亚洲精品日韩| 草草视频在线一区二区| 欧美午夜在线观看| 亚洲高清不卡在线| 国产欧美丝袜| 欧美猛男男男激情videos| 福利一区视频在线观看| 深田咏美在线x99av| 久久久综合网| 国产精品视频在线观看免费| 好吊日视频在线观看| 在线视频精品一| 日本片在线看| 国产91久久久久蜜臀青青天草二| 五月婷中文字幕| 日韩一二三区视频| 日韩视频在线免费看| 91精品啪在线观看国产爱臀| 日本不卡不码高清免费观看| 重囗味另类老妇506070| 日韩视频免费中文字幕| 亚洲男人av电影| 国产成人无码aa精品一区| 97av在线影院| 99热这里只有精品4| 中文字幕在线视频观看| 久久精品女人天堂| 麻豆视频国产| 日本三级免费看| 91精品视频一区| 亚洲无码精品在线播放| 欧美三级黄网| 日韩精品一区二区三区中文在线| 国产综合欧美| 日韩精品无码一区二区三区免费| 亚洲免费视频一区二区| 国产精品一线天粉嫩av| 欧美日韩国产免费观看| 天堂а在线中文在线无限看推荐| 欧美jizz| 波多野洁衣一区| 久久综合电影一区| av中文在线观看| www.久久东京| 国产区视频在线| 1769视频在线播放免费观看| 中文字幕一区二区av| 蜜臀久久99精品久久久久宅男| 欧美三级 欧美一级| 九九热国产在线| 天天干天天爽天天操| 欧美色欧美亚洲另类七区| 天堂tv亚洲tv日本tv欧美人tv| 男人日女人下面视频| 国产成人精品无码片区在线| 日韩电影一区二区三区| 91视频在线免费| 精产国品一区二区三区| 久久99精品国产.久久久久久| 国内精品福利| 热99在线视频| 国产成人精品777777| 日本在线观看中文字幕| 亚洲日韩中文字幕在线播放| 99re成人精品视频| 亚洲综合色视频在线观看| 欧美 日韩 国产一区| 欧美另类在线视频| 国产成人精品18| 亚洲精品一区在线观看香蕉| 5858s免费视频成人| 波多野结衣mp4| 亚洲视频免费| 日韩不卡的av| 国产精品美女诱惑| 亚洲а∨天堂久久精品喷水| 国产噜噜噜噜噜久久久久久久久| 亚洲free嫩bbb| 日日摸.com| 国产精品色在线观看| 麻豆成全视频免费观看在线看| av观看成片免费网站| 国产精品夜夜爽| 欧美日韩国产综合草草| 亚洲精品视频免费看| 日韩免费毛片视频| 亚洲s码欧洲m码国产av| 欧美精品久久久久久久小说| 国产女同在线观看| 日本成人免费| 成人不卡免费视频| 国产精品成人无码免费| 成人激情四射网| 日本女优爱爱视频| 天堂网一区二区| 日韩欧美精品在线不卡| 999精品在线视频| 国产熟女高潮视频| 久久亚洲精精品中文字幕| 国内精品免费在线观看| 欧美一区二区三区播放| 色综合久久久久久久| 91麻豆成人精品国产免费网站| 久久精品国产电影| 欧美日本不卡| 久久久免费高清电视剧观看| 日本高清+成人网在线观看| 国产一二三区av| 亚洲精品美女久久久久| 韩日精品在线| 国产一区二区三区av在线| 久久久久久久久久国产| 亚洲素人在线| 亚洲欧美卡通动漫| 91精品黄色| 亚洲视频在线观看一区| 日韩影视一区二区三区| 中文字幕亚洲无线码在线一区| 国产美女做爰免费视频软件| 美国黑人一级大黄| 日韩一区二区久久| 国产精成人品localhost| 国产老妇伦国产熟女老妇视频| 日韩你懂的电影在线观看| 欧美日韩精品综合在线| av电影免费在线观看| 香蕉视频在线观看www| 青春草在线视频免费观看| 日韩中文字幕不卡| 国产乱色在线观看| 黄色网址电影| 无遮挡的视频在线观看| 日韩成人一区二区三区在线观看| 五月激情四射婷婷| 日韩精品一级中文字幕精品视频免费观看| 一二三在线视频社区| 欧美日韩国产区| 欧美最近摘花xxxx摘花| xxx性欧美| 成人午夜电影久久影院| 羞羞视频网站在线观看| 亚洲激情偷拍| 欧美日韩一二区| 亚洲国产精品无码久久| 亚洲av成人片无码| 国产av人人夜夜澡人人爽| 久久久伊人日本| 国产一区二区精品久| 一级毛片高清视频| 精选一区二区三区四区五区| 久久久夜夜夜| 亚洲欧美网站| 巨大荫蒂视频欧美大片| 色偷偷综合社区| 久久婷婷国产综合精品青草| 另类小说欧美激情| 成人在线视频中文字幕| 国产一区二区三区精品欧美日韩一区二区三区| 欧美老tube| 国产探花在线精品| 欧洲美女女同性互添| 中文字幕国产在线| 日本在线视频网址| 国产精品稀缺呦系列在线| 久久精品日韩无码| 久久97超碰国产精品超碰| 黑人巨大精品欧美一区二区一视频| 成人免费看黄网址| 99热在线观看免费精品| 久久一二三国产| 羞羞视频立即看| 亚洲成人77777| 国产成人在线视频播放| 免费黄网大全| 久久视频免费在线播放| 一级片在线播放| 成人h动漫精品一区二区| 一区二区三区欧洲区| 日本三级免费网站| 国产欧美一区二区三区精品观看| 久久久激情视频| 国内成人免费视频| 国产一区二区三区亚洲| 国产熟女高潮视频| 黄色污污在线观看| 黄网站app在线观看| 99精品久久久久久| 色综合久久久久综合体| 99在线视频播放| 欧美丝袜一区二区| www.亚洲一区二区三区| 中文字幕有码在线播放| 无码国模国产在线观看| www.-级毛片线天内射视视| 蜜臀久久99精品久久久无需会员| 91麻豆6部合集magnet| 日本在线一区二区三区| 天堂美国久久| 国产精品美女999| 一区二区三区在线播放欧美|