Skip to content

ImageEditor Component ​

File Information ​

  • Path: app/components/asset/ImageEditor.vue
  • Purpose: Interactive image editor powered by Cropper.js. Supports crop, flip, rotate, resize, compress, and undo/redo. Embedded in the asset-detail panel's "Edit" tab.

Overview ​

ImageEditor wraps Cropper.js and exposes a reactive API through emitted events. It does not persist changes itself — the parent (ImageEditActions) collects the final canvas data and calls the save endpoint.

Key features:

  • Cropper initialisation on <img> load via initCropper(); exposes cropperInstance on the component for external control
  • Undo/redo via an actionHistory stack: each destructive operation (flip, rotate, crop-apply) pushes a snapshot
  • Compress mode — when isCompress: true, the crop UI hides and the parent drives dimension inputs through update:dimensions events
  • Loading overlay — v-show="processing || !isCanvasReady" covers the canvas during Jimp or Cropper operations; uses AppLoader vs v-progress-circular depending on white-label state
  • Error state — @error on the <img> emits image-error: true so the parent can show a fallback

Props ​

PropTypeDefaultDescription
srcStringrequiredImage URL passed to the <img> element
altString''Alt text for the image
mimeTypeString'image/png'MIME type used when exporting the edited canvas
isCompressBooleanfalseSwitches to compress/resize mode — hides crop UI
originalDataObject | nullnullOriginal image dimensions and metadata for reset
originalImageDataArrayBuffer | nullnullRaw image bytes for Jimp-based operations
imageDataLoadingBooleanfalseShows skeleton while the parent fetches originalImageData

Events ​

EventPayloadWhen
cropper-readybooleanCropper.js initialised (or destroyed)
image-errorbooleanThe <img> fires an error
update:dimensionsImageDimensionsUpdateCanvas dimensions change (crop/resize)
update:transformTransformStateFlip/rotate state changes

Exposed Ref ​

cropperInstance is exposed via defineExpose so the parent (ImageEditActions) can call Cropper.js methods directly:

typescript
const editor = ref<InstanceType<typeof ImageEditor>>()
editor.value?.cropperInstance?.rotate(90)
editor.value?.cropperInstance?.reset()

Undo/Redo ​

Each flip or rotate operation pushes a { type, data } entry onto actionHistory. The parent calls editor.value?.undo() to pop and replay the previous state. History is cleared on image source change.

Bicubic Resize ​

The bicubic algorithm (restored in fix(mig-09)) uses Jimp's RESIZE_BICUBIC for high-quality downscaling. This runs in a Web Worker to avoid blocking the main thread during large image processing.