{"version":3,"file":"useClips.mjs","sources":["../../../../../../../packages/components/watermark/src/useClips.ts"],"sourcesContent":["import { isArray } from '@hd-front-end/utils'\n\nimport type { WatermarkProps } from './watermark'\n\nexport const FontGap = 3\n\n// [alignRatio, spaceRatio]\nconst TEXT_ALIGN_RATIO_MAP = {\n  left: [0, 0.5],\n  start: [0, 0.5],\n  center: [0.5, 0],\n  right: [1, -0.5],\n  end: [1, -0.5],\n} as const\n\nfunction prepareCanvas(\n  width: number,\n  height: number,\n  ratio = 1\n): [\n  ctx: CanvasRenderingContext2D,\n  canvas: HTMLCanvasElement,\n  realWidth: number,\n  realHeight: number\n] {\n  const canvas = document.createElement('canvas')\n  const ctx = canvas.getContext('2d')!\n  const realWidth = width * ratio\n  const realHeight = height * ratio\n  canvas.setAttribute('width', `${realWidth}px`)\n  canvas.setAttribute('height', `${realHeight}px`)\n  ctx.save()\n\n  return [ctx, canvas, realWidth, realHeight]\n}\n\n/**\n * Get the clips of text content.\n * This is a lazy hook function since SSR no need this\n */\nexport default function useClips() {\n  // Get single clips\n  function getClips(\n    content: NonNullable<WatermarkProps['content']> | HTMLImageElement,\n    rotate: number,\n    ratio: number,\n    width: number,\n    height: number,\n    font: Required<NonNullable<WatermarkProps['font']>>,\n    gapX: number,\n    gapY: number,\n    space: number\n  ): [dataURL: string, finalWidth: number, finalHeight: number] {\n    // ================= Text / Image =================\n    const [ctx, canvas, contentWidth, contentHeight] = prepareCanvas(\n      width,\n      height,\n      ratio\n    )\n\n    if (content instanceof HTMLImageElement) {\n      // Image\n      ctx.drawImage(content, 0, 0, contentWidth, contentHeight)\n    } else {\n      // Text\n      const {\n        color,\n        fontSize,\n        fontStyle,\n        fontWeight,\n        fontFamily,\n        textAlign,\n        textBaseline,\n      } = font\n      const mergedFontSize = Number(fontSize) * ratio\n\n      ctx.font = `${fontStyle} normal ${fontWeight} ${mergedFontSize}px/${height}px ${fontFamily}`\n      ctx.fillStyle = color\n      ctx.textAlign = textAlign\n      ctx.textBaseline = textBaseline\n      const contents = isArray(content) ? content : [content]\n      contents?.forEach((item, index) => {\n        const [alignRatio, spaceRatio] = TEXT_ALIGN_RATIO_MAP[textAlign]\n        ctx.fillText(\n          item ?? '',\n          contentWidth * alignRatio + space * spaceRatio,\n          index * (mergedFontSize + FontGap * ratio)\n        )\n      })\n    }\n\n    // ==================== Rotate ====================\n    const angle = (Math.PI / 180) * Number(rotate)\n    const maxSize = Math.max(width, height)\n    const [rCtx, rCanvas, realMaxSize] = prepareCanvas(maxSize, maxSize, ratio)\n\n    // Copy from `ctx` and rotate\n    rCtx.translate(realMaxSize / 2, realMaxSize / 2)\n    rCtx.rotate(angle)\n    if (contentWidth > 0 && contentHeight > 0) {\n      rCtx.drawImage(canvas, -contentWidth / 2, -contentHeight / 2)\n    }\n\n    // Get boundary of rotated text\n    function getRotatePos(x: number, y: number) {\n      const targetX = x * Math.cos(angle) - y * Math.sin(angle)\n      const targetY = x * Math.sin(angle) + y * Math.cos(angle)\n      return [targetX, targetY]\n    }\n\n    let left = 0\n    let right = 0\n    let top = 0\n    let bottom = 0\n\n    const halfWidth = contentWidth / 2\n    const halfHeight = contentHeight / 2\n    const points = [\n      [0 - halfWidth, 0 - halfHeight],\n      [0 + halfWidth, 0 - halfHeight],\n      [0 + halfWidth, 0 + halfHeight],\n      [0 - halfWidth, 0 + halfHeight],\n    ]\n    points.forEach(([x, y]) => {\n      const [targetX, targetY] = getRotatePos(x, y)\n      left = Math.min(left, targetX)\n      right = Math.max(right, targetX)\n      top = Math.min(top, targetY)\n      bottom = Math.max(bottom, targetY)\n    })\n\n    const cutLeft = left + realMaxSize / 2\n    const cutTop = top + realMaxSize / 2\n    const cutWidth = right - left\n    const cutHeight = bottom - top\n\n    // ================ Fill Alternate ================\n    const realGapX = gapX * ratio\n    const realGapY = gapY * ratio\n    const filledWidth = (cutWidth + realGapX) * 2\n    const filledHeight = cutHeight + realGapY\n\n    const [fCtx, fCanvas] = prepareCanvas(filledWidth, filledHeight)\n\n    function drawImg(targetX = 0, targetY = 0) {\n      fCtx.drawImage(\n        rCanvas,\n        cutLeft,\n        cutTop,\n        cutWidth,\n        cutHeight,\n        targetX,\n        targetY,\n        cutWidth,\n        cutHeight\n      )\n    }\n    drawImg()\n    drawImg(cutWidth + realGapX, -cutHeight / 2 - realGapY / 2)\n    drawImg(cutWidth + realGapX, +cutHeight / 2 + realGapY / 2)\n\n    return [fCanvas.toDataURL(), filledWidth / ratio, filledHeight / ratio]\n  }\n\n  return getClips\n}\n"],"names":[],"mappings":"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"}