vue-advanced-cropper

repository·master·Indexed 22 days ago

https://github.com/advanced-cropper/vue-advanced-cropper

A highly customizable image cropping library for Vue.js supporting mobile and desktop. It provides a Cropper component with various cropping modes, aspect ratio restrictions, and canvas/coordinate outputs. The library includes specialized components like BoundingBox, DraggableArea, StencilPreview, and CircleStencil to allow developers to build fully custom cropping UIs.

Tokens
29.5K
Snippets
94
Records
133
Agent score
75%

What's inside vue-advanced-cropper

  1. How coordinates are reset during image changes

    master

    The resetCoordinates method is triggered automatically on every successful image change. It follows this sequence:

    1. Default Size: Calculates size using defaultSize (returns { width, height }).
    2. Default Position: Calculates position using defaultPosition (returns { left, top }).
    3. Transform Construction: Forms a transforms array: [{ width, height }, { left, top }].
    4. Delayed Transforms: If there were transforms queued (applied after an image change but before the new image finished loading), they are appended to the array.
    5. Application: The transforms are applied to the cropper.
  2. How to create a custom stencil

    master

    A custom stencil is a Vue component that allows you to define unique cropping shapes (like a circle) and custom resize/move logic. To work correctly with the cropper, a custom stencil must follow a specific contract:

    1. Receive Service Props: It must accept image, coordinates, transitions, and stencilCoordinates as props.
    2. Implement aspectRatios(): It must provide a method that returns an object with minimum and maximum fields (e.g., { minimum: 1, maximum: 1 } for a circle).
    3. Display the Cropped Area: Use the StencilPreview component to show the user what is being cropped.
    4. Emit Events: It must emit move, move-end, resize, and resize-end events to communicate changes back to the main cropper.
    5. Manage Positioning: Use the stencilCoordinates prop to set the stencil's position via CSS transform (specifically translate(left, top)) to avoid lag and flickering.
    <script>
    export default {
      name: 'CircleStencil',
      props: {
        image: Object,
        coordinates: Object,
        transitions: Object,
        stencilCoordinates: Object,
      },
      methods: {
        aspectRatios() {
          return { minimum: 1, maximum: 1 };
        }
      }
    };
    </script>
    
    <template>
      <div class="circle-stencil" :style="style"></div >
    </template>
  3. Requirements for creating a custom Stencil component

    master

    A stencil can be any arbitrary component, but to function correctly with the Cropper's resize algorithm and interaction model, it must meet these requirements:

    1. Inscription: It should be inscribed within the box represented by the provided coordinates (width, height, left, top).
    2. Aspect Ratio Support: If the stencil has aspect ratio constraints, it must implement an aspectRatios() method. This method should return an object containing minimum and maximum aspect ratio values.
    3. Event Emission: It must emit resize and move events to communicate user interactions back to the cropper.
    4. Visual Feedback: It should display the cropped part of the image (often via a preview).
  4. Update Cropper markup and background styling

    master

    When migrating to 1.0+, note the following changes to how the cropper renders:

    1. Background Boundaries: The background is now limited by the cropper boundary. If you use background-class to set a background-color, it will only fill the area within the cropper boundary. To apply a background color to the entire cropper area (including parts wider or taller than the boundary), use the standard class attribute instead.
    2. Foreground Layer: A new foreground layer has been introduced. You can customize this layer using the foreground-class prop. This layer sits between the image and the stencil and is typically used to darken the image.
  5. Understand Circle Stencil service props

    master

    ::: danger Important: Do not pass these props directly to the CircleStencil component. They are internal service props injected by the Cropper component itself. :::

    • image: An object containing image metadata: { src, width, height, transforms, loaded }.
    • stencilCoordinates: An object { left, right, height, width } representing the stencil's coordinates relative to the visible area.
    • transitions: A Boolean indicating if transitions are currently allowed.
  6. Understand the Cropper's internal model: Boundaries, Visible Area, and Coordinates

    master

    The Cropper component's logic is built on four key concepts:

    • Boundaries: The area inside the cropper that contains the image. By default, this is the image fitted to the cropper, but you can use the defaultBoundaries prop to force the boundaries to fill the cropper.
    • Visible Area: The specific part of the image that the user sees when the image is zoomed or translated. It must have the same aspect ratio as the boundaries. It is defined by left, top, width, and height relative to the image.
    • Coordinates: The actual cropped coordinates (left, top, width, height) of the image fragment relative to the image, located within the visibleArea.
    • Image: The source content being manipulated.
  7. Use the anchor property for accurate resizing

    master

    The anchor property is critical for implementing accurate stencil resizing algorithms.

    When building a resize algorithm, relying solely on the current cursor position can lead to inaccuracies because the cursor might not align perfectly with the handler's center after a movement. To ensure the mouse cursor remains at the exact same relative point on the handler where the user started the drag, you should use the anchor coordinates to adjust the resize box (the stencil). By calculating the offset based on the anchor, you can compensate for the movement and achieve the expected visual result.

  8. How coordinates are updated via applyTransforms

    master

    The applyTransforms method is the core mechanism for updating coordinates. It is used internally by setCoordinates, resetCoordinates, and when adapting to prop changes like minWidth, maxWidth, minHeight, or maxHeight.

    Note: Do not call applyTransforms directly.

    Method Signature

    applyTransforms(transforms, autoZoom)

    • transforms: An object containing new coordinates or an array containing one coordinate object.
    • autoZoom: A boolean indicating whether to use the auto-zoom algorithm (translating and resizing the visible area to fit the new coordinates).

    Transformation Logic

    For each transform provided:

    1. Size (width or height): Uses the approximatedSize algorithm to create a box. This respects aspect ratio and min/max constraints. The box is moved back to its previous position based on positionRestrictions (note: it may move outside the current visibleArea).
    2. Position (left or top): Moves the box to the specified coordinates, respecting positionRestrictions.
    3. Auto Zoom: If autoZoom is true, the visible area is transformed so that the new coordinates fit within it.
    4. Finalization: Calls onChangeCoordinates to update internal state and emit the corresponding event.
  9. How the Cropper and Stencil abstractions work together

    master

    The library is conceptually divided into two parts to allow for maximum flexibility:

    1. Cropper: The root component that manages the logic. It handles the image, boundaries, visible area, and the mathematical coordinates of the crop.
    2. Stencil: An arbitrary component used to visualize the cropped area and provide user interaction (moving and resizing).

    The Cropper operates on abstract coordinates, while the Stencil is responsible for rendering those coordinates as a UI element that the user can manipulate. This separation allows you to build highly custom cropping interfaces by providing your own stencil component.

    <!-- The Cropper manages logic, while the Stencil manages UI/Interaction -->
    <cropper>
      <my-custom-stencil />
    </cropper>