{"version":3,"file":"photo-crop-tool.mjs","sources":["../../../packages/components/src/photo-crop-tool.ts"],"sourcesContent":["import { LitElement, css, html } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { styleMap } from 'lit/directives/style-map.js'\nimport { safeCustomElement } from './base/define'\n\ntype ZoomType = 'fixed' | 'free'\ntype HandleType = 'move' | 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left'\n\ntype CropRect = {\n  x: number\n  y: number\n  width: number\n  height: number\n}\n\ntype DisplayRect = CropRect\n\nfunction clamp(value: number, min: number, max: number) {\n  return Math.min(Math.max(value, min), max)\n}\n\nfunction parseAspectRatio(value: string) {\n  const [left, right] = value.split('/').map(part => Number.parseFloat(part.trim()))\n  if (!left || !right || Number.isNaN(left) || Number.isNaN(right)) {\n    return 16 / 9\n  }\n  return left / right\n}\n\n@safeCustomElement('qxs-photo-crop-tool')\nexport class QxsPhotoCropTool extends LitElement {\n  static styles = css`\n    :host {\n      display: block;\n      width: 100%;\n      height: 100%;\n      min-height: 240px;\n    }\n\n    .img-box {\n      position: relative;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      width: 100%;\n      height: 100%;\n      overflow: hidden;\n      background: #fafafa;\n      border-radius: 12px;\n    }\n\n    .placeholder,\n    .error-message {\n      padding: 20px;\n      font-size: 14px;\n      line-height: 1.6;\n      color: #64748b;\n      text-align: center;\n    }\n\n    .error-message {\n      color: #dc2626;\n    }\n\n    .image {\n      position: absolute;\n      inset: 0;\n      user-select: none;\n      -webkit-user-drag: none;\n      pointer-events: none;\n    }\n\n    .crop-tool-box {\n      position: absolute;\n      box-sizing: border-box;\n      overflow: visible;\n      cursor: move;\n      border: 1px dashed #fff;\n      box-shadow: 0 0 0 9999px rgb(0 0 0 / 40%);\n      touch-action: none;\n    }\n\n    .handle {\n      position: absolute;\n      z-index: 2;\n      width: 28%;\n      aspect-ratio: 1 / 1;\n      background-color: rgb(2 2 2 / 1%);\n      border-radius: 50%;\n      transition: background-color 0.2s ease;\n    }\n\n    .handle::after {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      width: 10px;\n      height: 10px;\n      content: '';\n      background: var(--vp-c-brand-1, #3d61e3);\n      border-radius: 50%;\n      transform: translate(-50%, -50%);\n    }\n\n    .handle:hover,\n    .handle:active {\n      background-color: rgb(2 2 2 / 50%);\n    }\n\n    .top-left {\n      top: 0;\n      left: 0;\n      cursor: nwse-resize;\n      transform: translate(-50%, -50%);\n    }\n\n    .top-right {\n      top: 0;\n      right: 0;\n      cursor: nesw-resize;\n      transform: translate(50%, -50%);\n    }\n\n    .bottom-right {\n      right: 0;\n      bottom: 0;\n      cursor: nwse-resize;\n      transform: translate(50%, 50%);\n    }\n\n    .bottom-left {\n      bottom: 0;\n      left: 0;\n      cursor: nesw-resize;\n      transform: translate(-50%, 50%);\n    }\n  `\n\n  @property({ attribute: false }) imgFile: File | null = null\n  @property({ type: String, attribute: 'aspect-ratio' }) aspectRatio = '16 / 9'\n  @property({ type: Number, attribute: 'default-width' }) defaultWidth = 320\n  @property({ type: Number, attribute: 'default-height' }) defaultHeight = 180\n  @property({ type: String, attribute: 'zoom-type' }) zoomType: ZoomType = 'fixed'\n\n  @state() private _errorMessage = ''\n  @state() private _imageUrl = ''\n  @state() private _cropRect: CropRect = { x: 0, y: 0, width: 320, height: 180 }\n  @state() private _imageRect: DisplayRect = { x: 0, y: 0, width: 0, height: 0 }\n\n  @query('.img-box') private _container?: HTMLDivElement\n  @query('.image') private _image?: HTMLImageElement\n\n  private _resizeObserver: ResizeObserver | null = null\n  private _dragType: HandleType | null = null\n  private _dragOrigin: { x: number, y: number } | null = null\n  private _dragStartRect: CropRect | null = null\n  private _pendingReset = true\n  private _rafId = 0\n\n  connectedCallback() {\n    super.connectedCallback()\n    window.addEventListener('pointermove', this._handlePointerMove)\n    window.addEventListener('pointerup', this._handlePointerUp)\n    window.addEventListener('pointercancel', this._handlePointerUp)\n  }\n\n  firstUpdated() {\n    if (typeof ResizeObserver === 'undefined') {\n      return\n    }\n\n    this._resizeObserver = new ResizeObserver(() => {\n      this._scheduleLayoutSync()\n    })\n    this._resizeObserver.observe(this)\n  }\n\n  disconnectedCallback() {\n    super.disconnectedCallback()\n    this._revokeImageUrl()\n    this._resizeObserver?.disconnect()\n    if (this._rafId) {\n      cancelAnimationFrame(this._rafId)\n      this._rafId = 0\n    }\n    window.removeEventListener('pointermove', this._handlePointerMove)\n    window.removeEventListener('pointerup', this._handlePointerUp)\n    window.removeEventListener('pointercancel', this._handlePointerUp)\n  }\n\n  updated(changed: Map<string, unknown>) {\n    if (changed.has('imgFile')) {\n      this._applyImageFile()\n    }\n\n    if (changed.has('defaultWidth') || changed.has('defaultHeight') || changed.has('aspectRatio') || changed.has('zoomType')) {\n      this._pendingReset = true\n      this._scheduleLayoutSync()\n    }\n  }\n\n  async crop() {\n    if (!this._image || !this._imageRect.width || !this._image.naturalWidth || !this._image.naturalHeight) {\n      return null\n    }\n\n    const scale = this._image.naturalWidth / this._imageRect.width\n    const cropX = Math.max(this._cropRect.x - this._imageRect.x, 0) * scale\n    const cropY = Math.max(this._cropRect.y - this._imageRect.y, 0) * scale\n    const cropWidth = Math.max(this._cropRect.width * scale, 1)\n    const cropHeight = Math.max(this._cropRect.height * scale, 1)\n\n    const canvas = document.createElement('canvas')\n    canvas.width = Math.round(cropWidth)\n    canvas.height = Math.round(cropHeight)\n    const context = canvas.getContext('2d')\n\n    if (!context) {\n      return null\n    }\n\n    context.drawImage(\n      this._image,\n      cropX,\n      cropY,\n      cropWidth,\n      cropHeight,\n      0,\n      0,\n      canvas.width,\n      canvas.height,\n    )\n\n    return await new Promise<File | null>((resolve) => {\n      canvas.toBlob((blob) => {\n        if (!blob) {\n          resolve(null)\n          return\n        }\n\n        resolve(new File([blob], 'cropped_image.png', { type: 'image/png' }))\n      }, 'image/png')\n    })\n  }\n\n  resize() {\n    this._pendingReset = true\n    this._resetCropRect()\n  }\n\n  private _applyImageFile() {\n    this._revokeImageUrl()\n\n    if (!this.imgFile) {\n      this._errorMessage = ''\n      this._imageUrl = ''\n      this._pendingReset = true\n      this._cropRect = {\n        x: 0,\n        y: 0,\n        width: this.defaultWidth,\n        height: this.defaultHeight,\n      }\n      return\n    }\n\n    if (!this.imgFile.type.startsWith('image/')) {\n      this._errorMessage = '文件类型错误'\n      this._imageUrl = ''\n      return\n    }\n\n    this._errorMessage = ''\n    this._imageUrl = URL.createObjectURL(this.imgFile)\n    this._pendingReset = true\n  }\n\n  private _revokeImageUrl() {\n    if (this._imageUrl) {\n      URL.revokeObjectURL(this._imageUrl)\n    }\n  }\n\n  private _scheduleLayoutSync() {\n    if (this._rafId) {\n      cancelAnimationFrame(this._rafId)\n    }\n\n    this._rafId = requestAnimationFrame(() => {\n      this._rafId = 0\n      this._syncImageRect()\n    })\n  }\n\n  private _syncImageRect() {\n    if (!this._container || !this._image || !this._image.naturalWidth || !this._image.naturalHeight) {\n      return\n    }\n\n    const containerWidth = this._container.clientWidth || this.clientWidth\n    const containerHeight = this._container.clientHeight || this.clientHeight\n    if (!containerWidth || !containerHeight) {\n      return\n    }\n\n    const scale = Math.min(\n      containerWidth / this._image.naturalWidth,\n      containerHeight / this._image.naturalHeight,\n    )\n\n    const width = this._image.naturalWidth * scale\n    const height = this._image.naturalHeight * scale\n    const x = (containerWidth - width) / 2\n    const y = (containerHeight - height) / 2\n\n    this._imageRect = { x, y, width, height }\n\n    if (this._pendingReset) {\n      this._resetCropRect()\n      this._pendingReset = false\n    }\n    else {\n      this._cropRect = this._clampMoveRect(this._cropRect)\n    }\n  }\n\n  private _resetCropRect() {\n    const aspect = parseAspectRatio(this.aspectRatio)\n    const availableWidth = this._imageRect.width || this.defaultWidth\n    const availableHeight = this._imageRect.height || this.defaultHeight\n\n    let width = Math.min(this.defaultWidth, availableWidth)\n    let height = Math.min(this.defaultHeight, availableHeight)\n\n    if (this.zoomType === 'fixed') {\n      height = width / aspect\n      if (height > availableHeight) {\n        height = availableHeight\n        width = height * aspect\n      }\n    }\n\n    width = Math.min(width, availableWidth)\n    height = Math.min(height, availableHeight)\n\n    this._cropRect = {\n      x: this._imageRect.x + (availableWidth - width) / 2,\n      y: this._imageRect.y + (availableHeight - height) / 2,\n      width,\n      height,\n    }\n  }\n\n  private _handleImageLoad = () => {\n    this._scheduleLayoutSync()\n  }\n\n  private _handlePointerDown = (type: HandleType, event: PointerEvent) => {\n    event.preventDefault()\n    event.stopPropagation()\n    this._dragType = type\n    this._dragOrigin = { x: event.clientX, y: event.clientY }\n    this._dragStartRect = { ...this._cropRect }\n  }\n\n  private _handlePointerMove = (event: PointerEvent) => {\n    if (!this._dragType || !this._dragOrigin || !this._dragStartRect) {\n      return\n    }\n\n    event.preventDefault()\n    const deltaX = event.clientX - this._dragOrigin.x\n    const deltaY = event.clientY - this._dragOrigin.y\n\n    if (this._dragType === 'move') {\n      this._cropRect = this._clampMoveRect({\n        ...this._dragStartRect,\n        x: this._dragStartRect.x + deltaX,\n        y: this._dragStartRect.y + deltaY,\n      })\n      return\n    }\n\n    this._cropRect = this._resizeByHandle(this._dragType, this._dragStartRect, deltaX, deltaY)\n  }\n\n  private _handlePointerUp = () => {\n    this._dragType = null\n    this._dragOrigin = null\n    this._dragStartRect = null\n  }\n\n  private _clampMoveRect(rect: CropRect) {\n    const maxX = this._imageRect.x + this._imageRect.width - rect.width\n    const maxY = this._imageRect.y + this._imageRect.height - rect.height\n\n    return {\n      ...rect,\n      x: clamp(rect.x, this._imageRect.x, maxX),\n      y: clamp(rect.y, this._imageRect.y, maxY),\n    }\n  }\n\n  private _resizeByHandle(handle: Exclude<HandleType, 'move'>, startRect: CropRect, deltaX: number, deltaY: number) {\n    if (this.zoomType === 'free') {\n      return this._resizeFree(handle, startRect, deltaX, deltaY)\n    }\n\n    return this._resizeFixed(handle, startRect, deltaX)\n  }\n\n  private _resizeFree(handle: Exclude<HandleType, 'move'>, startRect: CropRect, deltaX: number, deltaY: number) {\n    const minSize = 40\n    const left = startRect.x\n    const top = startRect.y\n    const right = startRect.x + startRect.width\n    const bottom = startRect.y + startRect.height\n\n    if (handle === 'top-left') {\n      const x = clamp(left + deltaX, this._imageRect.x, right - minSize)\n      const y = clamp(top + deltaY, this._imageRect.y, bottom - minSize)\n      return { x, y, width: right - x, height: bottom - y }\n    }\n\n    if (handle === 'top-right') {\n      const newRight = clamp(right + deltaX, left + minSize, this._imageRect.x + this._imageRect.width)\n      const y = clamp(top + deltaY, this._imageRect.y, bottom - minSize)\n      return { x: left, y, width: newRight - left, height: bottom - y }\n    }\n\n    if (handle === 'bottom-right') {\n      const newRight = clamp(right + deltaX, left + minSize, this._imageRect.x + this._imageRect.width)\n      const newBottom = clamp(bottom + deltaY, top + minSize, this._imageRect.y + this._imageRect.height)\n      return { x: left, y: top, width: newRight - left, height: newBottom - top }\n    }\n\n    const x = clamp(left + deltaX, this._imageRect.x, right - minSize)\n    const newBottom = clamp(bottom + deltaY, top + minSize, this._imageRect.y + this._imageRect.height)\n    return { x, y: top, width: right - x, height: newBottom - top }\n  }\n\n  private _resizeFixed(handle: Exclude<HandleType, 'move'>, startRect: CropRect, deltaX: number) {\n    const aspect = parseAspectRatio(this.aspectRatio)\n    const minWidth = 40\n    const startRight = startRect.x + startRect.width\n    const startBottom = startRect.y + startRect.height\n\n    if (handle === 'top-left') {\n      let width = clamp(startRect.width - deltaX, minWidth, startRight - this._imageRect.x)\n      width = Math.min(width, (startBottom - this._imageRect.y) * aspect)\n      const height = width / aspect\n      return { x: startRight - width, y: startBottom - height, width, height }\n    }\n\n    if (handle === 'top-right') {\n      let width = clamp(startRect.width + deltaX, minWidth, this._imageRect.x + this._imageRect.width - startRect.x)\n      width = Math.min(width, (startBottom - this._imageRect.y) * aspect)\n      const height = width / aspect\n      return { x: startRect.x, y: startBottom - height, width, height }\n    }\n\n    if (handle === 'bottom-right') {\n      let width = clamp(startRect.width + deltaX, minWidth, this._imageRect.x + this._imageRect.width - startRect.x)\n      width = Math.min(width, (this._imageRect.y + this._imageRect.height - startRect.y) * aspect)\n      const height = width / aspect\n      return { x: startRect.x, y: startRect.y, width, height }\n    }\n\n    let width = clamp(startRect.width - deltaX, minWidth, startRight - this._imageRect.x)\n    width = Math.min(width, (this._imageRect.y + this._imageRect.height - startRect.y) * aspect)\n    const height = width / aspect\n    return { x: startRight - width, y: startRect.y, width, height }\n  }\n\n  render() {\n    const imageStyle = this._imageRect.width\n      ? styleMap({\n          left: `${this._imageRect.x}px`,\n          top: `${this._imageRect.y}px`,\n          width: `${this._imageRect.width}px`,\n          height: `${this._imageRect.height}px`,\n        })\n      : ''\n\n    const cropStyle = styleMap({\n      left: `${this._cropRect.x}px`,\n      top: `${this._cropRect.y}px`,\n      width: `${this._cropRect.width}px`,\n      height: `${this._cropRect.height}px`,\n      aspectRatio: this.zoomType === 'fixed' ? this.aspectRatio : '',\n    })\n\n    return html`\n      <div part=\"container\" class=\"img-box\">\n        ${this._errorMessage\n          ? html`<div part=\"error-message\" class=\"error-message\">${this._errorMessage}</div>`\n          : this._imageUrl\n            ? html`\n                <img\n                  part=\"image\"\n                  class=\"image\"\n                  style=${imageStyle}\n                  src=${this._imageUrl}\n                  alt=\"\"\n                  @load=${this._handleImageLoad}\n                />\n                <div\n                  part=\"crop-box\"\n                  class=\"crop-tool-box\"\n                  style=${cropStyle}\n                  @pointerdown=${(event: PointerEvent) => this._handlePointerDown('move', event)}\n                >\n                  <div\n                    part=\"handle top-left\"\n                    class=\"handle top-left\"\n                    @pointerdown=${(event: PointerEvent) => this._handlePointerDown('top-left', event)}\n                  ></div>\n                  <div\n                    part=\"handle top-right\"\n                    class=\"handle top-right\"\n                    @pointerdown=${(event: PointerEvent) => this._handlePointerDown('top-right', event)}\n                  ></div>\n                  <div\n                    part=\"handle bottom-right\"\n                    class=\"handle bottom-right\"\n                    @pointerdown=${(event: PointerEvent) => this._handlePointerDown('bottom-right', event)}\n                  ></div>\n                  <div\n                    part=\"handle bottom-left\"\n                    class=\"handle bottom-left\"\n                    @pointerdown=${(event: PointerEvent) => this._handlePointerDown('bottom-left', event)}\n                  ></div>\n                </div>\n              `\n            : html`<div part=\"placeholder\" class=\"placeholder\">请选择图片</div>`}\n      </div>\n    `\n  }\n}\n"],"names":["clamp","value","min","max","parseAspectRatio","left","right","part","QxsPhotoCropTool","LitElement","type","event","deltaX","deltaY","changed","scale","cropX","cropY","cropWidth","cropHeight","canvas","context","resolve","blob","containerWidth","containerHeight","width","height","x","y","aspect","availableWidth","availableHeight","rect","maxX","maxY","handle","startRect","top","bottom","newRight","newBottom","minWidth","startRight","startBottom","imageStyle","styleMap","cropStyle","html","css","__decorateClass","property","state","query","safeCustomElement"],"mappings":"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"}