index.html 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. let width = signature.canvas.get('width')
  108. let height = signature.canvas.get('height')
  109. canvas.width = width * pixelRatio
  110. canvas.height = height * pixelRatio
  111. this.signature.pen.getMaskedImageData((imageData)=>{
  112. ctx.putImageData(imageData, 0, 0);
  113. if(destWidth&&destHeight){
  114. const _canvas = document.createElement('canvas')
  115. _canvas.width = destWidth
  116. _canvas.height = destHeight
  117. const _context = _canvas.getContext('2d')
  118. _context.drawImage(canvas, 0, 0, destWidth, destHeight)
  119. canvas.remove()
  120. canvas = _canvas
  121. }
  122. const path = canvas.toDataURL();
  123. canvas.remove()
  124. if (typeof path == "string") {
  125. const index = Math.ceil(path.length / 8);
  126. for (var i = 0; i < 8; i++) {
  127. if (i == 7) {
  128. emit({"success": path.substr(i * index, index)});
  129. } else {
  130. emit({"file": path.substr(i * index, index)});
  131. }
  132. }
  133. } else {
  134. console.error("canvas no data");
  135. emit({"fail": "canvas no data"});
  136. }
  137. })
  138. }
  139. function save(param) {
  140. // delete param.success;
  141. // delete param.fail;
  142. clearTimeout(timer);
  143. timer = setTimeout(() => {
  144. let {fileType = 'png', quality = 1, n, destWidth=0, destHeight=0} = param
  145. const type = `image/${fileType}`.replace(/jpg/, 'jpeg');
  146. const {backgroundColor, landscape, boundingBox} = options
  147. const flag = backgroundColor || landscape || boundingBox||destWidth&&destHeight
  148. let path = canvasEl.toDataURL(!flag && type, !flag && quality)
  149. if(flag) {
  150. let canvas = document.createElement('canvas')
  151. const pixelRatio = signature.canvas.get('pixelRatio')
  152. let width = signature.canvas.get('width')
  153. let height = signature.canvas.get('height')
  154. let x = 0
  155. let y = 0
  156. const next = () => {
  157. const size = [width, height]
  158. if(landscape) {size.reverse()}
  159. canvas.width = size[0] * pixelRatio
  160. canvas.height = size[1] * pixelRatio
  161. const param = [x, y, width, height, 0 , 0, width, height].map(item => item * pixelRatio)
  162. const context = canvas.getContext('2d')
  163. // context.scale(pixelRatio, pixelRatio)
  164. if (landscape) {
  165. context.translate(0, width * pixelRatio)
  166. context.rotate(-Math.PI / 2)
  167. }
  168. if (backgroundColor && !isTransparent(backgroundColor)) {
  169. context.fillStyle = backgroundColor
  170. context.fillRect(0, 0, width * pixelRatio, height * pixelRatio)
  171. }
  172. const drawImage = ()=>{
  173. }
  174. // param
  175. context.drawImage(signature.canvas.get('el'), ...param)
  176. if(destWidth&&destHeight){
  177. const _canvas = document.createElement('canvas')
  178. _canvas.width = destWidth
  179. _canvas.height = destHeight
  180. const _context = _canvas.getContext('2d')
  181. _context.drawImage(canvas, 0, 0, destWidth, destHeight)
  182. canvas.remove()
  183. canvas = _canvas
  184. }
  185. path = canvas.toDataURL(type, quality)
  186. canvas.remove()
  187. }
  188. if(boundingBox) {
  189. const res = signature.getContentBoundingBox()
  190. width = res.width
  191. height = res.height
  192. x = res.startX
  193. y = res.startY
  194. next()
  195. } else {
  196. next()
  197. }
  198. }
  199. if (typeof path == "string") {
  200. const index = Math.ceil(path.length / 8);
  201. for (var i = 0; i < 8; i++) {
  202. if (i == 7) {
  203. emit({"success": path.substr(i * index, index)});
  204. } else {
  205. emit({"file": path.substr(i * index, index)});
  206. }
  207. }
  208. } else {
  209. console.error("canvas no data");
  210. emit({"fail": "canvas no data"});
  211. }
  212. }, 30);
  213. }
  214. </script>
  215. </body>
  216. </html>