canvas.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. export const CircleImage = (ctx, img, x, y, r) => {
  2. ctx.save()
  3. ctx.beginPath()
  4. ctx.arc(x + r, y + r, r, 0, 2 * Math.PI)
  5. ctx.clip()
  6. ctx.drawImage(img, x, y, 2 * r, 2 * r)
  7. ctx.restore()
  8. }
  9. export class Canvas {
  10. context: UniApp.CanvasContext
  11. size: { width: number; height: number }
  12. designSize: { width?: number; height?: number }
  13. constructor(
  14. ctx: UniApp.CanvasContext,
  15. size: { width: number; height: number },
  16. designSize: { width?: number; height?: number },
  17. ) {
  18. this.context = ctx
  19. this.size = size
  20. this.designSize = designSize
  21. }
  22. px(designPx) {
  23. return (this.size.width / this.designSize.width) * designPx
  24. }
  25. /**
  26. * 绘制圆形
  27. */
  28. Circle(color, designX, designY, designR) {
  29. this.context.save()
  30. this.context.beginPath()
  31. this.context.arc(
  32. this.px(designX) + this.px(designR),
  33. this.px(designY) + this.px(designR),
  34. this.px(designR),
  35. 0,
  36. 2 * Math.PI,
  37. )
  38. this.context.setFillStyle(color)
  39. this.context.fill()
  40. }
  41. CircleImage(img, designX, designY, designR) {
  42. this.context.save()
  43. this.context.beginPath()
  44. this.context.arc(
  45. this.px(designX) + this.px(designR),
  46. this.px(designY) + this.px(designR),
  47. this.px(designR),
  48. 0,
  49. 2 * Math.PI,
  50. )
  51. this.context.clip()
  52. this.context.drawImage(
  53. img,
  54. this.px(designX),
  55. this.px(designY),
  56. 2 * this.px(designR),
  57. 2 * this.px(designR),
  58. )
  59. this.context.restore()
  60. }
  61. Image(img, designX, designY, designW, designH) {
  62. this.context.drawImage(
  63. img,
  64. this.px(designX),
  65. this.px(designY),
  66. this.px(designW),
  67. this.px(designH),
  68. )
  69. }
  70. FillImage(img) {
  71. this.context.drawImage(img, 0, 0, this.size.width, this.size.height)
  72. }
  73. FillText(text, color, designFontSize, designX, designY, align = 'left') {
  74. this.context.setFillStyle(color)
  75. this.context.setFontSize(this.px(designFontSize))
  76. if (align === 'center') {
  77. const textWidth = this.context.measureText(text).width
  78. designX = designX - textWidth / 2 / (this.size.width / this.designSize.width)
  79. }
  80. this.context.fillText(text, this.px(designX), this.px(designY))
  81. }
  82. /**
  83. * 绘制圆角矩形
  84. */
  85. RoundRect(color, designX, designY, designW, designH, designR) {
  86. this.context.save()
  87. this.context.beginPath()
  88. this.context.arc(
  89. this.px(designX) + this.px(designR),
  90. this.px(designY) + this.px(designR),
  91. this.px(designR),
  92. Math.PI,
  93. Math.PI * 1.5,
  94. )
  95. this.context.lineTo(this.px(designX) + this.px(designW) - this.px(designR), this.px(designY))
  96. this.context.arc(
  97. this.px(designX) + this.px(designW) - this.px(designR),
  98. this.px(designY) + this.px(designR),
  99. this.px(designR),
  100. Math.PI * 1.5,
  101. Math.PI * 2,
  102. )
  103. this.context.lineTo(
  104. this.px(designX) + this.px(designW),
  105. this.px(designY) + this.px(designH) - this.px(designR),
  106. )
  107. this.context.arc(
  108. this.px(designX) + this.px(designW) - this.px(designR),
  109. this.px(designY) + this.px(designH) - this.px(designR),
  110. this.px(designR),
  111. 0,
  112. Math.PI * 0.5,
  113. )
  114. this.context.lineTo(this.px(designX) + this.px(designR), this.px(designY) + this.px(designH))
  115. this.context.arc(
  116. this.px(designX) + this.px(designR),
  117. this.px(designY) + this.px(designH) - this.px(designR),
  118. this.px(designR),
  119. Math.PI * 0.5,
  120. Math.PI,
  121. )
  122. this.context.setFillStyle(color)
  123. this.context.fill()
  124. }
  125. /**
  126. * 绘制水平居中的一行多个不同样式的文本 例如:'文本1: 123, 文本2: 456'
  127. */
  128. FillTexts(textSegments: { text: string; font: string; color: string }[], designY): void {
  129. // Calculate total text width
  130. let totalWidth = 0
  131. textSegments.forEach((segment) => {
  132. this.context.font = segment.font
  133. totalWidth += this.context.measureText(segment.text).width
  134. })
  135. // Starting x position for centered text
  136. let startX = (this.size.width - totalWidth) / 2
  137. const y = this.px(designY) // Fixed vertical position
  138. // Draw each text segment
  139. textSegments.forEach((segment) => {
  140. this.context.font = segment.font
  141. this.context.fillStyle = segment.color
  142. this.context.fillText(segment.text, startX, y)
  143. startX += this.context.measureText(segment.text).width // Move x position for next segment
  144. })
  145. }
  146. }