{"version":3,"file":"av-canvas.umd.cjs","sources":["../src/types.ts","../src/utils.ts","../src/sprites/sprite-manager.ts","../src/sprites/render-ctrl.ts","../src/sprites/sprite-op.ts","../src/av-canvas.ts"],"sourcesContent":["import { Rect } from '@fly-cut/av-cliper';\n\n/**\n * 二维坐标系中的点\n */\nexport interface IPoint {\n  x: number;\n  y: number;\n}\n\n/**\n * 锚点（坐标系原点）\n */\nexport interface IAnchor extends IPoint {}\n\n/**\n * 分辨率（尺寸）\n */\nexport interface IResolution {\n  width: number;\n  height: number;\n}\n\n/**\n * 画布分辨率与实际宽高的比例\n */\nexport interface ICvsRatio {\n  w: number;\n  h: number;\n}\n\n/**\n * 控制点：上、下、左、右，左上、左下、右上、右下、旋转\n * 当 Rect 只允许等比例缩放时（{@link Rect.fixedAspectRatio} = true），缺少 t、b、l、r 四个控制点\n */\nexport type RectCtrls = Partial<Record<'t' | 'b' | 'l' | 'r', Rect>> &\n  Record<'lt' | 'lb' | 'rt' | 'rb' | 'rotate', Rect>;\n\nexport const CTRL_KEYS = [\n  't',\n  'b',\n  'l',\n  'r',\n  'lt',\n  'lb',\n  'rt',\n  'rb',\n  'rotate',\n] as const;\n\nexport type TCtrlKey = (typeof CTRL_KEYS)[number];\n","import { Rect } from '@fly-cut/av-cliper';\nimport { RectCtrls } from './types';\n\nexport function createEl(tagName: string): HTMLElement {\n  return document.createElement(tagName);\n}\n\n/**\n * 根据 canvas 创建该画布上的 Sprite 控制点生成器\n * 因为控制点的大小需要根据画布的大小动态调整\n */\nexport function createCtrlsGetter(cvsEl: HTMLCanvasElement) {\n  let ctrlSize = 16;\n  const cvsResizeOb = new ResizeObserver((entries) => {\n    const fisrtEntry = entries[0];\n    if (fisrtEntry == null) return;\n    ctrlSize = 10 / (fisrtEntry.contentRect.width / cvsEl.width);\n  });\n  cvsResizeOb.observe(cvsEl);\n  function rectCtrlsGetter(rect: Rect): RectCtrls {\n    const { w, h } = rect;\n    // 控制点元素大小, 以 分辨率 为基准\n    const sz = ctrlSize;\n    // half size\n    const hfSz = sz / 2;\n    const hfW = w / 2;\n    const hfH = h / 2;\n    // rotate size\n    const rtSz = sz * 1.5;\n    const hfRtSz = rtSz / 2;\n    // ctrl 坐标是相对于 sprite 中心点\n    const tblr = rect.fixedAspectRatio\n      ? {}\n      : {\n          t: new Rect(-hfSz, -hfH - hfSz, sz, sz, rect),\n          b: new Rect(-hfSz, hfH - hfSz, sz, sz, rect),\n          l: new Rect(-hfW - hfSz, -hfSz, sz, sz, rect),\n          r: new Rect(hfW - hfSz, -hfSz, sz, sz, rect),\n        };\n    return {\n      ...tblr,\n      lt: new Rect(-hfW - hfSz, -hfH - hfSz, sz, sz, rect),\n      lb: new Rect(-hfW - hfSz, hfH - hfSz, sz, sz, rect),\n      rt: new Rect(hfW - hfSz, -hfH - hfSz, sz, sz, rect),\n      rb: new Rect(hfW - hfSz, hfH - hfSz, sz, sz, rect),\n      rotate: new Rect(-hfRtSz, -hfH - sz * 2 - hfRtSz, rtSz, rtSz, rect),\n    };\n  }\n  return {\n    rectCtrlsGetter,\n    destroy: () => {\n      cvsResizeOb.disconnect();\n    },\n  };\n}\n","import { VisibleSprite } from '@fly-cut/av-cliper';\nimport { EventTool } from '@fly-cut/internal-utils';\n\nexport enum ESpriteManagerEvt {\n  ActiveSpriteChange = 'activeSpriteChange',\n  AddSprite = 'addSprite',\n}\n\nexport class SpriteManager {\n  #sprites: VisibleSprite[] = [];\n\n  #activeSprite: VisibleSprite | null = null;\n\n  #evtTool = new EventTool<{\n    [ESpriteManagerEvt.AddSprite]: (s: VisibleSprite) => void;\n    [ESpriteManagerEvt.ActiveSpriteChange]: (s: VisibleSprite | null) => void;\n  }>();\n\n  on = this.#evtTool.on;\n\n  get activeSprite(): VisibleSprite | null {\n    return this.#activeSprite;\n  }\n  set activeSprite(s: VisibleSprite | null) {\n    if (s === this.#activeSprite) return;\n    this.#activeSprite = s;\n    this.#evtTool.emit(ESpriteManagerEvt.ActiveSpriteChange, s);\n  }\n\n  async addSprite(vs: VisibleSprite): Promise<void> {\n    await vs.ready;\n    this.#sprites.push(vs);\n    this.#sprites = this.#sprites.sort((a, b) => a.zIndex - b.zIndex);\n    vs.on('propsChange', (props) => {\n      if (props.zIndex == null) return;\n      this.#sprites = this.#sprites.sort((a, b) => a.zIndex - b.zIndex);\n    });\n\n    this.#evtTool.emit(ESpriteManagerEvt.AddSprite, vs);\n  }\n\n  removeSprite(spr: VisibleSprite): void {\n    if (this.#activeSprite === spr) this.activeSprite = null;\n    this.#sprites = this.#sprites.filter((s) => s !== spr);\n    spr.destroy();\n  }\n\n  getSprites(filter: { time: boolean } = { time: true }): VisibleSprite[] {\n    return this.#sprites.filter(\n      (s) =>\n        s.visible &&\n        (filter.time\n          ? this.#renderTime >= s.time.offset &&\n            this.#renderTime <= s.time.offset + s.time.duration\n          : true),\n    );\n  }\n\n  #renderTime = 0;\n  updateRenderTime(time: number) {\n    this.#renderTime = time;\n\n    // 避免素材不可见，但渲染了素材边框控制点\n    const as = this.activeSprite;\n    if (\n      as != null &&\n      (time < as.time.offset || time > as.time.offset + as.time.duration)\n    ) {\n      this.activeSprite = null;\n    }\n  }\n\n  destroy(): void {\n    this.#evtTool.destroy();\n    this.#sprites.forEach((s) => s.destroy());\n    this.#sprites = [];\n  }\n}\n","import { CTRL_KEYS, ICvsRatio, RectCtrls, TCtrlKey } from '../types';\nimport { createEl } from '../utils';\nimport { VisibleSprite, Rect } from '@fly-cut/av-cliper';\nimport { ESpriteManagerEvt, SpriteManager } from './sprite-manager';\n\nexport function renderCtrls(\n  container: HTMLElement,\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n  rectCtrlsGetter: (rect: Rect) => RectCtrls,\n): () => void {\n  const cvsRatio = {\n    w: cvsEl.clientWidth / cvsEl.width,\n    h: cvsEl.clientHeight / cvsEl.height,\n  };\n\n  const observer = new ResizeObserver(() => {\n    cvsRatio.w = cvsEl.clientWidth / cvsEl.width;\n    cvsRatio.h = cvsEl.clientHeight / cvsEl.height;\n\n    if (sprMng.activeSprite == null) return;\n    syncCtrlElPos(\n      sprMng.activeSprite,\n      rectEl,\n      ctrlsEl,\n      cvsRatio,\n      rectCtrlsGetter,\n      cvsEl,\n    );\n  });\n\n  observer.observe(cvsEl);\n\n  let lastActSprEvtClear = () => {};\n  const { rectEl, ctrlsEl } = createRectAndCtrlEl(container);\n  const offSprChange = sprMng.on(ESpriteManagerEvt.ActiveSpriteChange, (s) => {\n    // 每次变更，需要清理上一个事件监听器\n    lastActSprEvtClear();\n    if (s == null) {\n      rectEl.style.display = 'none';\n      return;\n    }\n    syncCtrlElPos(s, rectEl, ctrlsEl, cvsRatio, rectCtrlsGetter, cvsEl);\n    lastActSprEvtClear = s.on('propsChange', () => {\n      syncCtrlElPos(s, rectEl, ctrlsEl, cvsRatio, rectCtrlsGetter, cvsEl);\n    });\n    rectEl.style.display = '';\n  });\n\n  return () => {\n    observer.disconnect();\n    offSprChange();\n    rectEl.remove();\n    lastActSprEvtClear();\n  };\n}\n\nfunction createRectAndCtrlEl(container: HTMLElement): {\n  rectEl: HTMLElement;\n  ctrlsEl: Record<TCtrlKey, HTMLElement>;\n} {\n  const rectEl = createEl('div');\n  rectEl.style.cssText = `\n    position: absolute;\n    pointer-events: none;\n    border: 1px solid #eee;\n    box-sizing: border-box;\n    display: none;\n  `;\n  const ctrlsEl = Object.fromEntries(\n    CTRL_KEYS.map((k) => {\n      const d = createEl('div');\n      d.style.cssText = `\n        display: none;\n        position: absolute;\n        border: 1px solid #3ee; border-radius: 50%;\n        box-sizing: border-box;\n        background-color: #fff;\n      `;\n      return [k, d];\n    }),\n  ) as Record<TCtrlKey, HTMLElement>;\n\n  Object.values(ctrlsEl).forEach((d) => rectEl.appendChild(d));\n  container.appendChild(rectEl);\n  return {\n    rectEl,\n    ctrlsEl,\n  };\n}\n\nfunction syncCtrlElPos(\n  s: VisibleSprite,\n  rectEl: HTMLElement,\n  ctrlsEl: Record<TCtrlKey, HTMLElement>,\n  cvsRatio: ICvsRatio,\n  rectCtrlsGetter: (rect: Rect) => RectCtrls,\n  cvsEl: HTMLCanvasElement,\n): void {\n  const { x, y, w, h, angle } = s.rect;\n\n  // 计算画布中心在容器坐标系中的坐标\n  const cvsCenterXInContainer = (cvsEl.width / 2) * cvsRatio.w;\n  const cvsCenterYInContainer = (cvsEl.height / 2) * cvsRatio.h;\n\n  // VisibleSprite 的 rect.x, rect.y 是其中心点相对于画布中心的坐标。\n  // 计算 VisibleSprite 视觉左上角相对于画布中心的坐标。\n  const visualLeftXInCanvasCenter = x - w / 2;\n  const visualTopYInCanvasCenter = y - h / 2;\n\n  // 将 VisibleSprite 视觉左上角坐标从画布中心坐标系转换到容器左上角坐标系。\n  Object.assign(rectEl.style, {\n    left: `${cvsCenterXInContainer + visualLeftXInCanvasCenter * cvsRatio.w}px`,\n    top: `${cvsCenterYInContainer + visualTopYInCanvasCenter * cvsRatio.h}px`,\n    width: `${w * cvsRatio.w}px`,\n    height: `${h * cvsRatio.h}px`,\n    rotate: `${angle}rad`,\n  });\n  Object.entries(rectCtrlsGetter(s.rect)).forEach(([k, { x, y, w, h }]) => {\n    // ctrl 是相对中心点定位的\n    Object.assign(ctrlsEl[k as TCtrlKey].style, {\n      display: 'block',\n      left: '50%',\n      top: '50%',\n      width: `${w * cvsRatio.w}px`,\n      height: `${h * cvsRatio.h}px`,\n      // border 1px, 所以要 -1\n      transform: `translate(${x * cvsRatio.w}px, ${y * cvsRatio.h}px)`,\n    });\n  });\n}\n","import { ESpriteManagerEvt, SpriteManager } from './sprite-manager';\nimport { ICvsRatio, IPoint, RectCtrls, TCtrlKey } from '../types';\nimport { VisibleSprite, Rect } from '@fly-cut/av-cliper';\nimport { createEl } from '../utils';\n\n/**\n * 鼠标点击，激活 sprite\n */\nexport function activeSprite(\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n  rectCtrlsGetter: (rect: Rect) => RectCtrls,\n): () => void {\n  const cvsRatio = {\n    w: cvsEl.clientWidth / cvsEl.width,\n    h: cvsEl.clientHeight / cvsEl.height,\n  };\n\n  const observer = new ResizeObserver(() => {\n    cvsRatio.w = cvsEl.clientWidth / cvsEl.width;\n    cvsRatio.h = cvsEl.clientHeight / cvsEl.height;\n  });\n  observer.observe(cvsEl);\n\n  const onCvsMouseDown = (evt: MouseEvent): void => {\n    if (evt.button !== 0) return;\n    const { offsetX, offsetY } = evt;\n    const ofx = offsetX / cvsRatio.w;\n    const ofy = offsetY / cvsRatio.h;\n    // 转换为相对于画布中心的坐标\n    const cx = ofx - cvsEl.width / 2;\n    const cy = ofy - cvsEl.height / 2;\n\n    if (sprMng.activeSprite != null) {\n      const [ctrlKey] =\n        (Object.entries(rectCtrlsGetter(sprMng.activeSprite.rect)).find(\n          ([, rect]) => rect.checkHit(cx, cy),\n        ) as [TCtrlKey, Rect]) ?? [];\n      if (ctrlKey != null) return;\n    }\n    sprMng.activeSprite =\n      sprMng\n        .getSprites()\n        // 排在后面的层级更高\n        .reverse()\n        .find((s) => s.visible && s.selectable && s.rect.checkHit(cx, cy)) ??\n      null;\n  };\n\n  cvsEl.addEventListener('pointerdown', onCvsMouseDown);\n\n  return () => {\n    observer.disconnect();\n    cvsEl.removeEventListener('pointerdown', onCvsMouseDown);\n  };\n}\n\n/**\n * 让canvas中的sprite可以被拖拽移动\n */\nexport function draggabelSprite(\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n  container: HTMLElement,\n  rectCtrlsGetter: (rect: Rect) => RectCtrls,\n): () => void {\n  const cvsRatio = {\n    w: cvsEl.clientWidth / cvsEl.width,\n    h: cvsEl.clientHeight / cvsEl.height,\n  };\n\n  const observer = new ResizeObserver(() => {\n    cvsRatio.w = cvsEl.clientWidth / cvsEl.width;\n    cvsRatio.h = cvsEl.clientHeight / cvsEl.height;\n  });\n  observer.observe(cvsEl);\n\n  let startX = 0;\n  let startY = 0;\n  let startRect: Rect | null = null;\n\n  const refline = createRefline(cvsEl, container);\n\n  let hitSpr: VisibleSprite | null = null;\n  // sprMng.activeSprite 在 av-canvas.ts -> activeSprite 中被赋值\n  const onCvsMouseDown = (evt: MouseEvent): void => {\n    // 鼠标左键才能拖拽移动\n    if (evt.button !== 0 || sprMng.activeSprite == null) return;\n    hitSpr = sprMng.activeSprite;\n    const { offsetX, offsetY, clientX, clientY } = evt;\n    // 如果已有激活 sprite，先判定是否命中其 ctrls\n    if (\n      hitRectCtrls({\n        rect: hitSpr.rect,\n        offsetX,\n        offsetY,\n        clientX,\n        clientY,\n        cvsRatio,\n        cvsEl,\n        rectCtrlsGetter,\n      })\n    ) {\n      // 命中 ctrl 是缩放 sprite，略过后续移动 sprite 逻辑\n      return;\n    }\n\n    startRect = hitSpr.rect.clone();\n\n    refline.magneticEffect(hitSpr.rect.x, hitSpr.rect.y, hitSpr.rect);\n\n    startX = clientX;\n    startY = clientY;\n    window.addEventListener('pointermove', onMouseMove);\n    window.addEventListener('pointerup', clearWindowEvt);\n  };\n\n  const onMouseMove = (evt: MouseEvent): void => {\n    if (hitSpr == null || startRect == null) return;\n\n    const { clientX, clientY } = evt;\n    let expectX = startRect.x + (clientX - startX) / cvsRatio.w;\n    let expectY = startRect.y + (clientY - startY) / cvsRatio.h;\n\n    updateRectWithSafeMargin(\n      hitSpr.rect,\n      cvsEl,\n      refline.magneticEffect(expectX, expectY, hitSpr.rect),\n    );\n  };\n\n  cvsEl.addEventListener('pointerdown', onCvsMouseDown);\n\n  const clearWindowEvt = (): void => {\n    refline.hide();\n    window.removeEventListener('pointermove', onMouseMove);\n    window.removeEventListener('pointerup', clearWindowEvt);\n  };\n\n  return () => {\n    observer.disconnect();\n    refline.destroy();\n    clearWindowEvt();\n    cvsEl.removeEventListener('pointerdown', onCvsMouseDown);\n  };\n}\n\n/**\n * 缩放 sprite\n */\nfunction scaleRect({\n  sprRect,\n  startX,\n  startY,\n  ctrlKey,\n  cvsRatio,\n  cvsEl,\n}: {\n  sprRect: Rect;\n  startX: number;\n  startY: number;\n  ctrlKey: TCtrlKey;\n  cvsRatio: ICvsRatio;\n  cvsEl: HTMLCanvasElement;\n}): void {\n  const startRect = sprRect.clone();\n\n  const onMouseMove = (evt: MouseEvent): void => {\n    const { clientX, clientY } = evt;\n    const deltaX = (clientX - startX) / cvsRatio.w;\n    const deltaY = (clientY - startY) / cvsRatio.h;\n\n    // 对角线上的点是等比例缩放，key 的长度为 2\n    const scaler = ctrlKey.length === 1 ? stretchScale : fixedRatioScale;\n    const { x, y, w, h } = startRect;\n    // rect 对角线角度\n    const diagonalAngle = Math.atan2(h, w);\n    const { incW, incH, incS, rotateAngle } = scaler({\n      deltaX,\n      deltaY,\n      angle: sprRect.angle,\n      ctrlKey,\n      diagonalAngle,\n    });\n\n    // 最小宽高缩放限定\n    const minSize = 10;\n    let newW = w;\n    let newH = h;\n    // 中心点缩放时，宽高增量是原来的两倍\n    let newIncW = startRect.fixedScaleCenter ? incW * 2 : incW;\n    let newIncH = startRect.fixedScaleCenter ? incH * 2 : incH;\n    // 最小长度缩放限定\n    let newIncS = incS;\n    // 起始对角线长度\n    const startS = Math.sqrt(h ** 2 + w ** 2);\n    // 最小对角线长度\n    const minS = Math.sqrt((minSize * (h / w)) ** 2 + minSize ** 2);\n    switch (ctrlKey) {\n      // 非等比例缩放时，变化的增量范围 由原宽高跟 minSize 的差值决定\n      // 非等比例缩放时，根据ctrlKey的不同，固定宽高中的一个，另一个根据增量计算，并考虑最小值限定\n      case 'l':\n        newW = Math.max(w + newIncW, minSize);\n        newIncS = Math.min(incS, w - minSize);\n        break;\n      case 'r':\n        newW = Math.max(w + newIncW, minSize);\n        newIncS = Math.max(incS, minSize - w);\n        break;\n      case 'b':\n        newH = Math.max(h + newIncH, minSize);\n        newIncS = Math.min(incS, h - minSize);\n        break;\n      case 't':\n        newH = Math.max(h + newIncH, minSize);\n        newIncS = Math.max(incS, minSize - h);\n        break;\n      // 等比例缩放时，变化（对角线长度）的增量范围由原对角线长度跟 minSize 对角线的差值决定\n      // 等比例缩放时，某一边达到最小值时保持宽高比例不变\n      case 'lt':\n      case 'lb':\n        newW = Math.max(w + newIncW, minSize);\n        newH = newW === minSize ? (h / w) * newW : h + newIncH;\n        newIncS = Math.min(incS, startS - minS);\n        break;\n      case 'rt':\n      case 'rb':\n        newW = Math.max(w + newIncW, minSize);\n        newH = newW === minSize ? (h / w) * newW : h + newIncH;\n        newIncS = Math.max(incS, minS - startS);\n        break;\n    }\n    let newX = x;\n    let newY = y;\n    if (startRect.fixedScaleCenter) {\n      newX = x + w / 2 - newW / 2;\n      newY = y + h / 2 - newH / 2;\n    } else {\n      const newCenterX = (newIncS / 2) * Math.cos(rotateAngle) + x + w / 2;\n      const newCenterY = (newIncS / 2) * Math.sin(rotateAngle) + y + h / 2;\n      newX = newCenterX - newW / 2;\n      newY = newCenterY - newH / 2;\n    }\n\n    updateRectWithSafeMargin(sprRect, cvsEl, {\n      x: newX,\n      y: newY,\n      w: newW,\n      h: newH,\n    });\n  };\n\n  const clearWindowEvt = (): void => {\n    window.removeEventListener('pointermove', onMouseMove);\n    window.removeEventListener('pointerup', clearWindowEvt);\n  };\n  window.addEventListener('pointermove', onMouseMove);\n  window.addEventListener('pointerup', clearWindowEvt);\n}\n\n/**\n * 拉伸缩放, 上t 下b 左l 右r\n */\nfunction stretchScale({\n  deltaX,\n  deltaY,\n  angle,\n  ctrlKey,\n}: {\n  deltaX: number;\n  deltaY: number;\n  angle: number;\n  ctrlKey: TCtrlKey;\n}): {\n  incW: number;\n  incH: number;\n  incS: number;\n  rotateAngle: number;\n} {\n  // 计算矩形增加的宽度\n  let incS = 0;\n  let incW = 0;\n  let incH = 0;\n  let rotateAngle = angle;\n  if (ctrlKey === 'l' || ctrlKey === 'r') {\n    incS = deltaX * Math.cos(angle) + deltaY * Math.sin(angle);\n    // l 缩放是反向的\n    incW = incS * (ctrlKey === 'l' ? -1 : 1);\n  } else if (ctrlKey === 't' || ctrlKey === 'b') {\n    // 计算矩形增加的宽度，旋转坐标系让x轴与角度重合，鼠标位置在x轴的投影（x值）即为增加的高度\n    rotateAngle = angle - Math.PI / 2;\n    incS = deltaX * Math.cos(rotateAngle) + deltaY * Math.sin(rotateAngle);\n    incH = incS * (ctrlKey === 'b' ? -1 : 1);\n  }\n\n  return { incW, incH, incS, rotateAngle };\n}\n\n/**\n * 等比例缩放\n */\nfunction fixedRatioScale({\n  deltaX,\n  deltaY,\n  angle,\n  ctrlKey,\n  diagonalAngle,\n}: {\n  deltaX: number;\n  deltaY: number;\n  angle: number;\n  ctrlKey: TCtrlKey;\n  diagonalAngle: number;\n}): {\n  incW: number;\n  incH: number;\n  incS: number;\n  rotateAngle: number;\n} {\n  // 坐标系旋转角度， lb->rt的对角线的初始角度为负数，所以需要乘以-1\n  const rotateAngle =\n    (ctrlKey === 'lt' || ctrlKey === 'rb' ? 1 : -1) * diagonalAngle + angle;\n  // 旋转坐标系让x轴与对角线重合，鼠标位置在x轴的投影（x值）即为增加的长度\n  const incS = deltaX * Math.cos(rotateAngle) + deltaY * Math.sin(rotateAngle);\n  // lb lt 缩放值是反向\n  const coefficient = ctrlKey === 'lt' || ctrlKey === 'lb' ? -1 : 1;\n  // 等比例缩放，增加宽高等于长度乘以对应的角度函数\n  // 因为等比例缩放，中心及被拖拽的点，一定在对角线上\n  const incW = incS * Math.cos(diagonalAngle) * coefficient;\n  const incH = incS * Math.sin(diagonalAngle) * coefficient;\n\n  return { incW, incH, incS, rotateAngle };\n}\n\nfunction hitRectCtrls({\n  rect,\n  cvsRatio,\n  offsetX,\n  offsetY,\n  clientX,\n  clientY,\n  cvsEl,\n  rectCtrlsGetter,\n}: {\n  rect: Rect;\n  cvsRatio: ICvsRatio;\n  offsetX: number;\n  offsetY: number;\n  clientX: number;\n  clientY: number;\n  cvsEl: HTMLCanvasElement;\n  rectCtrlsGetter: (rect: Rect) => RectCtrls;\n}): boolean {\n  // 将鼠标点击偏移坐标映射成 canvas 坐，\n  const ofx = offsetX / cvsRatio.w;\n  const ofy = offsetY / cvsRatio.h;\n  // 转换为相对于画布中心的坐标\n  const cx = ofx - cvsEl.width / 2;\n  const cy = ofy - cvsEl.height / 2;\n\n  const [k] =\n    (Object.entries(rectCtrlsGetter(rect)).find(([, rect]) =>\n      rect.checkHit(cx, cy),\n    ) as [TCtrlKey, Rect]) ?? [];\n\n  if (k == null) return false;\n  if (k === 'rotate') {\n    rotateRect(rect, cntMap2Outer(rect.center, cvsRatio, cvsEl));\n  } else {\n    scaleRect({\n      sprRect: rect,\n      ctrlKey: k,\n      startX: clientX,\n      startY: clientY,\n      cvsRatio,\n      cvsEl,\n    });\n  }\n  // 命中 ctrl 后续是缩放 sprite，略过移动 sprite 逻辑\n  return true;\n}\n\n/**\n * 监听拖拽事件，将鼠标坐标转换为旋转角度\n * 旋转时，rect的坐标不变\n */\nfunction rotateRect(rect: Rect, outCnt: IPoint): void {\n  const onMove = ({ clientX, clientY }: MouseEvent): void => {\n    // 映射为 中心点坐标系\n    const x = clientX - outCnt.x;\n    const y = clientY - outCnt.y;\n    // 旋转控制点在正上方，与 x 轴是 -90°， 所以需要加上 Math.PI / 2\n    const angle = Math.atan2(y, x) + Math.PI / 2;\n    rect.angle = angle;\n  };\n  const clear = (): void => {\n    window.removeEventListener('pointermove', onMove);\n    window.removeEventListener('pointerup', clear);\n  };\n  window.addEventListener('pointermove', onMove);\n  window.addEventListener('pointerup', clear);\n}\n\n/**\n * canvas 内部（resolution）坐标映射成外部（DOM）坐标\n */\nfunction cntMap2Outer(\n  cnt: IPoint,\n  cvsRatio: ICvsRatio,\n  cvsEl: HTMLElement,\n): IPoint {\n  const x = cnt.x * cvsRatio.w;\n  const y = cnt.y * cvsRatio.h;\n\n  const { left, top } = cvsEl.getBoundingClientRect();\n  return {\n    x: x + left,\n    y: y + top,\n  };\n}\n\n/**\n * 限制安全范围，避免 sprite 完全超出边界\n */\nfunction updateRectWithSafeMargin(\n  rect: Rect,\n  cvsEl: HTMLCanvasElement,\n  value: Partial<Pick<Rect, 'x' | 'y' | 'w' | 'h'>>,\n) {\n  const newState = { x: rect.x, y: rect.y, w: rect.w, h: rect.h, ...value };\n  const safeMarginRatio = 0.05; // Keep 5% of the sprite visible if it goes off-screen\n  const minVisibleWidth = newState.w * safeMarginRatio;\n  const minVisibleHeight = newState.h * safeMarginRatio;\n\n  // Canvas boundaries in the center-origin coordinate system\n  const canvasLeft = -cvsEl.width / 2;\n  const canvasRight = cvsEl.width / 2;\n  const canvasTop = -cvsEl.height / 2;\n  const canvasBottom = cvsEl.height / 2;\n\n  // Calculate the desired visible part if the sprite was fully on screen\n  // For simplicity, let's ensure at least a small fixed part (e.g. 10px) or minVisibleWidth/Height is visible.\n  // Or, more robustly, the safeX and safeY from the original code represented the part of the *canvas* that should remain clear.\n  // Let's re-interpret safeWidth/safeHeight as the minimum portion of the *sprite* that must remain on canvas.\n\n  // Min x for rect.x (center of sprite) such that right edge of sprite is at canvasLeft + minVisibleWidth\n  const minX = canvasLeft - newState.w / 2 + minVisibleWidth;\n  // Max x for rect.x (center of sprite) such that left edge of sprite is at canvasRight - minVisibleWidth\n  const maxX = canvasRight + newState.w / 2 - minVisibleWidth;\n\n  // Min y for rect.y (center of sprite) such that bottom edge of sprite is at canvasTop + minVisibleHeight\n  const minY = canvasTop - newState.h / 2 + minVisibleHeight;\n  // Max y for rect.y (center of sprite) such that top edge of sprite is at canvasBottom - minVisibleHeight\n  const maxY = canvasBottom + newState.h / 2 - minVisibleHeight;\n\n  if (newState.x < minX) {\n    newState.x = minX;\n  } else if (newState.x > maxX) {\n    newState.x = maxX;\n  }\n\n  if (newState.y < minY) {\n    newState.y = minY;\n  } else if (newState.y > maxY) {\n    newState.y = maxY;\n  }\n\n  rect.x = newState.x;\n  rect.y = newState.y;\n  rect.w = newState.w;\n  rect.h = newState.h;\n}\n\n/**\n * 创建四周+中线参考线, 靠近具有磁吸效果\n */\nfunction createRefline(cvsEl: HTMLCanvasElement, container: HTMLElement) {\n  const reflineBaseCSS = `display: none; position: absolute;`;\n  const baseSettings = { w: 0, h: 0, x: 0, y: 0 } as const;\n  const reflineSettings: Record<\n    'top' | 'bottom' | 'left' | 'right' | 'vertMiddle' | 'horMiddle',\n    {\n      // 四周加中线参考线，它们的坐标、宽高只能是 0 ｜ 50 ｜ 100\n      w: 0 | 50 | 100;\n      h: 0 | 50 | 100;\n      x: 0 | 50 | 100;\n      y: 0 | 50 | 100;\n      ref: { prop: 'x' | 'y'; val: (rect: Rect) => number };\n    }\n  > = {\n    vertMiddle: {\n      ...baseSettings,\n      h: 100,\n      x: 50,\n      ref: { prop: 'x', val: ({ w }) => (cvsEl.width - w) / 2 },\n    },\n    horMiddle: {\n      ...baseSettings,\n      w: 100,\n      y: 50,\n      ref: { prop: 'y', val: ({ h }) => (cvsEl.height - h) / 2 },\n    },\n    top: {\n      ...baseSettings,\n      w: 100,\n      ref: { prop: 'y', val: () => 0 },\n    },\n    bottom: {\n      ...baseSettings,\n      w: 100,\n      y: 100,\n      ref: { prop: 'y', val: ({ h }) => cvsEl.height - h },\n    },\n    left: {\n      ...baseSettings,\n      h: 100,\n      ref: { prop: 'x', val: () => 0 },\n    },\n    right: {\n      ...baseSettings,\n      h: 100,\n      x: 100,\n      ref: { prop: 'x', val: ({ w }) => cvsEl.width - w },\n    },\n  } as const;\n\n  const lineWrap = createEl('div');\n  lineWrap.style.cssText = `\n    position: absolute;\n    top: 0; left: 0;\n    width: 100%; height: 100%;\n    pointer-events: none;\n    box-sizing: border-box;\n  `;\n  const reflineEls = Object.fromEntries(\n    Object.entries(reflineSettings).map(([key, { w, h, x, y }]) => {\n      const lineEl = createEl('div');\n      lineEl.style.cssText = `\n        ${reflineBaseCSS}\n        border-${w > 0 ? 'top' : 'left'}: 1px solid #3ee;\n        top: ${y}%; left: ${x}%;\n        ${x === 100 ? 'margin-left: -1px' : ''};\n        ${y === 100 ? 'margin-top: -1px' : ''};\n        width: ${w}%; height: ${h}%;\n      `;\n      lineWrap.appendChild(lineEl);\n      return [key, lineEl];\n    }),\n  ) as Record<keyof typeof reflineSettings, HTMLDivElement>;\n  container.appendChild(lineWrap);\n\n  const magneticDistance = 6 / (900 / cvsEl.width);\n  return {\n    magneticEffect(expectX: number, expectY: number, rect: Rect) {\n      const retVal = { x: expectX, y: expectY };\n      let reflineKey: keyof typeof reflineSettings;\n      let correctionState = { x: false, y: false };\n      for (reflineKey in reflineSettings) {\n        const { prop, val } = reflineSettings[reflineKey].ref;\n        if (correctionState[prop]) continue;\n\n        const refVal = val(rect);\n        if (\n          Math.abs(rect[prop] - refVal) <= magneticDistance &&\n          Math.abs(rect[prop] - (prop === 'x' ? expectX : expectY)) <=\n            magneticDistance\n        ) {\n          retVal[prop] = refVal;\n          reflineEls[reflineKey].style.display = 'block';\n          correctionState[prop] = true;\n        } else {\n          reflineEls[reflineKey].style.display = 'none';\n        }\n      }\n      return retVal;\n    },\n    hide() {\n      Object.values(reflineEls).forEach((el) => (el.style.display = 'none'));\n    },\n    destroy() {\n      lineWrap.remove();\n    },\n  };\n}\n\n/**\n * 根据当前位置（sprite & ctrls），动态调整鼠标样式\n */\nexport function dynamicCusor(\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n  rectCtrlsGetter: (rect: Rect) => RectCtrls,\n): () => void {\n  const cvsRatio = {\n    w: cvsEl.clientWidth / cvsEl.width,\n    h: cvsEl.clientHeight / cvsEl.height,\n  };\n\n  const observer = new ResizeObserver(() => {\n    cvsRatio.w = cvsEl.clientWidth / cvsEl.width;\n    cvsRatio.h = cvsEl.clientHeight / cvsEl.height;\n  });\n  observer.observe(cvsEl);\n\n  const cvsStyle = cvsEl.style;\n\n  let actSpr = sprMng.activeSprite;\n  sprMng.on(ESpriteManagerEvt.ActiveSpriteChange, (s) => {\n    actSpr = s;\n    if (s == null) cvsStyle.cursor = '';\n  });\n  // 鼠标按下时，在操作过程中，不需要变换鼠标样式\n  let isMSDown = false;\n  const onDown = ({ offsetX, offsetY }: MouseEvent): void => {\n    isMSDown = true;\n    // 将鼠标点击偏移坐标映射成 canvas 坐，\n    const ofx = offsetX / cvsRatio.w;\n    const ofy = offsetY / cvsRatio.h;\n    // 转换为相对于画布中心的坐标\n    const cx = ofx - cvsEl.width / 2;\n    const cy = ofy - cvsEl.height / 2;\n\n    // 直接选中 sprite 时，需要改变鼠标样式为 move\n    if (actSpr?.rect.checkHit(cx, cy) === true && cvsStyle.cursor === '') {\n      cvsStyle.cursor = 'move';\n    }\n  };\n  const onWindowUp = (): void => {\n    isMSDown = false;\n  };\n\n  // 八个 ctrl 点位对应的鼠标样式，构成循环\n  const curStyles = [\n    'ns-resize',\n    'nesw-resize',\n    'ew-resize',\n    'nwse-resize',\n    'ns-resize',\n    'nesw-resize',\n    'ew-resize',\n    'nwse-resize',\n  ];\n  const curInitIdx = { t: 0, rt: 1, r: 2, rb: 3, b: 4, lb: 5, l: 6, lt: 7 };\n\n  const onMove = (evt: MouseEvent): void => {\n    // 按下之后，不再变化，因为可能是在拖拽控制点\n    if (actSpr == null || isMSDown) return;\n    const { offsetX, offsetY } = evt;\n    const ofx = offsetX / cvsRatio.w;\n    const ofy = offsetY / cvsRatio.h;\n    // 转换为相对于画布中心的坐标\n    const cx = ofx - cvsEl.width / 2;\n    const cy = ofy - cvsEl.height / 2;\n\n    const [ctrlKey] =\n      (Object.entries(rectCtrlsGetter(actSpr.rect)).find(([, rect]) =>\n        rect.checkHit(cx, cy),\n      ) as [TCtrlKey, Rect]) ?? [];\n\n    if (ctrlKey != null) {\n      if (ctrlKey === 'rotate') {\n        cvsStyle.cursor = 'crosshair';\n        return;\n      }\n      // 旋转后，控制点的箭头指向也需要修正\n      const angle = actSpr.rect.angle;\n      const oa = angle < 0 ? angle + 2 * Math.PI : angle;\n      // 每个控制点的初始样式（idx） + 旋转角度导致的偏移，即为新鼠标样式\n      // 每旋转45°，偏移+1，以此在curStyles中循环\n      const idx =\n        (curInitIdx[ctrlKey] + Math.floor((oa + Math.PI / 8) / (Math.PI / 4))) %\n        8;\n      cvsStyle.cursor = curStyles[idx];\n      return;\n    }\n    if (actSpr.rect.checkHit(cx, cy)) {\n      cvsStyle.cursor = 'move';\n      return;\n    }\n    // 未命中 ctrls、sprite，重置为默认鼠标样式\n    cvsStyle.cursor = '';\n  };\n\n  cvsEl.addEventListener('pointermove', onMove);\n  cvsEl.addEventListener('pointerdown', onDown);\n  window.addEventListener('pointerup', onWindowUp);\n\n  return () => {\n    observer.disconnect();\n    cvsEl.removeEventListener('pointermove', onMove);\n    cvsEl.removeEventListener('pointerdown', onDown);\n    window.removeEventListener('pointerup', onWindowUp);\n  };\n}\n","import {\n  Log,\n  Combinator,\n  OffscreenSprite,\n  VisibleSprite,\n  MediaStreamClip,\n  ICombinatorOpts,\n} from '@fly-cut/av-cliper';\nimport { renderCtrls } from './sprites/render-ctrl';\nimport { ESpriteManagerEvt, SpriteManager } from './sprites/sprite-manager';\nimport {\n  activeSprite,\n  draggabelSprite,\n  dynamicCusor,\n} from './sprites/sprite-op';\nimport { IAnchor, IResolution } from './types';\nimport { createCtrlsGetter, createEl } from './utils';\nimport { workerTimer, EventTool } from '@fly-cut/internal-utils';\n\n/**\n * 默认的音频设置，⚠️ 不要变更它的值 ⚠️\n */\nconst DEFAULT_AUDIO_CONF = {\n  sampleRate: 48000,\n  channelCount: 2,\n  codec: 'mp4a.40.2',\n} as const;\n\nfunction createInitCvsEl(resolution: IResolution): HTMLCanvasElement {\n  const cvsEl = createEl('canvas') as HTMLCanvasElement;\n  cvsEl.style.cssText = `\n    width: 100%;\n    height: 100%;\n    display: block;\n    touch-action: none;\n  `;\n  cvsEl.width = resolution.width;\n  cvsEl.height = resolution.height;\n\n  return cvsEl;\n}\n\n/**\n *\n * 一个可交互的画布，让用户添加各种素材，支持基础交互（拖拽、缩放、旋转、时间偏移）\n *\n * 用于在 Web 环境中实现视频剪辑、直播推流工作台功能\n *\n * @description\n *\n  - 添加/删除素材（视频、音频、图片、文字）\n  - 分割（裁剪）素材\n  - 控制素材在视频中的空间属性（坐标、旋转、缩放）\n  - 控制素材在视频中的时间属性（偏移、时长）\n  - 设置坐标系原点位置\n  - 实时预览播放\n  - 纯浏览器环境生成视频\n\n * @see [直播录制](https://webav-tech.github.io/WebAV/demo/4_2-recorder-avcanvas)\n * @see [视频剪辑](https://webav-tech.github.io/WebAV/demo/6_4-video-editor)\n * @example\n * const avCvs = new AVCanvas(document.querySelector('#app'), {\n *   bgColor: '#333',\n *   width: 1920,\n *   height: 1080,\n * });\n *\n */\nexport class AVCanvas {\n  #cvsEl: HTMLCanvasElement;\n\n  #spriteManager: SpriteManager;\n\n  #cvsCtx: CanvasRenderingContext2D;\n\n  #destroyed = false;\n\n  #clears: Array<() => void> = [];\n  #stopRender: () => void;\n\n  #evtTool = new EventTool<{\n    timeupdate: (time: number) => void;\n    paused: () => void;\n    playing: () => void;\n    activeSpriteChange: (sprite: VisibleSprite | null) => void;\n  }>();\n  on = this.#evtTool.on;\n\n  #opts;\n\n  #backgroundOptions: {\n    mode: 'cover' | 'contain' | 'stretch' | 'repeat';\n    opacity: number;\n    blur: number;\n  } = {\n    mode: 'cover',\n    opacity: 1,\n    blur: 0,\n  };\n\n  // 在 AVCanvas 类中添加\n  #backgroundImage: ImageBitmap | null = null;\n  #originalBackgroundImage: ImageBitmap | null = null;\n\n  // 添加锚点属性\n  #anchor: IAnchor = { x: 0, y: 0 };\n\n  /**\n   * 创建 `AVCanvas` 类的实例。\n   * @param attchEl - 要添加画布的元素。\n   * @param opts - 画布的选项\n   * @param opts.bgColor - 画布的背景颜色。\n   * @param opts.width - 画布的宽度。\n   * @param opts.height - 画布的高度。\n   */\n  constructor(\n    attchEl: HTMLElement,\n    opts: {\n      bgColor: string;\n    } & IResolution,\n  ) {\n    this.#opts = opts;\n    this.#cvsEl = createInitCvsEl(opts);\n    const ctx = this.#cvsEl.getContext('2d', { alpha: false });\n    if (ctx == null) throw Error('canvas context is null');\n    this.#cvsCtx = ctx;\n    const container = createEl('div');\n    container.style.cssText =\n      'width: 100%; height: 100%; position: relative; overflow: hidden;';\n    container.appendChild(this.#cvsEl);\n    attchEl.appendChild(container);\n\n    createEmptyOscillatorNode(this.#audioCtx).connect(this.#captureAudioDest);\n\n    this.#spriteManager = new SpriteManager();\n\n    const { rectCtrlsGetter, destroy: ctrlGetterDestroy } = createCtrlsGetter(\n      this.#cvsEl,\n    );\n    this.#clears.push(\n      ctrlGetterDestroy,\n      // 鼠标样式、控制 sprite 依赖 activeSprite，\n      // activeSprite 需要在他们之前监听到 mousedown 事件 (代码顺序需要靠前)\n      activeSprite(this.#cvsEl, this.#spriteManager, rectCtrlsGetter),\n      dynamicCusor(this.#cvsEl, this.#spriteManager, rectCtrlsGetter),\n      draggabelSprite(\n        this.#cvsEl,\n        this.#spriteManager,\n        container,\n        rectCtrlsGetter,\n      ),\n      renderCtrls(container, this.#cvsEl, this.#spriteManager, rectCtrlsGetter),\n      // 因为默认为中心对齐，所以可以不用考虑居中的问题，0，0就是居中\n      // this.#spriteManager.on(ESpriteManagerEvt.AddSprite, (s) => {\n      //   const { rect } = s;\n      //   // 默认居中\n      //   if (rect.x === 0 && rect.y === 0) {\n      //     // 考虑锚点的情况\n      //     rect.x = (this.#cvsEl.width - rect.w) / 2;\n      //     rect.y = (this.#cvsEl.height - rect.h) / 2;\n      //   }\n      // }),\n      EventTool.forwardEvent(this.#spriteManager, this.#evtTool, [\n        ESpriteManagerEvt.ActiveSpriteChange,\n      ]),\n    );\n\n    let lastRenderTime = this.#renderTime;\n    let start = performance.now();\n    let runCnt = 0;\n    const expectFrameTime = 1000 / 30;\n    this.#stopRender = workerTimer(() => {\n      // workerTimer 会略快于真实时钟，使用真实时间（performance.now）作为基准\n      // 跳过部分运行帧修正时间，避免导致音画不同步\n      if ((performance.now() - start) / (expectFrameTime * runCnt) < 1) {\n        return;\n      }\n      runCnt += 1;\n      this.#render();\n\n      if (lastRenderTime !== this.#renderTime) {\n        lastRenderTime = this.#renderTime;\n        this.#evtTool.emit('timeupdate', Math.round(lastRenderTime));\n      }\n    }, expectFrameTime);\n\n    // ;(window as any).cvsEl = this.#cvsEl\n  }\n\n  #renderTime = 0e6;\n  #updateRenderTime(time: number) {\n    this.#renderTime = time;\n    this.#spriteManager.updateRenderTime(time);\n  }\n\n  #pause() {\n    const emitPaused = this.#playState.step !== 0;\n    this.#playState.step = 0;\n    if (emitPaused) {\n      this.#evtTool.emit('paused');\n      this.#audioCtx.suspend();\n    }\n    for (const asn of this.#playingAudioCache) {\n      asn.stop();\n      asn.disconnect();\n    }\n    this.#playingAudioCache.clear();\n  }\n\n  #audioCtx = new AudioContext();\n  #captureAudioDest = this.#audioCtx.createMediaStreamDestination();\n\n  #playingAudioCache: Set<AudioBufferSourceNode> = new Set();\n  #render() {\n    const cvsCtx = this.#cvsCtx;\n    let ts = this.#renderTime;\n    const { start, end, step, audioPlayAt } = this.#playState;\n    if (step !== 0 && ts >= start && ts < end) {\n      ts += step;\n    } else {\n      this.#pause();\n    }\n    this.#updateRenderTime(ts);\n\n    // 清除画布\n    cvsCtx.fillStyle = this.#opts.bgColor;\n    cvsCtx.fillRect(0, 0, this.#cvsEl.width, this.#cvsEl.height);\n\n    // 如果有背景图片，绘制背景图片\n    if (this.#backgroundImage) {\n      const { width, height } = this.#cvsEl;\n      const { mode, opacity } = this.#backgroundOptions;\n\n      // 保存当前上下文状态\n      cvsCtx.save();\n\n      // 设置透明度\n      if (opacity !== 1) {\n        cvsCtx.globalAlpha = opacity;\n      }\n\n      // 根据不同模式绘制背景\n      switch (mode) {\n        case 'cover':\n          // 覆盖模式，保持宽高比填满整个画布\n          drawImageCover(cvsCtx, this.#backgroundImage, 0, 0, width, height);\n          break;\n        case 'contain':\n          // 包含模式，保持宽高比完整显示图片\n          drawImageContain(cvsCtx, this.#backgroundImage, 0, 0, width, height);\n          break;\n        case 'stretch':\n          // 拉伸模式，拉伸填满整个画布\n          cvsCtx.drawImage(this.#backgroundImage, 0, 0, width, height);\n          break;\n        case 'repeat':\n          // 重复模式，平铺填满整个画布\n          const pattern = cvsCtx.createPattern(this.#backgroundImage, 'repeat');\n          if (pattern) {\n            cvsCtx.fillStyle = pattern;\n            cvsCtx.fillRect(0, 0, width, height);\n          }\n          break;\n      }\n\n      // 恢复上下文状态\n      cvsCtx.restore();\n    }\n\n    const ctxDestAudioData: Float32Array[][] = [];\n    for (const s of this.#spriteManager.getSprites()) {\n      cvsCtx.save();\n\n      // 应用锚点变换\n      // if (this.#anchor.x !== 0 || this.#anchor.y !== 0) {\n      //   // 保存当前的变换矩阵\n      //   cvsCtx.translate(this.#anchor.x, this.#anchor.y);\n      // }\n\n      const { audio } = s.render(cvsCtx, ts - s.time.offset, this.#anchor);\n      cvsCtx.restore();\n\n      ctxDestAudioData.push(audio);\n    }\n    cvsCtx.resetTransform();\n\n    if (step !== 0) {\n      const curAudioTime = Math.max(this.#audioCtx.currentTime, audioPlayAt);\n      const audioSourceArr = convertPCM2AudioSource(\n        ctxDestAudioData,\n        this.#audioCtx,\n      );\n\n      let addTime = 0;\n      for (const ads of audioSourceArr) {\n        ads.start(curAudioTime);\n        ads.connect(this.#audioCtx.destination);\n        ads.connect(this.#captureAudioDest);\n\n        this.#playingAudioCache.add(ads);\n        ads.onended = () => {\n          ads.disconnect();\n          this.#playingAudioCache.delete(ads);\n        };\n        addTime = Math.max(addTime, ads.buffer?.duration ?? 0);\n      }\n      this.#playState.audioPlayAt = curAudioTime + addTime;\n    }\n  }\n\n  #playState = {\n    start: 0,\n    end: 0,\n    // paused state when step equal 0\n    step: 0,\n    // step: (1000 / 30) * 1000,\n    audioPlayAt: 0,\n  };\n  /**\n   * 每 33ms 更新一次画布，绘制已添加的 Sprite\n   * @param opts - 播放选项\n   * @param opts.start - 开始播放的时间（单位：微秒）\n   * @param [opts.end] - 结束播放的时间（单位：微秒）。如果未指定，则播放到最后一个 Sprite 的结束时间\n   * @param [opts.playbackRate] - 播放速率。1 表示正常速度，2 表示两倍速度，0.5 表示半速等。如果未指定，则默认为 1\n   * @throws 如果开始时间大于等于结束时间或小于 0，则抛出错误\n   */\n  play(opts: { start: number; end?: number; playbackRate?: number }) {\n    const spriteTimes = this.#spriteManager\n      .getSprites({ time: false })\n      .map((s) => s.time.offset + s.time.duration);\n    const end =\n      opts.end ??\n      (spriteTimes.length > 0 ? Math.max(...spriteTimes) : Infinity);\n\n    if (opts.start >= end || opts.start < 0) {\n      throw Error(\n        `Invalid time parameter, ${JSON.stringify({ start: opts.start, end })}`,\n      );\n    }\n\n    this.#updateRenderTime(opts.start);\n    this.#spriteManager.getSprites({ time: false }).forEach((vs) => {\n      const { offset, duration } = vs.time;\n      const selfOffset = this.#renderTime - offset;\n      vs.preFrame(selfOffset > 0 && selfOffset < duration ? selfOffset : 0);\n    });\n\n    this.#playState.start = opts.start;\n    this.#playState.end = end;\n    // AVCanvas 30FPS，将播放速率转换成步长\n    this.#playState.step = (opts.playbackRate ?? 1) * (1000 / 30) * 1000;\n    this.#audioCtx.resume();\n    this.#playState.audioPlayAt = 0;\n\n    this.#evtTool.emit('playing');\n    Log.info('AVCanvs play by:', this.#playState);\n  }\n\n  /**\n   * 暂停播放，画布内容不再更新\n   */\n  pause() {\n    this.#pause();\n  }\n\n  /**\n   * 预览 `AVCanvas` 指定时间的图像帧\n   */\n  previewFrame(time: number) {\n    this.#updateRenderTime(time);\n    this.#pause();\n  }\n\n  /**\n   * 获取当前帧的截图图像 返回的是一个base64\n   */\n  captureImage(): string {\n    return this.#cvsEl.toDataURL();\n  }\n\n  get activeSprite() {\n    return this.#spriteManager.activeSprite;\n  }\n  set activeSprite(s: VisibleSprite | null) {\n    this.#spriteManager.activeSprite = s;\n  }\n\n  #sprMapAudioNode = new WeakMap<VisibleSprite, AudioNode>();\n  /**\n   * 添加 {@link VisibleSprite}\n   * @param args {@link VisibleSprite}\n   * @example\n   * const sprite = new VisibleSprite(\n   *   new ImgClip({\n   *     type: 'image/gif',\n   *     stream: (await fetch('https://xx.gif')).body!,\n   *   }),\n   * );\n   */\n  addSprite: SpriteManager['addSprite'] = async (vs) => {\n    if (this.#audioCtx.state === 'suspended')\n      this.#audioCtx.resume().catch(Log.error);\n\n    const clip = vs.getClip();\n    if (clip instanceof MediaStreamClip && clip.audioTrack != null) {\n      const audioNode = this.#audioCtx.createMediaStreamSource(\n        new MediaStream([clip.audioTrack]),\n      );\n      audioNode.connect(this.#captureAudioDest);\n      this.#sprMapAudioNode.set(vs, audioNode);\n    }\n    await this.#spriteManager.addSprite(vs);\n    vs.preFrame(0);\n  };\n  /**\n   * 删除 {@link VisibleSprite}\n   * @param args\n   * @returns\n   * @example\n   * const sprite = new VisibleSprite();\n   * avCvs.removeSprite(sprite);\n   */\n  removeSprite: SpriteManager['removeSprite'] = (vs) => {\n    this.#sprMapAudioNode.get(vs)?.disconnect();\n    this.#spriteManager.removeSprite(vs);\n  };\n\n  /**\n   * 销毁实例\n   */\n  destroy(): void {\n    if (this.#destroyed) return;\n    this.#destroyed = true;\n\n    this.#audioCtx.close();\n    this.#captureAudioDest.disconnect();\n    this.#evtTool.destroy();\n    this.#stopRender();\n    this.#cvsEl.parentElement?.remove();\n    this.#clears.forEach((fn) => fn());\n    this.#playingAudioCache.clear();\n    this.#spriteManager.destroy();\n  }\n\n  /**\n   * 合成所有素材的图像与音频，返回实时媒体流 `MediaStream`\n   *\n   * 可用于 WebRTC 推流，或由 {@link [AVRecorder](../../av-recorder/classes/AVRecorder.html)} 录制生成视频文件\n   *\n   * @see [直播录制](https://webav-tech.github.io/WebAV/demo/4_2-recorder-avcanvas)\n   *\n   */\n  captureStream(): MediaStream {\n    if (this.#audioCtx.state === 'suspended') {\n      this.#audioCtx.resume().catch(Log.error);\n    }\n\n    const ms = new MediaStream(\n      this.#cvsEl\n        .captureStream()\n        .getTracks()\n        .concat(this.#captureAudioDest.stream.getTracks()),\n    );\n    Log.info(\n      'AVCanvas.captureStream, tracks:',\n      ms.getTracks().map((t) => t.kind),\n    );\n    return ms;\n  }\n\n  /**\n   * 创建一个视频合成器 {@link [Combinator](../../av-cliper/classes/Combinator.html)} 实例，用于将当前画布添加的 Sprite 导出为视频文件流\n   *\n   * @param opts - 创建 Combinator 的可选参数\n   * @throws 如果没有添加素材，会抛出错误\n   *\n   * @example\n   * avCvs.createCombinator().output() // => ReadableStream\n   *\n   * @see [视频剪辑](https://webav-tech.github.io/WebAV/demo/6_4-video-editor)\n   */\n  async createCombinator(opts: ICombinatorOpts = {}) {\n    Log.info('AVCanvas.createCombinator, opts:', opts);\n\n    const com = new Combinator({ ...this.#opts, ...opts });\n    const sprites = this.#spriteManager.getSprites({ time: false });\n    if (sprites.length === 0) throw Error('No sprite added');\n\n    for (const vs of sprites) {\n      const os = new OffscreenSprite(vs.getClip());\n      os.time = { ...vs.time };\n      vs.copyStateTo(os);\n      await com.addSprite(os);\n    }\n    return com;\n  }\n\n  /**\n   * 设置背景图片\n   * @param image 背景图片（ImageBitmap、HTMLImageElement 或 URL）\n   * @param options 可选配置（如拉伸模式、透明度等）\n   */\n  async setBackgroundImage(\n    image: ImageBitmap | HTMLImageElement | string,\n    options: {\n      mode?: 'cover' | 'contain' | 'stretch' | 'repeat';\n      opacity?: number;\n      blur?: number;\n    } = {},\n  ): Promise<void> {\n    // 如果传入的是 URL 字符串，先加载图片\n    let originalImage: ImageBitmap;\n    if (typeof image === 'string') {\n      const response = await fetch(image);\n      const blob = await response.blob();\n      originalImage = await createImageBitmap(blob);\n    } else if (image instanceof HTMLImageElement) {\n      // 如果是 HTMLImageElement，转换为 ImageBitmap\n      originalImage = await createImageBitmap(image);\n    } else {\n      originalImage = image;\n    }\n\n    // 保存原始图像用于重新处理\n    this.#originalBackgroundImage = originalImage;\n\n    // 保存选项\n    this.#backgroundOptions = {\n      mode: options.mode || 'cover',\n      opacity: options.opacity !== undefined ? options.opacity : 1,\n      blur: options.blur !== undefined ? options.blur : 0,\n    };\n\n    // 如果需要模糊效果，预先处理图像\n    if (this.#backgroundOptions.blur > 0) {\n      // 创建离屏 Canvas 来应用模糊效果\n      const offscreenCanvas = new OffscreenCanvas(\n        originalImage.width,\n        originalImage.height,\n      );\n      const offscreenCtx = offscreenCanvas.getContext('2d');\n\n      if (offscreenCtx) {\n        // 应用模糊效果\n        offscreenCtx.filter = `blur(${this.#backgroundOptions.blur}px)`;\n\n        // 绘制图像\n        offscreenCtx.drawImage(originalImage, 0, 0);\n\n        // 创建处理后的 ImageBitmap\n        this.#backgroundImage = await createImageBitmap(offscreenCanvas);\n      } else {\n        // 如果无法创建上下文，使用原始图像\n        this.#backgroundImage = originalImage;\n      }\n    } else {\n      // 不需要模糊效果，直接使用原始图像\n      this.#backgroundImage = originalImage;\n    }\n  }\n\n  /**\n   * 更新背景图片的模糊效果或透明度\n   * @param options 可选配置（模式、透明度、模糊度）\n   */\n  async updateBackgroundOptions(\n    options: {\n      mode?: 'cover' | 'contain' | 'stretch' | 'repeat';\n      opacity?: number;\n      blur?: number;\n    } = {},\n  ): Promise<void> {\n    if (!this.#originalBackgroundImage) return;\n\n    // 更新选项\n    if (options.mode !== undefined) {\n      this.#backgroundOptions.mode = options.mode;\n    }\n    if (options.opacity !== undefined) {\n      this.#backgroundOptions.opacity = options.opacity;\n    }\n    if (options.blur !== undefined) {\n      this.#backgroundOptions.blur = options.blur;\n    }\n\n    // 如果模糊度发生变化，重新处理图像\n    if (options.blur !== undefined) {\n      if (this.#backgroundOptions.blur > 0) {\n        // 创建离屏 Canvas 来应用模糊效果\n        const offscreenCanvas = new OffscreenCanvas(\n          this.#originalBackgroundImage.width,\n          this.#originalBackgroundImage.height,\n        );\n        const offscreenCtx = offscreenCanvas.getContext('2d');\n\n        if (offscreenCtx) {\n          // 应用模糊效果\n          offscreenCtx.filter = `blur(${this.#backgroundOptions.blur}px)`;\n\n          // 绘制图像\n          offscreenCtx.drawImage(this.#originalBackgroundImage, 0, 0);\n\n          // 创建处理后的 ImageBitmap\n          this.#backgroundImage = await createImageBitmap(offscreenCanvas);\n        }\n      } else {\n        // 不需要模糊效果，直接使用原始图像\n        this.#backgroundImage = this.#originalBackgroundImage;\n      }\n    }\n  }\n\n  /**\n   * 清除背景图片，恢复使用纯色背景\n   */\n  clearBackgroundImage(): void {\n    this.#backgroundImage = null;\n    this.#originalBackgroundImage = null;\n  }\n\n  /**\n   * 刷新当前画布内容\n   * @description 强制重新渲染当前画布的所有内容，包括背景和所有精灵\n   */\n  refresh(): void {\n    // 更新渲染时间并暂停播放，确保所有内容都会被重新渲染\n    this.#updateRenderTime(this.#renderTime);\n    this.#pause();\n  }\n\n  /**\n   * 设置画布的坐标原点\n   * @param x - 原点的 x 坐标（0-1 之间表示百分比，大于 1 表示具体像素值）\n   * @param y - 原点的 y 坐标（0-1 之间表示百分比，大于 1 表示具体像素值）\n   */\n  setAnchor(x: number, y: number): void {\n    // 计算实际锚点坐标\n    const width = this.#cvsEl.width;\n    const height = this.#cvsEl.height;\n\n    // 如果 x, y 在 0-1 之间，认为是百分比值\n    const anchorX = x >= 0 && x <= 1 ? x * width : x;\n    const anchorY = y >= 0 && y <= 1 ? y * height : y;\n\n    this.#anchor = { x: anchorX, y: anchorY };\n\n    // 只需要触发重新渲染，让画布使用新的锚点\n    this.#render();\n  }\n}\n\nfunction convertPCM2AudioSource(pcmData: Float32Array[][], ctx: AudioContext) {\n  const asArr: AudioBufferSourceNode[] = [];\n  if (pcmData.length === 0) return asArr;\n\n  for (const [chan0Buf, chan1Buf] of pcmData) {\n    if (chan0Buf == null) continue;\n    if (chan0Buf.length <= 0) continue;\n\n    const buf = ctx.createBuffer(\n      2,\n      chan0Buf.length,\n      DEFAULT_AUDIO_CONF.sampleRate,\n    );\n    buf.copyToChannel(chan0Buf, 0);\n    buf.copyToChannel(chan1Buf ?? chan0Buf, 1);\n    const audioSource = ctx.createBufferSource();\n    audioSource.buffer = buf;\n    asArr.push(audioSource);\n  }\n  return asArr;\n}\n\n/**\n * 空背景音，让 dest 能持续收到音频数据，否则时间会异常偏移\n */\nfunction createEmptyOscillatorNode(ctx: AudioContext) {\n  const osc = ctx.createOscillator();\n  const real = new Float32Array([0, 0]);\n  const imag = new Float32Array([0, 0]);\n  const wave = ctx.createPeriodicWave(real, imag, {\n    disableNormalization: true,\n  });\n  osc.setPeriodicWave(wave);\n  osc.start();\n  return osc;\n}\n\n/**\n * 绘制图片并保持宽高比填满整个目标区域（类似CSS的background-size: cover）\n * 图片可能会被裁剪，但不会变形\n */\nfunction drawImageCover(\n  ctx: CanvasRenderingContext2D,\n  img: ImageBitmap,\n  x: number,\n  y: number,\n  width: number,\n  height: number,\n): void {\n  const imgRatio = img.width / img.height;\n  const targetRatio = width / height;\n\n  let drawWidth = width;\n  let drawHeight = height;\n  let offsetX = 0;\n  let offsetY = 0;\n\n  // 计算绘制尺寸和偏移量，保持宽高比\n  if (targetRatio > imgRatio) {\n    // 目标区域更宽，需要裁剪高度\n    drawHeight = (width / img.width) * img.height;\n    offsetY = (height - drawHeight) / 2;\n  } else {\n    // 目标区域更高，需要裁剪宽度\n    drawWidth = (height / img.height) * img.width;\n    offsetX = (width - drawWidth) / 2;\n  }\n\n  ctx.drawImage(img, x + offsetX, y + offsetY, drawWidth, drawHeight);\n}\n\n/**\n * 绘制图片并保持宽高比完整显示在目标区域内（类似CSS的background-size: contain）\n * 图片完整显示，但可能会有空白区域\n */\nfunction drawImageContain(\n  ctx: CanvasRenderingContext2D,\n  img: ImageBitmap,\n  x: number,\n  y: number,\n  width: number,\n  height: number,\n): void {\n  const imgRatio = img.width / img.height;\n  const targetRatio = width / height;\n\n  let drawWidth = width;\n  let drawHeight = height;\n  let offsetX = 0;\n  let offsetY = 0;\n\n  // 计算绘制尺寸和偏移量，保持宽高比\n  if (targetRatio < imgRatio) {\n    // 目标区域更窄，宽度撑满，高度等比缩放\n    drawHeight = (width / img.width) * img.height;\n    offsetY = (height - drawHeight) / 2;\n  } else {\n    // 目标区域更宽，高度撑满，宽度等比缩放\n    drawWidth = (height / img.height) * img.width;\n    offsetX = (width - drawWidth) / 2;\n  }\n\n  ctx.drawImage(img, x + offsetX, y + offsetY, drawWidth, drawHeight);\n}\n"],"names":["CTRL_KEYS","createEl","tagName","createCtrlsGetter","cvsEl","ctrlSize","cvsResizeOb","entries","fisrtEntry","rectCtrlsGetter","rect","w","sz","hfSz","hfW","hfH","rtSz","hfRtSz","Rect","ESpriteManagerEvt","SpriteManager","__privateAdd","_sprites","_activeSprite","_evtTool","EventTool","__publicField","__privateGet","_renderTime","s","__privateSet","vs","a","b","props","spr","filter","time","as","renderCtrls","container","sprMng","cvsRatio","observer","syncCtrlElPos","rectEl","ctrlsEl","lastActSprEvtClear","createRectAndCtrlEl","offSprChange","k","d","x","y","h","angle","cvsCenterXInContainer","cvsCenterYInContainer","visualLeftXInCanvasCenter","visualTopYInCanvasCenter","activeSprite","onCvsMouseDown","evt","offsetX","offsetY","ofx","ofy","cx","cy","ctrlKey","draggabelSprite","startX","startY","startRect","refline","createRefline","hitSpr","clientX","clientY","hitRectCtrls","onMouseMove","clearWindowEvt","expectX","expectY","updateRectWithSafeMargin","scaleRect","sprRect","deltaX","deltaY","scaler","stretchScale","fixedRatioScale","diagonalAngle","incW","incH","incS","rotateAngle","minSize","newW","newH","newIncW","newIncH","newIncS","startS","minS","newX","newY","newCenterX","newCenterY","coefficient","rotateRect","cntMap2Outer","outCnt","onMove","clear","cnt","left","top","value","newState","safeMarginRatio","minVisibleWidth","minVisibleHeight","canvasLeft","canvasRight","canvasTop","canvasBottom","minX","maxX","minY","maxY","reflineBaseCSS","baseSettings","reflineSettings","lineWrap","reflineEls","key","lineEl","magneticDistance","retVal","reflineKey","correctionState","prop","val","refVal","el","dynamicCusor","cvsStyle","actSpr","isMSDown","onDown","onWindowUp","curStyles","curInitIdx","oa","idx","DEFAULT_AUDIO_CONF","createInitCvsEl","resolution","AVCanvas","attchEl","opts","_AVCanvas_instances","_cvsEl","_spriteManager","_cvsCtx","_destroyed","_clears","_stopRender","_opts","_backgroundOptions","_backgroundImage","_originalBackgroundImage","_anchor","_audioCtx","_captureAudioDest","_playingAudioCache","_playState","_sprMapAudioNode","Log","clip","MediaStreamClip","audioNode","_a","ctx","createEmptyOscillatorNode","ctrlGetterDestroy","lastRenderTime","start","runCnt","expectFrameTime","workerTimer","__privateMethod","render_fn","spriteTimes","end","updateRenderTime_fn","offset","duration","selfOffset","pause_fn","fn","ms","t","com","Combinator","sprites","os","OffscreenSprite","image","options","originalImage","blob","offscreenCanvas","offscreenCtx","width","height","anchorX","anchorY","emitPaused","asn","cvsCtx","ts","step","audioPlayAt","mode","opacity","drawImageCover","drawImageContain","pattern","ctxDestAudioData","audio","curAudioTime","audioSourceArr","convertPCM2AudioSource","addTime","ads","pcmData","asArr","chan0Buf","chan1Buf","buf","audioSource","osc","real","imag","wave","img","imgRatio","targetRatio","drawWidth","drawHeight"],"mappings":"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"}