export const CircleImage = (ctx, img, x, y, r) => { ctx.save() ctx.beginPath() ctx.arc(x + r, y + r, r, 0, 2 * Math.PI) ctx.clip() ctx.drawImage(img, x, y, 2 * r, 2 * r) ctx.restore() } export class Canvas { context: UniApp.CanvasContext size: { width: number; height: number } designSize: { width?: number; height?: number } constructor( ctx: UniApp.CanvasContext, size: { width: number; height: number }, designSize: { width?: number; height?: number }, ) { this.context = ctx this.size = size this.designSize = designSize } px(designPx) { return (this.size.width / this.designSize.width) * designPx } /** * 绘制圆形 */ Circle(color, designX, designY, designR) { this.context.save() this.context.beginPath() this.context.arc( this.px(designX) + this.px(designR), this.px(designY) + this.px(designR), this.px(designR), 0, 2 * Math.PI, ) this.context.setFillStyle(color) this.context.fill() } CircleImage(img, designX, designY, designR) { this.context.save() this.context.beginPath() this.context.arc( this.px(designX) + this.px(designR), this.px(designY) + this.px(designR), this.px(designR), 0, 2 * Math.PI, ) this.context.clip() this.context.drawImage( img, this.px(designX), this.px(designY), 2 * this.px(designR), 2 * this.px(designR), ) this.context.restore() } Image(img, designX, designY, designW, designH) { this.context.drawImage( img, this.px(designX), this.px(designY), this.px(designW), this.px(designH), ) } FillImage(img) { this.context.drawImage(img, 0, 0, this.size.width, this.size.height) } FillText(text, color, designFontSize, designX, designY, align = 'left') { this.context.setFillStyle(color) this.context.setFontSize(this.px(designFontSize)) if (align === 'center') { const textWidth = this.context.measureText(text).width designX = designX - textWidth / 2 / (this.size.width / this.designSize.width) } this.context.fillText(text, this.px(designX), this.px(designY)) } /** * 绘制圆角矩形 */ RoundRect(color, designX, designY, designW, designH, designR) { this.context.save() this.context.beginPath() this.context.arc( this.px(designX) + this.px(designR), this.px(designY) + this.px(designR), this.px(designR), Math.PI, Math.PI * 1.5, ) this.context.lineTo(this.px(designX) + this.px(designW) - this.px(designR), this.px(designY)) this.context.arc( this.px(designX) + this.px(designW) - this.px(designR), this.px(designY) + this.px(designR), this.px(designR), Math.PI * 1.5, Math.PI * 2, ) this.context.lineTo( this.px(designX) + this.px(designW), this.px(designY) + this.px(designH) - this.px(designR), ) this.context.arc( this.px(designX) + this.px(designW) - this.px(designR), this.px(designY) + this.px(designH) - this.px(designR), this.px(designR), 0, Math.PI * 0.5, ) this.context.lineTo(this.px(designX) + this.px(designR), this.px(designY) + this.px(designH)) this.context.arc( this.px(designX) + this.px(designR), this.px(designY) + this.px(designH) - this.px(designR), this.px(designR), Math.PI * 0.5, Math.PI, ) this.context.setFillStyle(color) this.context.fill() } /** * 绘制水平居中的一行多个不同样式的文本 例如:'文本1: 123, 文本2: 456' */ FillTexts(textSegments: { text: string; font: string; color: string }[], designY): void { // Calculate total text width let totalWidth = 0 textSegments.forEach((segment) => { this.context.font = segment.font totalWidth += this.context.measureText(segment.text).width }) // Starting x position for centered text let startX = (this.size.width - totalWidth) / 2 const y = this.px(designY) // Fixed vertical position // Draw each text segment textSegments.forEach((segment) => { this.context.font = segment.font this.context.fillStyle = segment.color this.context.fillText(segment.text, startX, y) startX += this.context.measureText(segment.text).width // Move x position for next segment }) } }