wx-canvas.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. export default class WxCanvas {
  2. ctx;
  3. type;
  4. canvasId;
  5. canvasNode;
  6. stepList = [];
  7. canvasPrototype = {};
  8. constructor(type, ctx, canvasId, isNew, canvasNode) {
  9. this.ctx = ctx;
  10. this.canvasId = canvasId;
  11. this.type = type;
  12. if (isNew) {
  13. this.canvasNode = canvasNode || {};
  14. }
  15. }
  16. // 通用的属性设置器
  17. _setProperty(name, value) {
  18. this.canvasPrototype[name] = value;
  19. this.stepList.push({ action: name, args: value, actionType: 'set' });
  20. }
  21. // 通用的方法调用器
  22. _callMethod(name, ...args) {
  23. this.stepList.push({ action: name, args, actionType: 'func' });
  24. }
  25. // 简化的属性访问器
  26. get width() { return this.canvasNode?.width || 0; }
  27. set width(w) { if (this.canvasNode) this.canvasNode.width = w; }
  28. get height() { return this.canvasNode?.height || 0; }
  29. set height(h) { if (this.canvasNode) this.canvasNode.height = h; }
  30. // 简化的属性访问器
  31. get lineWidth() { return this.canvasPrototype.lineWidth; }
  32. set lineWidth(v) { this._setProperty('lineWidth', v); }
  33. get lineCap() { return this.canvasPrototype.lineCap; }
  34. set lineCap(v) { this._setProperty('lineCap', v); }
  35. get lineJoin() { return this.canvasPrototype.lineJoin; }
  36. set lineJoin(v) { this._setProperty('lineJoin', v); }
  37. get miterLimit() { return this.canvasPrototype.miterLimit; }
  38. set miterLimit(v) { this._setProperty('miterLimit', v); }
  39. get lineDashOffset() { return this.canvasPrototype.lineDashOffset; }
  40. set lineDashOffset(v) { this._setProperty('lineDashOffset', v); }
  41. get font() { return this.canvasPrototype.font; }
  42. set font(v) { this.ctx.font = v; this._setProperty('font', v); }
  43. get textAlign() { return this.canvasPrototype.textAlign; }
  44. set textAlign(v) { this._setProperty('textAlign', v); }
  45. get textBaseline() { return this.canvasPrototype.textBaseline; }
  46. set textBaseline(v) { this._setProperty('textBaseline', v); }
  47. get fillStyle() { return this.canvasPrototype.fillStyle; }
  48. set fillStyle(v) { this._setProperty('fillStyle', v); }
  49. get strokeStyle() { return this.canvasPrototype.strokeStyle; }
  50. set strokeStyle(v) { this._setProperty('strokeStyle', v); }
  51. get globalAlpha() { return this.canvasPrototype.globalAlpha; }
  52. set globalAlpha(v) { this._setProperty('globalAlpha', v); }
  53. get globalCompositeOperation() { return this.canvasPrototype.globalCompositeOperation; }
  54. set globalCompositeOperation(v) { this._setProperty('globalCompositeOperation', v); }
  55. get shadowColor() { return this.canvasPrototype.shadowColor; }
  56. set shadowColor(v) { this._setProperty('shadowColor', v); }
  57. get shadowOffsetX() { return this.canvasPrototype.shadowOffsetX; }
  58. set shadowOffsetX(v) { this._setProperty('shadowOffsetX', v); }
  59. get shadowOffsetY() { return this.canvasPrototype.shadowOffsetY; }
  60. set shadowOffsetY(v) { this._setProperty('shadowOffsetY', v); }
  61. get shadowBlur() { return this.canvasPrototype.shadowBlur; }
  62. set shadowBlur(v) { this._setProperty('shadowBlur', v); }
  63. // 简化的方法调用
  64. save() { this._callMethod('save'); }
  65. restore() { this._callMethod('restore'); }
  66. setLineDash(...args) { this.canvasPrototype.lineDash = args; this._callMethod('setLineDash', ...args); }
  67. moveTo(...args) { this._callMethod('moveTo', ...args); }
  68. closePath() { this._callMethod('closePath'); }
  69. lineTo(...args) { this._callMethod('lineTo', ...args); }
  70. quadraticCurveTo(...args) { this._callMethod('quadraticCurveTo', ...args); }
  71. bezierCurveTo(...args) { this._callMethod('bezierCurveTo', ...args); }
  72. arcTo(...args) { this._callMethod('arcTo', ...args); }
  73. arc(...args) { this._callMethod('arc', ...args); }
  74. rect(...args) { this._callMethod('rect', ...args); }
  75. scale(...args) { this._callMethod('scale', ...args); }
  76. rotate(...args) { this._callMethod('rotate', ...args); }
  77. translate(...args) { this._callMethod('translate', ...args); }
  78. transform(...args) { this._callMethod('transform', ...args); }
  79. setTransform(...args) { this._callMethod('setTransform', ...args); }
  80. clearRect(...args) { this._callMethod('clearRect', ...args); }
  81. fillRect(...args) { this._callMethod('fillRect', ...args); }
  82. strokeRect(...args) { this._callMethod('strokeRect', ...args); }
  83. fillText(...args) { this._callMethod('fillText', ...args); }
  84. strokeText(...args) { this._callMethod('strokeText', ...args); }
  85. beginPath() { this._callMethod('beginPath'); }
  86. fill() { this._callMethod('fill'); }
  87. stroke() { this._callMethod('stroke'); }
  88. drawFocusIfNeeded(...args) { this._callMethod('drawFocusIfNeeded', ...args); }
  89. clip() { this._callMethod('clip'); }
  90. isPointInPath(...args) { this._callMethod('isPointInPath', ...args); }
  91. drawImage(...args) { this._callMethod('drawImage', ...args); }
  92. addHitRegion(...args) { this._callMethod('addHitRegion', ...args); }
  93. removeHitRegion(...args) { this._callMethod('removeHitRegion', ...args); }
  94. clearHitRegions(...args) { this._callMethod('clearHitRegions', ...args); }
  95. putImageData(...args) { this._callMethod('putImageData', ...args); }
  96. // 直接返回的方法
  97. getLineDash() { return this.canvasPrototype.lineDash; }
  98. createLinearGradient(...args) { return this.ctx.createLinearGradient(...args); }
  99. createRadialGradient(...args) {
  100. return this.type === '2d'
  101. ? this.ctx.createRadialGradient(...args)
  102. : this.ctx.createCircularGradient(...args.slice(3, 6));
  103. }
  104. createPattern(...args) { return this.ctx.createPattern(...args); }
  105. measureText(...args) { return this.ctx.measureText(...args); }
  106. createImageData(...args) { return this.ctx.createImageData(...args); }
  107. getImageData(...args) { return this.ctx.getImageData(...args); }
  108. async draw(reserve, func) {
  109. const realstepList = this.stepList.slice();
  110. this.stepList.length = 0;
  111. if (this.type === '2d') {
  112. if (!reserve) {
  113. this.ctx.clearRect(0, 0, this.canvasNode.width, this.canvasNode.height);
  114. }
  115. if (realstepList.length > 0) {
  116. for (const step of realstepList) {
  117. await this.implement2DStep(step);
  118. }
  119. }
  120. if (func) func();
  121. }else {
  122. if (realstepList.length > 0) {
  123. for (const step of realstepList) {
  124. this.implementMinaStep(step);
  125. }
  126. }
  127. this.ctx.draw(reserve, func);
  128. }
  129. }
  130. implementMinaStep(step) {
  131. if (step.action === 'textAlign') {
  132. this.ctx.setTextAlign(step.args);
  133. } else if (step.action === 'textBaseline') {
  134. this.ctx.setTextBaseline(step.args);
  135. } else if (step.actionType === 'set') {
  136. this.ctx[step.action] = step.args;
  137. } else if (step.actionType === 'func') {
  138. step.args ? this.ctx[step.action](...step.args) : this.ctx[step.action]();
  139. }
  140. }
  141. implement2DStep(step) {
  142. return new Promise((resolve) => {
  143. if (step.action === 'drawImage') {
  144. const img = this.canvasNode.createImage();
  145. img.src = step.args[0];
  146. img.onload = () => {
  147. this.ctx.drawImage(img, ...step.args.slice(1));
  148. resolve(undefined);
  149. };
  150. } else {
  151. if (step.actionType === 'set') {
  152. this.ctx[step.action] = step.args;
  153. } else if (step.actionType === 'func') {
  154. step.args ? this.ctx[step.action](...step.args) : this.ctx[step.action]();
  155. }
  156. resolve(undefined);
  157. }
  158. });
  159. }
  160. }