index.html 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  7. <title></title>
  8. <style type="text/css">
  9. html,
  10. body,
  11. canvas {
  12. padding: 0;
  13. margin: 0;
  14. width: 100%;
  15. height: 100%;
  16. overflow-y: hidden;
  17. background-color: transparent;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <canvas id="lime-signature"></canvas>
  23. <script type="text/javascript" src="./uni.webview.1.5.3.js"></script>
  24. <script type="text/javascript" src="./signature.js"></script>
  25. <script>
  26. var signature = null;
  27. var timer = null;
  28. var isStart = false;
  29. var options = null
  30. console.log = function(...args) {
  31. postMessage(args);
  32. };
  33. // function stringify(key, value) {
  34. // if (typeof value === 'object' && value !== null) {
  35. // if (cache.indexOf(value) !== -1) {
  36. // return;
  37. // }
  38. // cache.push(value);
  39. // }
  40. // return value;
  41. // };
  42. function emit(event, data) {
  43. postMessage({
  44. event,
  45. data: typeof data !== "object" && data !== null ? data : JSON.stringify(data),
  46. });
  47. // cache = [];
  48. }
  49. function postMessage(data) {
  50. uni.postMessage({
  51. data
  52. });
  53. }
  54. function update(v = {}) {
  55. if (signature) {
  56. options = v
  57. signature.pen.setOption(v);
  58. } else {
  59. signature = new Signature.Signature({el: "lime-signature"});
  60. canvasEl = signature.canvas.get("el");
  61. options = v
  62. signature.pen.setOption(v)
  63. const width = signature.canvas.get("width");
  64. const height = signature.canvas.get("height");
  65. emit({changeSize: {width,height}})
  66. }
  67. }
  68. function clear() {
  69. signature.clear()
  70. }
  71. function undo() {
  72. signature.undo()
  73. }
  74. function redo() {
  75. signature.redo()
  76. }
  77. function isEmpty() {
  78. const isEmpty = signature.isEmpty()
  79. emit({isEmpty});
  80. }
  81. function isTransparent(color) {
  82. // 判断颜色是否为 transparent
  83. if (color === 'transparent') {
  84. return true;
  85. }
  86. // 判断颜色是否为 rgba 的 a 为 0
  87. if (color.startsWith('rgba')) {
  88. const regex = /\d+(\.\d+)?/g;
  89. const matches = color.match(regex);
  90. if (matches !== null) {
  91. const alpha = parseFloat(matches[3]);
  92. if (alpha === 0) {
  93. return true;
  94. }
  95. }
  96. }
  97. return false;
  98. }
  99. function mask(param){
  100. clearTimeout(timer);
  101. let {destWidth=0, destHeight=0} = param
  102. let width = this.signature.canvas.get('width')
  103. let height = this.signature.canvas.get('height')
  104. let canvas = document.createElement('canvas')
  105. const ctx = canvas.getContext('2d');
  106. const pixelRatio = signature.canvas.get('pixelRatio')
  107. canvas.width = width * pixelRatio
  108. canvas.height = height * pixelRatio
  109. this.signature.pen.getMaskedImageData((imageData)=>{
  110. ctx.putImageData(imageData, 0, 0);
  111. if(destWidth&&destHeight){
  112. const _canvas = document.createElement('canvas')
  113. _canvas.width = destWidth
  114. _canvas.height = destHeight
  115. const _context = _canvas.getContext('2d')
  116. _context.drawImage(canvas, 0, 0, destWidth, destHeight)
  117. canvas.remove()
  118. canvas = _canvas
  119. }
  120. const path = canvas.toDataURL();
  121. canvas.remove()
  122. if (typeof path == "string") {
  123. const index = Math.ceil(path.length / 8);
  124. for (var i = 0; i < 8; i++) {
  125. if (i == 7) {
  126. emit({"success": path.substr(i * index, index)});
  127. } else {
  128. emit({"file": path.substr(i * index, index)});
  129. }
  130. }
  131. } else {
  132. console.error("canvas no data");
  133. emit({"fail": "canvas no data"});
  134. }
  135. })
  136. }
  137. function save(param) {
  138. // delete param.success;
  139. // delete param.fail;
  140. clearTimeout(timer);
  141. timer = setTimeout(() => {
  142. let {fileType = 'png', quality = 1, n, destWidth=0, destHeight=0} = param
  143. const type = `image/${fileType}`.replace(/jpg/, 'jpeg');
  144. const {backgroundColor, landscape, boundingBox} = options
  145. const flag = backgroundColor || landscape || boundingBox||destWidth&&destHeight
  146. let path = canvasEl.toDataURL(!flag && type, !flag && quality)
  147. if(flag) {
  148. let canvas = document.createElement('canvas')
  149. const pixelRatio = signature.canvas.get('pixelRatio')
  150. let width = signature.canvas.get('width')
  151. let height = signature.canvas.get('height')
  152. let x = 0
  153. let y = 0
  154. const next = () => {
  155. const size = [width, height]
  156. if(landscape) {size.reverse()}
  157. canvas.width = size[0] * pixelRatio
  158. canvas.height = size[1] * pixelRatio
  159. const param = [x, y, width, height, 0 , 0, width, height].map(item => item * pixelRatio)
  160. const context = canvas.getContext('2d')
  161. // context.scale(pixelRatio, pixelRatio)
  162. if (landscape) {
  163. context.translate(0, width * pixelRatio)
  164. context.rotate(-Math.PI / 2)
  165. }
  166. if (backgroundColor && !isTransparent(backgroundColor)) {
  167. context.fillStyle = backgroundColor
  168. context.fillRect(0, 0, width * pixelRatio, height * pixelRatio)
  169. }
  170. const drawImage = ()=>{
  171. }
  172. // param
  173. context.drawImage(signature.canvas.get('el'), ...param)
  174. if(destWidth&&destHeight){
  175. const _canvas = document.createElement('canvas')
  176. _canvas.width = destWidth
  177. _canvas.height = destHeight
  178. const _context = _canvas.getContext('2d')
  179. _context.drawImage(canvas, 0, 0, destWidth, destHeight)
  180. canvas.remove()
  181. canvas = _canvas
  182. }
  183. path = canvas.toDataURL(type, quality)
  184. canvas.remove()
  185. }
  186. if(boundingBox) {
  187. const res = signature.getContentBoundingBox()
  188. width = res.width
  189. height = res.height
  190. x = res.startX
  191. y = res.startY
  192. next()
  193. } else {
  194. next()
  195. }
  196. }
  197. if (typeof path == "string") {
  198. const index = Math.ceil(path.length / 8);
  199. for (var i = 0; i < 8; i++) {
  200. if (i == 7) {
  201. emit({"success": path.substr(i * index, index)});
  202. } else {
  203. emit({"file": path.substr(i * index, index)});
  204. }
  205. }
  206. } else {
  207. console.error("canvas no data");
  208. emit({"fail": "canvas no data"});
  209. }
  210. }, 30);
  211. }
  212. </script>
  213. </body>
  214. </html>