Skip to content

Image: Cropped/masked editing #35

@dvoytenko

Description

@dvoytenko

Feature description

  • How does the image editing work?
  • How does it interop with the selection transformers?
  • How are the editing tools overlayed?
  • How do we show the background for image cropping?

Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • A suggestion is made based on the findings

Implementation brief

  • A very preliminary implementation demo is here. Here's a short video.
  • There are two transformable elements involved: the image's shell (the element itself) and the image panning within the cropped shell. Ideally we will use the Moveable library for them as well.
  • These transformables are mostly independent from each other: the elements are not grouped and not operating as a group. But they define boundaries and guidelines for each other. Thus this will require two Moveable components.
  • I can reuse the existing "selection" Moveable implemented in Basic implementation of react-moveable npm package for dragging, resizing, rotating ampproject/amp-wp#3798 for the element's shell or we can add a new one. The differences: we have to restyle the resizing grips to crop style and we need to disable dragging and rotation. The demo borrows the Moveable from Basic implementation of react-moveable npm package for dragging, resizing, rotating ampproject/amp-wp#3798 but changes it quite a bit. But, as in Basic implementation of react-moveable npm package for dragging, resizing, rotating ampproject/amp-wp#3798 resizing is done by outline and the actual element is resized once it's released. I think it's better since it shows a clear indication of before/after state. The resize operation itself is expensive: it updates pan position, scale factor, etc.
  • The second Moveable only enables dragging. It's for panning of the full image in the cropped shell. Unlike resize - the demo implements panning immediately to show exactly how focal point changes. Note that panning is very cheap comparing to resize.
  • It's very important that panning Moveable is on top of the resizing one. This appears a limitation of the library.
  • The demo uses state for element properties. This will, of course, change.
  • The panning/cropping implemented using two images on top of each other that are 100% synchronized. The bottom image has opacity of 0.5 and is used to show the "ghost" image behind the actual image. The top image has opacity of 1 and is clipped to the element's outline.
  • Demo adds scaler per design mocks. However, this scaler "feels" more like an edit panel, with the only exception that it's not docked in the side-panel on the right. It looks like design mocks add more such "floating" panels for other elements. Perhaps we can implement them the same way as side-panels, except that they will be floating. E.g. IMAGE_SCALE_PANEL: {float: true, anchor: 'bottom'} or such.
  • Big annoyance: if the element properties are updated some other way, there's no clear way to "refresh" Moveable component to remeasure and redraw selection/anchor lines. For now I'm resetting these components using key-increment. Very ugly. So, lmk if you have an advice for this.
  • It looks like Moveable doesn't support bounds for resizing - that's very annoying. LMK if you found a way.
  • Idle observation: we need some form of an ESC stack where different transient operations could push themselves to. When ESC is clicked, we would only need to cancel the top-most operation and pop it from the stack. E.g. while resizing ESC should cancel resizing and go back to the previous size. The subsequent ESC should just exist the edit mode. Etc.

QA testing instructions

Demo

Changelog entry

Metadata

Metadata

Assignees

Labels

P0Critical, drop everything

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions