{"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 '@webav/av-cliper';\n\n/**\n * 二维坐标系中的点\n */\nexport interface IPoint {\n  x: number;\n  y: number;\n}\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 '@webav/av-cliper';\nimport { ICvsRatio, RectCtrls } from './types';\n\nexport function createEl(tagName: string): HTMLElement {\n  return document.createElement(tagName);\n}\n\nconst rectGetterCache = new WeakMap<\n  HTMLCanvasElement,\n  (rect: Rect) => RectCtrls\n>();\n/**\n * 根据 canvas 创建该画布上的 Sprite 控制点生成器\n * 因为控制点的大小需要根据画布的大小动态调整\n */\nexport function getRectCtrls(cvsEl: HTMLCanvasElement, rect: Rect) {\n  if (rectGetterCache.has(cvsEl)) {\n    return rectGetterCache.get(cvsEl)!(rect);\n  }\n\n  let ctrlSize = 10;\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  rectGetterCache.set(cvsEl, rectCtrlsGetter);\n  return rectCtrlsGetter(rect);\n}\n\n// 复用 canvas 比例的获取，避免重复 observer\nconst cvsRatioCache = new WeakMap<HTMLCanvasElement, ICvsRatio>();\nexport function getCvsRatio(cvsEl: HTMLCanvasElement): ICvsRatio {\n  if (cvsRatioCache.has(cvsEl)) {\n    return cvsRatioCache.get(cvsEl)!;\n  }\n\n  const cvsRatio = {\n    w: cvsEl.clientWidth / cvsEl.width,\n    h: cvsEl.clientHeight / cvsEl.height,\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  cvsRatioCache.set(cvsEl, cvsRatio);\n  return cvsRatio;\n}\n","import { VisibleSprite } from '@webav/av-cliper';\nimport { EventTool } from '@webav/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  activeSpriteByCoord(x: number, y: number): void {\n    this.activeSprite =\n      this.getSprites()\n        // 排在后面的层级更高\n        .reverse()\n        .find((s) => s.visible && s.rect.checkHit(x, y)) ?? null;\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 { VisibleSprite } from '@webav/av-cliper';\nimport { CTRL_KEYS, TCtrlKey } from '../types';\nimport { createEl, getCvsRatio, getRectCtrls } from '../utils';\nimport { ESpriteManagerEvt, SpriteManager } from './sprite-manager';\n\nexport function renderCtrls(\n  container: HTMLElement,\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n): () => void {\n  const cvsRatio = getCvsRatio(cvsEl);\n  const observer = new ResizeObserver(() => {\n    if (sprMng.activeSprite == null) return;\n    syncCtrlElPos(sprMng.activeSprite, cvsEl, rectEl, ctrlsEl);\n  });\n  observer.observe(cvsEl);\n\n  let lastActSprEvtClear = () => {};\n  const { rectEl, ctrlsEl } = createRectAndCtrlEl(container);\n\n  // 添加点击事件处理\n  rectEl.addEventListener('pointerdown', (evt) => {\n    // 如果点击的是控制点，不处理点击穿透\n    if (Object.values(ctrlsEl).includes(evt.target as HTMLElement)) {\n      return;\n    }\n\n    // 获取相对于 canvas 的坐标，可能需要激活更上层的 sprite\n    const cvsRect = cvsEl.getBoundingClientRect();\n    const x = (evt.clientX - cvsRect.left) / cvsRatio.w;\n    const y = (evt.clientY - cvsRect.top) / cvsRatio.h;\n    sprMng.activeSpriteByCoord(x, y);\n  });\n\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, cvsEl, rectEl, ctrlsEl);\n    lastActSprEvtClear = s.on('propsChange', () => {\n      syncCtrlElPos(s, cvsEl, rectEl, ctrlsEl);\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.classList.add('sprite-rect');\n  rectEl.style.cssText = `\n    position: absolute;\n    z-index: 3;\n    pointer-events: auto;\n    border: 1px solid #eee;\n    box-sizing: border-box;\n    display: none;\n    cursor: move;\n  `;\n  const ctrlsEl = Object.fromEntries(\n    CTRL_KEYS.map((k) => {\n      const d = createEl('div');\n      d.classList.add(`ctrl-key-${k}`);\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        pointer-events: auto;\n        cursor: ${k === 'rotate' ? 'crosshair' : 'default'};\n        user-select: none;\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  cvsEl: HTMLCanvasElement,\n  rectEl: HTMLElement,\n  ctrlsEl: Record<TCtrlKey, HTMLElement>,\n): void {\n  const cvsRatio = getCvsRatio(cvsEl);\n  const { x, y, w, h, angle } = s.rect;\n  Object.assign(rectEl.style, {\n    left: `${x * cvsRatio.w}px`,\n    top: `${y * cvsRatio.h}px`,\n    width: `${w * cvsRatio.w}px`,\n    height: `${h * cvsRatio.h}px`,\n    rotate: `${angle}rad`,\n  });\n  Object.entries(getRectCtrls(cvsEl, 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 { Rect } from '@webav/av-cliper';\nimport { debounce } from '@webav/internal-utils';\nimport { CTRL_KEYS, ICvsRatio, IPoint, TCtrlKey } from '../types';\nimport { createEl, getCvsRatio } from '../utils';\nimport { ESpriteManagerEvt, SpriteManager } from './sprite-manager';\n\n/**\n * 鼠标点击，激活 sprite\n */\nexport function activeSprite(\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n): () => void {\n  const onCvsMouseDown = (evt: MouseEvent): void => {\n    if (evt.button !== 0) return;\n    // 如果点击的是控制元素，不处理选择逻辑\n    if ((evt.target as HTMLElement) !== cvsEl) return;\n\n    const cvsRatio = getCvsRatio(cvsEl);\n    const { offsetX, offsetY } = evt;\n    const ofx = offsetX / cvsRatio.w;\n    const ofy = offsetY / cvsRatio.h;\n\n    sprMng.activeSpriteByCoord(ofx, ofy);\n  };\n\n  cvsEl.addEventListener('pointerdown', onCvsMouseDown);\n\n  return () => {\n    cvsEl.removeEventListener('pointerdown', onCvsMouseDown);\n  };\n}\n\n/**\n * 让sprite可以被拖拽移动、缩放和旋转\n */\nexport function draggabelSprite(\n  cvsEl: HTMLCanvasElement,\n  sprMng: SpriteManager,\n  container: HTMLElement,\n): () => void {\n  let startX = 0;\n  let startY = 0;\n  let startRect: Rect | null = null;\n\n  const refline = createRefline(cvsEl, container);\n\n  // 查找控制 sprite 的 DOM 元素，在 renderCtrls 中创建并添加到 container 中\n  const rectEl = container.querySelector('.sprite-rect') as HTMLElement;\n  if (!rectEl) throw Error('sprite-rect DOM Node not found');\n\n  // 移动sprite的处理函数\n  const onRectMouseDown = (evt: MouseEvent): void => {\n    if (evt.button !== 0 || sprMng.activeSprite == null) return;\n\n    const hitSpr = sprMng.activeSprite;\n    const { clientX, clientY } = evt;\n\n    startRect = hitSpr.rect.clone();\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    evt.stopPropagation();\n  };\n\n  const cvsRatio = getCvsRatio(cvsEl);\n  const onMouseMove = (evt: MouseEvent): void => {\n    if (sprMng.activeSprite == 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      sprMng.activeSprite.rect,\n      cvsEl,\n      refline.magneticEffect(expectX, expectY, sprMng.activeSprite.rect),\n    );\n  };\n\n  const clearWindowEvt = (): void => {\n    refline.hide();\n    window.removeEventListener('pointermove', onMouseMove);\n    window.removeEventListener('pointerup', clearWindowEvt);\n  };\n\n  // 初始设置\n  rectEl.addEventListener('pointerdown', onRectMouseDown);\n  cvsEl.addEventListener('pointerdown', onRectMouseDown);\n  const offCtrlEvt = setupCtrlEvents(cvsEl, rectEl, sprMng);\n\n  return () => {\n    refline.destroy();\n    clearWindowEvt();\n    rectEl.removeEventListener('pointerdown', onRectMouseDown);\n    cvsEl.removeEventListener('pointerdown', onRectMouseDown);\n    offCtrlEvt();\n  };\n}\n\n// 为控制点添加事件处理\nfunction setupCtrlEvents(\n  cvsEl: HTMLCanvasElement,\n  rectEl: HTMLElement,\n  sprMng: SpriteManager,\n) {\n  // 获取所有控制点元素\n  const ctrlElements = Array.from(rectEl.children) as HTMLElement[];\n\n  const cvsRatio = getCvsRatio(cvsEl);\n  // 鼠标按下对应的节点，进行对应的操作（旋转、缩放）\n  ctrlElements.forEach((ctrlEl, index) => {\n    const ctrlKey = CTRL_KEYS[index];\n    ctrlEl.addEventListener('pointerdown', (evt: MouseEvent) => {\n      if (evt.button !== 0 || sprMng.activeSprite == null) return;\n\n      const { clientX, clientY } = evt;\n\n      if (ctrlKey === 'rotate') {\n        rotateRect(\n          sprMng.activeSprite.rect,\n          cntMap2Outer(sprMng.activeSprite.rect.center, cvsRatio, cvsEl),\n        );\n      } else {\n        scaleRect({\n          sprRect: sprMng.activeSprite.rect,\n          ctrlKey,\n          startX: clientX,\n          startY: clientY,\n          cvsRatio,\n          cvsEl,\n        });\n      }\n\n      evt.stopPropagation();\n    });\n  });\n\n  ctrlElements[CTRL_KEYS.indexOf('rotate')].style.cursor = 'crosshair';\n\n  // 根据角度，动态调整每个控制节点的鼠标样式\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 = {\n    t: 0,\n    rt: 1,\n    r: 2,\n    rb: 3,\n    b: 4,\n    lb: 5,\n    l: 6,\n    lt: 7,\n  };\n\n  let offPropsEvt = () => {};\n  const offActSprEvt = sprMng.on(ESpriteManagerEvt.ActiveSpriteChange, (s) => {\n    offPropsEvt();\n    if (s == null) return;\n\n    const updateCursorStyle = debounce(function () {\n      const { angle } = s.rect;\n      const oa = angle < 0 ? angle + 2 * Math.PI : angle;\n\n      ctrlElements.forEach((ctrlEl, index) => {\n        const ctrlKey = CTRL_KEYS[index];\n        if (ctrlKey === 'rotate') return;\n        // 每个控制点的初始样式（idx） + 旋转角度导致的偏移，即为新鼠标样式\n        // 每旋转45°，偏移+1，以此在curStyles中循环\n        const idx =\n          (curInitIdx[ctrlKey] +\n            Math.floor((oa + Math.PI / 8) / (Math.PI / 4))) %\n          8;\n        ctrlEl.style.cursor = curStyles[idx];\n      });\n    }, 300);\n\n    offPropsEvt = s.on('propsChange', (props) => {\n      if (props.rect?.angle == null) return;\n      updateCursorStyle();\n    });\n\n    updateCursorStyle();\n  });\n  return () => {\n    offPropsEvt();\n    offActSprEvt();\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\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 safeWidth = cvsEl.width * 0.05;\n  const safeHeight = cvsEl.height * 0.05;\n  if (newState.x < -newState.w + safeWidth) {\n    newState.x = -newState.w + safeWidth;\n  } else if (newState.x > cvsEl.width - safeWidth) {\n    newState.x = cvsEl.width - safeWidth;\n  }\n  if (newState.y < -newState.h + safeHeight) {\n    newState.y = -newState.h + safeHeight;\n  } else if (newState.y > cvsEl.height - safeHeight) {\n    newState.y = cvsEl.height - safeHeight;\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    z-index: 4;\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\n      // 记录每个维度(x,y)的最小距离和对应的参考线\n      const minDist = { x: magneticDistance, y: magneticDistance };\n\n      type RefLineKey = keyof typeof reflineEls;\n      const activeReflines = { x: '', y: '' } as {\n        x: RefLineKey | '';\n        y: RefLineKey | '';\n      };\n\n      // 隐藏所有参考线，稍后会显示激活的参考线\n      Object.values(reflineEls).forEach((el) => (el.style.display = 'none'));\n\n      // 遍历所有参考线\n      for (const reflineKey in reflineSettings) {\n        const { prop, val } =\n          reflineSettings[reflineKey as keyof typeof reflineSettings].ref;\n        const refVal = val(rect);\n        const currentVal = prop === 'x' ? expectX : expectY;\n\n        // 计算与参考线的距离\n        const dist = Math.abs(currentVal - refVal);\n\n        // 在磁吸范围内，且比当前记录的最小距离更近\n        if (dist <= magneticDistance && dist < minDist[prop]) {\n          minDist[prop] = dist;\n          retVal[prop] = refVal;\n          activeReflines[prop] = reflineKey as RefLineKey;\n        }\n      }\n\n      // 显示激活的参考线\n      if (activeReflines.x) {\n        reflineEls[activeReflines.x].style.display = 'block';\n      }\n      if (activeReflines.y) {\n        reflineEls[activeReflines.y].style.display = 'block';\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","import {\n  Combinator,\n  ICombinatorOpts,\n  Log,\n  MediaStreamClip,\n  OffscreenSprite,\n  Rect,\n  VisibleSprite,\n} from '@webav/av-cliper';\nimport { EventTool, workerTimer } from '@webav/internal-utils';\nimport { renderCtrls } from './sprites/render-ctrl';\nimport { ESpriteManagerEvt, SpriteManager } from './sprites/sprite-manager';\nimport { activeSprite, draggabelSprite } from './sprites/sprite-op';\nimport { IResolution } from './types';\nimport { createEl, getRectCtrls } from './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 * @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  /**\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 = 'width: 100%; height: 100%; position: relative;';\n    container.appendChild(this.#cvsEl);\n    attchEl.appendChild(container);\n\n    createEmptyOscillatorNode(this.#audioCtx).connect(this.#captureAudioDest);\n\n    // 创建 this.#cvsEl 时自动设置 ctrlSize 初始值\n    // 避免首次渲染时 ctrls 节点大小不符合期望，所以这里不需要它的返回值\n    getRectCtrls(this.#cvsEl, { x: 0, y: 0, w: 0, h: 0 } as Rect);\n\n    this.#spriteManager = new SpriteManager();\n\n    this.#clears.push(\n      // 鼠标样式、控制 sprite 依赖 activeSprite，\n      // activeSprite 需要在他们之前监听到 mousedown 事件 (代码顺序需要靠前)\n      activeSprite(this.#cvsEl, this.#spriteManager),\n      renderCtrls(container, this.#cvsEl, this.#spriteManager),\n      draggabelSprite(this.#cvsEl, this.#spriteManager, container),\n      this.#spriteManager.on(ESpriteManagerEvt.AddSprite, (s) => {\n        const { rect } = s;\n        // 默认居中\n        if (rect.x === 0 && rect.y === 0) {\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.#cvsCtx.fillStyle = opts.bgColor;\n      this.#cvsCtx.fillRect(0, 0, this.#cvsEl.width, this.#cvsEl.height);\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    const ctxDestAudioData: Float32Array[][] = [];\n    for (const s of this.#spriteManager.getSprites()) {\n      cvsCtx.save();\n      const { audio } = s.render(cvsCtx, ts - s.time.offset);\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\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"],"names":["CTRL_KEYS","createEl","tagName","rectGetterCache","getRectCtrls","cvsEl","rect","ctrlSize","entries","fisrtEntry","rectCtrlsGetter","w","h","sz","hfSz","hfW","hfH","rtSz","hfRtSz","Rect","cvsRatioCache","getCvsRatio","cvsRatio","ESpriteManagerEvt","SpriteManager","__privateAdd","_sprites","_activeSprite","_evtTool","EventTool","__publicField","__privateGet","_renderTime","s","__privateSet","x","y","vs","a","b","props","spr","filter","time","as","renderCtrls","container","sprMng","observer","syncCtrlElPos","rectEl","ctrlsEl","lastActSprEvtClear","createRectAndCtrlEl","evt","cvsRect","offSprChange","k","d","angle","activeSprite","onCvsMouseDown","offsetX","offsetY","ofx","ofy","draggabelSprite","startX","startY","startRect","refline","createRefline","onRectMouseDown","hitSpr","clientX","clientY","onMouseMove","clearWindowEvt","expectX","expectY","updateRectWithSafeMargin","offCtrlEvt","setupCtrlEvents","ctrlElements","ctrlEl","index","ctrlKey","rotateRect","cntMap2Outer","scaleRect","curStyles","curInitIdx","offPropsEvt","offActSprEvt","updateCursorStyle","debounce","oa","idx","_a","sprRect","deltaX","deltaY","scaler","stretchScale","fixedRatioScale","diagonalAngle","incW","incH","incS","rotateAngle","minSize","newW","newH","newIncW","newIncH","newIncS","startS","minS","newX","newY","newCenterX","newCenterY","coefficient","outCnt","onMove","clear","cnt","left","top","value","newState","safeWidth","safeHeight","reflineBaseCSS","baseSettings","reflineSettings","lineWrap","reflineEls","key","lineEl","magneticDistance","retVal","minDist","activeReflines","el","reflineKey","prop","val","refVal","dist","DEFAULT_AUDIO_CONF","createInitCvsEl","resolution","AVCanvas","attchEl","opts","_AVCanvas_instances","_cvsEl","_spriteManager","_cvsCtx","_destroyed","_clears","_stopRender","_opts","_audioCtx","_captureAudioDest","_playingAudioCache","_playState","_sprMapAudioNode","Log","clip","MediaStreamClip","audioNode","ctx","createEmptyOscillatorNode","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","emitPaused","asn","cvsCtx","ts","step","audioPlayAt","ctxDestAudioData","audio","curAudioTime","audioSourceArr","convertPCM2AudioSource","addTime","ads","pcmData","asArr","chan0Buf","chan1Buf","buf","audioSource","osc","real","imag","wave"],"mappings":"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"}