testPrintCanvas.ts 4.13 KB
import type { RawImageDataSource } from './types/printer'

export function getTestPrintCanvasSize (maxWidthDots = 384): { width: number, height: number } {
  const width = Math.max(256, Math.round(maxWidthDots || 384) - (Math.round(maxWidthDots || 384) % 8))
  const height = Math.max(220, Math.round(width * 0.62))
  return { width, height }
}

function drawRoundedRect (
  ctx: UniNamespace.CanvasContext,
  x: number,
  y: number,
  width: number,
  height: number,
  radius: number
) {
  const r = Math.max(0, Math.min(radius, Math.min(width, height) / 2))
  ctx.beginPath()
  ctx.moveTo(x + r, y)
  ctx.lineTo(x + width - r, y)
  ctx.arcTo(x + width, y, x + width, y + r, r)
  ctx.lineTo(x + width, y + height - r)
  ctx.arcTo(x + width, y + height, x + width - r, y + height, r)
  ctx.lineTo(x + r, y + height)
  ctx.arcTo(x, y + height, x, y + height - r, r)
  ctx.lineTo(x, y + r)
  ctx.arcTo(x, y, x + r, y, r)
  ctx.closePath()
}

export async function renderTestPrintCanvasImageData (
  canvasId: string,
  componentInstance: any,
  size: { width: number, height: number }
): Promise<RawImageDataSource> {
  const width = Math.max(8, size.width - (size.width % 8))
  const height = Math.max(1, size.height)
  const scale = width / 800
  const ctx = uni.createCanvasContext(canvasId, componentInstance)

  ctx.setFillStyle('#ffffff')
  ctx.fillRect(0, 0, width, height)

  drawRoundedRect(ctx, 10 * scale, 10 * scale, width - 20 * scale, height - 20 * scale, 18 * scale)
  ctx.setLineWidth(Math.max(2, 3 * scale))
  ctx.setStrokeStyle('#111111')
  ctx.stroke()

  ctx.setFillStyle('#111111')
  ctx.setFontSize(Math.max(22, Math.round(width * 0.045)))
  ctx.fillText('IN USE FOOD LABEL', 26 * scale, 44 * scale)

  ctx.setLineWidth(Math.max(1, 2 * scale))
  ctx.beginPath()
  ctx.moveTo(24 * scale, 62 * scale)
  ctx.lineTo(width - 24 * scale, 62 * scale)
  ctx.stroke()

  ctx.setFontSize(Math.max(18, Math.round(width * 0.036)))
  ctx.fillText('Product', 26 * scale, 96 * scale)
  ctx.setFontSize(Math.max(20, Math.round(width * 0.04)))
  ctx.fillText('Grilled Chicken Breast', 26 * scale, 128 * scale)

  ctx.setFontSize(Math.max(17, Math.round(width * 0.034)))
  ctx.fillText('Prepared Protein / Hot Prep', 26 * scale, 162 * scale)
  ctx.fillText('Prepared: 03/20/2026 10:30 AM', 26 * scale, 220 * scale)
  ctx.fillText('Use By : 03/23/2026 10:30 AM', 26 * scale, 268 * scale)
  ctx.fillText('Shelf Life: 72 Hours', 26 * scale, 316 * scale)

  const rightX = 540 * scale
  ctx.setFontSize(Math.max(18, Math.round(width * 0.035)))
  ctx.fillText('Label ID', rightX, 96 * scale)
  ctx.setFontSize(Math.max(16, Math.round(width * 0.03)))
  ctx.fillText('TEST-260320-001', rightX, 128 * scale)
  ctx.fillText('Status: ACTIVE', rightX, 238 * scale)
  ctx.fillText('Station: LINE 1', rightX, 286 * scale)
  ctx.fillText('User: TEST USER', rightX, 334 * scale)

  const qrX = rightX
  const qrY = 148 * scale
  const qrSize = Math.round(120 * scale)
  ctx.setLineWidth(Math.max(2, 3 * scale))
  ctx.strokeRect(qrX, qrY, qrSize, qrSize)
  ctx.strokeRect(qrX + 10 * scale, qrY + 10 * scale, 20 * scale, 20 * scale)
  ctx.strokeRect(qrX + qrSize - 30 * scale, qrY + 10 * scale, 20 * scale, 20 * scale)
  ctx.strokeRect(qrX + 10 * scale, qrY + qrSize - 30 * scale, 20 * scale, 20 * scale)
  ctx.fillRect(qrX + 42 * scale, qrY + 18 * scale, 12 * scale, 12 * scale)
  ctx.fillRect(qrX + 58 * scale, qrY + 34 * scale, 8 * scale, 8 * scale)
  ctx.fillRect(qrX + 46 * scale, qrY + 54 * scale, 10 * scale, 10 * scale)
  ctx.fillRect(qrX + 68 * scale, qrY + 68 * scale, 12 * scale, 12 * scale)
  ctx.fillRect(qrX + 50 * scale, qrY + 84 * scale, 8 * scale, 8 * scale)

  await new Promise<void>((resolve) => {
    ctx.draw(false, () => resolve())
  })

  await new Promise<void>((resolve) => setTimeout(resolve, 30))

  return new Promise((resolve, reject) => {
    uni.canvasGetImageData({
      canvasId,
      x: 0,
      y: 0,
      width,
      height,
      success: (res: any) => {
        resolve({
          width,
          height,
          data: res.data,
        })
      },
      fail: (err: any) => {
        reject(new Error(err?.errMsg || 'CANVAS_GET_IMAGE_DATA_FAILED'))
      },
    }, componentInstance)
  })
}