Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] Add freeform image cropper component #63335

Draft
wants to merge 34 commits into
base: trunk
Choose a base branch
from

Conversation

kevin940726
Copy link
Member

@kevin940726 kevin940726 commented Jul 10, 2024

What?

The first draft of implementing a freeform image cropper component aiming to solve #22582.

Note

This PR is a WIP.
Please see the features and TODOs section below. We want to open a draft PR first to gather some very early feedback to ensure we are on the right track.

Why?

See #22582. The current image cropping tool lacks some advanced features we want to support. The library we used doesn't provide the features we need, and we can't find other third-party libraries that do. This component is an attempt to implement our own solution and potentially use it in the Media Library revamp.

How?

Lots of math 🧠.

Add a new <ImageCropper> component in the @wordpress/components package. Currently, it's not exported at all and only available in the storybook environment for testing. We'll export it as a private component next once we reach a point where it can be integrated into the block editor.

The basic usage is as follow:

<ImageCropper.Provider width={250} height={200} src={IMG}>
  <ImageCropper />
</ImageCroppper.Provider>

See the storybook for advanced usage.

Features and TODOs

Here's an unexhaustive list of supported features and TODOs with demo recordings.

  • Resizing

    • ✅ Resize the cropping window

      Kapture.2024-08-01.at.15.19.18.mp4

    • ✅ Scale after resizing

      Kapture.2024-08-01.at.15.19.18.mp4

    • ✅ Resize after rotation

      Kapture.2024-08-01.at.15.20.12.mp4

    • Resize max bounds

      It should not be resized to be bigger than the image. Additionally, zooming out while resizing near the max bounds is nice-to-have. Here's a demo from the Google Photos iOS app:

      RPReplay_Final1722504920.mov

  • Dragging

    • ✅ Drag/pan the image

      Kapture.2024-08-01.at.15.23.01.mp4

    • ✅ Drag max bounds

      Kapture.2024-08-01.at.15.23.34.mp4

    • ✅ Drag after rotation

      Kapture.2024-08-01.at.15.25.06.mp4

  • Rotation

    • ✅ Rotate the image around the center of the cropping window

      Kapture.2024-08-02.at.01.40.35.mp4

    • ✅ Rotate 90 degrees (clockwise and counterclockwise)

      Kapture.2024-08-01.at.15.25.06.mp4

    • ✅ Scale after rotation

      Kapture.2024-08-01.at.15.28.32.mp4

    • Rotation animation

      The cropping window should also rotate with the image.

      Kapture.2024-08-01.at.15.29.07.mp4

  • Flipping

    • ✅ Flip the image horizontally

      Flipping the image vertically can be achieved by rotating and flipping.

      Kapture.2024-08-01.at.15.30.12.mp4

    • ✅ Flip animation

      Kapture.2024-08-01.at.15.30.12.mp4

  • Zooming

    • ✅ Zoom in/out the image around the cursor's position by pinching

      Kapture.2024-08-01.at.15.30.50.mp4

    • ✅ Zoom after rotation

      Kapture.2024-08-01.at.15.31.44.mp4

    • ✅ Zoom max and min bounds

      Currently, the maximum and minimum scale bounds are set to 1 and 10 respectively.

    • Zoom with a mouse or keyboard.

    • Resize after zooming out

  • Aspect ratio

    • Lock/Unlock the aspect ratio
  • Responsive

    • ✅ Resize the container after resizing the window

      It mostly works but has some bugs and lacks testing.

  • Accessibility

    • Keyboard shortcuts
    • Screen reader support
    • Reduced motion support
  • Styling

    • Designers' approval
  • Integration

  • Testing

    • Unit tests
    • End-to-end tests

Testing Instructions

For testing in the image block in the editor, enable the gutenberg experiment under "Gutenberg" -> "Experiments" -> "Redesigned image cropper".

Kapture.2024-08-16.at.15.34.13.mp4

For testing the component in the storybook:

  1. Run the storybook dev server (npm run storybook:dev)
  2. Visit http://localhost:50240/iframe.html?args=&id=components-imagecropper--inline to view and play with the component.

Testing Instructions for Keyboard

This component is currently not accessible to the keyboard, but it's on the plan.

@kevin940726 kevin940726 added [Feature] Media Anything that impacts the experience of managing media [Type] Experimental Experimental feature or API. [Feature] Component System WordPress component system labels Jul 10, 2024
@kevin940726 kevin940726 self-assigned this Jul 10, 2024
@jasmussen
Copy link
Contributor

Nice one, took it for a quick spin:

cropping

This is looking solid and promising. Small bug with zooming too much and it flips the image.

This is very nascent, so hard to fully review until it's in a branch, implemented for the Image block, but a few general observations/thoughts:

  • The dark frame around it we probably want to avoid.
  • We should not have 8 resize handles. In the editor for resizing the image, we have 2, right and bottom. There's an open question around how the resize handles left and right will work when this gets transplanted into the canvas, that's likely also related to the dark frame for "scaling up", so those are some questions we will need to consider later. But we can at least remove the resize handles in the corner.
  • We'll need to think about where to place the slider for rotating the image, and whether that slider is the right interface for it. E.g. it can't live inside the block toolbar directly. Something like the gradient direction tool may be useful here.

Nice work.

@talldan
Copy link
Contributor

talldan commented Jul 10, 2024

We'll need to think about where to place the slider for rotating the image, and whether that slider is the right interface for it. E.g. it can't live inside the block toolbar directly. Something like the gradient direction tool may be useful here.

If the number of resize handles were reduced, there could be rotation handles on the corners, or some applications have a handle that extends out like this:
Screenshot 2024-07-10 at 3 18 33 pm

@andrewserong
Copy link
Contributor

This is feeling really nice to use so far! Another couple of questions, and possibly for @jasmussen (and once we integrate with the image block):

  • How might we expose aspect ratio controls at the same time? The dropdown in the block toolbar can be a bit hidden for users, I've seen some people miss them altogether.
  • The scrollwheel to zoom feature works pretty well for me, but I didn't notice it at first. Would we also want to have zoom in / zoom out buttons, alongside the rotation control?

@kevin940726
Copy link
Member Author

We'll need to think about where to place the slider for rotating the image, and whether that slider is the right interface for it.

Most cropping tools that inspire this PR have their rotation slider below the image. For instance, here's Google Photos web:

Kapture.2024-07-11.at.13.47.33.mp4

The dimmed background is also needed in this case. I think we can also consider placing the slider at the bottom of the editing canvas? It can be toggled with a click in the block toolbar since it's an advanced usage.

there could be rotation handles on the corners, or some applications have a handle that extends out like this

I also considered this, but IMO this sort of UI only makes sense when you're rotating the cropping window itself, not the background image. Because this PR currently assumes that every cropped image should still be an unrotated rectangle, rotating the cropping window doesn't make sense here.

The scrollwheel to zoom feature works pretty well for me, but I didn't notice it at first. Would we also want to have zoom in / zoom out buttons, alongside the rotation control?

I think we should, at least for feature completion of accessibility. We can potentially add more keyboard controls too (Ctrl++/-?) in addition to the UI control.

@jasmussen
Copy link
Contributor

How might we expose aspect ratio controls at the same time? The dropdown in the block toolbar can be a bit hidden for users, I've seen some people miss them altogether.

We need a fresh design for this. The following much older design could be a starting point, but it needs a fresh take that is more like the existing and with a smaller visual diff.
Crop and rotate in isolation
Crop and rotate in-canvas i2

For example, the modal may look fun at a quick glance, but let's not do this, it's not compatible with cropping tools that are likely to also exist in a future media library, and it also is a clunky amount of additional steps compared to a more lean and light-weight in-canvas cropping tool. I'm sharing it only because there may be some elements as far as aspect ratio that may be worth revisiting.

Note specifically how the block toolbar itself becomes modal. Instead of having a single image block toolbar that grows wider with crop tools, this one proposes a drilldown effect for the block toolbar, affording better and clearer tools. Not sure how feasible, but it's worth resurfacing.

Figma.

The scrollwheel to zoom feature works pretty well for me, but I didn't notice it at first. Would we also want to have zoom in / zoom out buttons, alongside the rotation control?

I like the slider in the toolbar, though I'm also aware that this is substantially more difficult to get right, than it looks at a glance. So also here it would seem useful to free up space in the block toolbar, however we can. Since it's already modal through the apply/cancel actions, perhaps that can be a way to take up more space in the block toolbar?

@talldan
Copy link
Contributor

talldan commented Jul 11, 2024

I also considered this, but IMO this sort of UI only makes sense when you're rotating the cropping window itself, not the background image. Because this PR currently assumes that every cropped image should still be an unrotated rectangle, rotating the cropping window doesn't make sense here.

That's a good point 😄

I think my main concern would be how this works in terms of inline editing when there are other blocks after the image, and also when there's a caption in that position. Something more minimal might be easier to wrangle. Having secondary UI controls in the inspector or toolbar is still always an option (and might be needed for accessibility).

It can be something to iterate on though, it'll be interesting to see the designs.

@kevin940726
Copy link
Member Author

Kapture.2024-07-16.at.18.30.39.mp4

I added the rotation (90deg clockwise and counter-clockwise) feature. The reason angle and turns(can't think of a better name 😅) are separated is because the value for angle is between -45 to 45, and we need a way to distinguish between angle: 45, turns: 0 and angle: -45, turns: 1.

Currently, getImageBlob for rotated images doesn't work as expected. I probably need some help on some math there and simplify the logic in reducer 😅.

};
}

function imageCropperReducer( state: State, action: Action ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great to add some inline comments to the code within this reducer. Geometry code like this is notoriously hard to read.

I spotted a bug, if I resize twice from the bottom-right, the top-left of the resizable box jumps position incorrectly:

Kapture.2024-07-17.at.12.28.41.mp4

I found it a little difficult to understand the intention of the code in the RESIZE_WINDOW action, so some comments would help greatly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it a little difficult to understand the intention of the code in the RESIZE_WINDOW action, so some comments would help greatly.

Yeah, that's one of the things I need help with 😅. Half the time I don't even know what I'm doing 🤦. I'd need to re-organize my thoughts and refactor this in a way that makes it easier to write comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here might help - #63335 (comment).

There might be one or two things I got wrong because I'm mostly doing this as a mental exercise, but I think a good rule is to not modify the underlying image coordinates until the user hits 'apply'. Instead store the manipulations in a 'transform' object that describes how the image has been manipulated. It might be similar to what you're doing already, but I found it difficult to tell.

I think the important thing is to get the reducer working correctly and then have the UI work from that state. It might be challenging with some of the opinionated UI pieces like resizableBox, but a solid foundation for the maths will make everything work much more reliably.

Comment on lines 7 to 50
export type State = {
// The container/image's width.
width: number;
// The container/image's height.
height: number;
// The rotation angle between -45deg to 45deg.
angle: number;
// The number of 90-degree turns.
turns: 0 | 1 | 2 | 3;
// The zoom scale.
scale: number;
// Whether the image is flipped horizontally.
flipped: boolean;
// The offset position of the cropper window.
offset: Position;
// The position of center of the image.
position: Position;
// The size of the cropper window.
size: Size;
// Whether the cropper window is resizing.
isResizing: boolean;
// Whether the image is dragging/moving.
isDragging: boolean;
};
Copy link
Contributor

@talldan talldan Jul 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good aim could be to model the state like this:

State = {
    image: {
		// the image would always have a `top`/`left` of zero, because we apply `transform.translation` to move it. A rect is a web friendly storage format so might as well use it to keep things consistent.
        rect: { top, right, bottom, left, x, y, width, height }
    },
    imageTransforms: {
        rotate: number,
        scale: number, 
        translate: Vector2<number>,
        reflect: Vector2<bool>
    },
    // the resizable box
    clippingRect: { 
        rect: { top, right, bottom, left, x, y, width, height }
    },
    // UI states
    isResizing: bool,
    isDragging: bool,
}

I'm visualizing the image manipulation as two separate things.

Firstly, if you completely disregard the 'clipping rect', there are distinct changes the user can make to the image. They can rotate it (slider), zoom it (mouse wheel) and translate it (drag it). As the user makes those changes the deltas are added to the transform state. The image state doesn't change at all until the user clicks 'apply', at which point the transform state is reset to zero.

Keeping the transform as a state like this is pretty important as the scaling and rotation need to be applied before translation (moving) when transforming something geometrically around its center (assuming the origin is the center of the image, if not it can be translated to its center first before scaling, and then translated back again).

The clipping rect is a separate thing on top of that, but from what I can tell, it doesn't affect the underlying image until the user applies the crop, so I think a rect is the only state needed for it.

There might be more needed after that, for example I notice that the clipping rect and the image are often translated together (after resizing the clipping area, the image and clipping rect are recentered), but I think it'd be better to store that as a separate transform object (e.g. viewTransform) that's applied to the resizable box and the image (after the other transforms) so that they both move by the exact same amount.

This reflects pretty closely how video games work in having a series of 'transforms' (model, view, projection), though they store them in matrices:
https://gamedev.stackexchange.com/questions/178643/the-view-matrix-finally-explained

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was also going to comment that turns might be more portable/easily understood as a rotate value, possibly in combination with the deg/radian?

Copy link
Member Author

@kevin940726 kevin940726 Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean a rotate and a degree value? I never like the naming of turns so I might switch to that 😅.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean a rotate and a degree value?

Oh, the controls are separate, right? Then, yes 😄

var( --wp-cropper-window-x ),
var( --wp-cropper-window-y )
);
box-shadow: 0 0 0 100vmax rgba( 0, 0, 0, 0.5 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fantastic start. Awesome work @kevin940726

What do you think about adding some simple guide rulers? I'm using Google photos as inspiration 😄

Kapture.2024-07-22.at.15.39.57.mp4
Example
export const Resizable = styled( ResizableBox )`
	transform: translate(
		var( --wp-cropper-window-x ),
		var( --wp-cropper-window-y )
	);
	box-shadow: 0 0 0 100vmax rgba( 0, 0, 0, 0.6 );
	&:active {
		box-shadow: 0 0 0 100vmax rgba( 0, 0, 0, 0.4 );
		&::after,
		&::before,
		${ Draggable }::after, ${ Draggable }::before {
			position: absolute;
			padding: 0;
			width: 1px;
			height: 100%;
			overflow: hidden;
			left: 33.33%;
			content: ' ';
			background: rgba( 255, 255, 255, 0.33 );
			z-index: 1000;
			display: block;
		}

		&::before {
			right: 33.33%;
			left: auto;
		}

		${ Draggable }::before {
			left: auto;
			width: 100%;
			height: 1px;
			top: 33.33%;
		}

		${ Draggable }::after {
			left: auto;
			width: 100%;
			height: 1px;
			bottom: 33.33%;
			top: auto;
		}
	}
`;

Also, I know it's eye candy, but a subtle animation during the post-crop translate (not dragging) would look pleasing to my eye at least 🤗

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I think we can also show it on dragging and rotating too!.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a commit that includes the rulers and the animations!

Kapture.2024-07-29.at.15.46.56.mp4

);
Default.args = {
src: 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Hydrochoeris_hydrochaeris_in_Brazil_in_Petr%C3%B3polis%2C_Rio_de_Janeiro%2C_Brazil_09.jpg/1200px-Hydrochoeris_hydrochaeris_in_Brazil_in_Petr%C3%B3polis%2C_Rio_de_Janeiro%2C_Brazil_09.jpg',
width: 250,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be helpful to provide an example of a crop container that resizes with the window/parent container?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, absolutely! It's on the TODO list but not supported yet. I think we can first implement the core features and then make it responsive. We also need to fix that it's not cropping the image in its original resolution 😅.

@kevin940726
Copy link
Member Author

I added a section of features and TODOs in the PR description. Please let me know if any of them isn't clear! I'll try to add more too.

@ajlende
Copy link
Contributor

ajlende commented Aug 1, 2024

Related to resizing the container, when we're using this in the block editor for the image block, the crop area should be the same size as the final image. One of the goals of core block editing is to make the editing mode look as close to the preview mode as possible.

@ajlende ajlende force-pushed the add/freeform-image-cropper branch from 38d4ee5 to 797ec46 Compare August 1, 2024 16:55
Comment on lines 78 to 81
dispatch( {
type: 'ROTATE_CLOCKWISE',
isCounterClockwise: true,
} );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this API is a little confusing as one onehand it's ROTATE_CLOCKWISE and then on the other it's isCounterClockwise: true. Maybe the action type could be ROTATE_90 or something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! I renamed it to ROTATE_90_DEG in 2fd0c69.

Comment on lines 97 to 98
angle: 0,
rotations: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of interest, why does the angle needs to be stored separately to rotations? The two feel like the same thing to me.

Copy link
Contributor

@ajlende ajlende Aug 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are the same thing, but this matches the UI of the Google photos cropper that many of these interactions seemed to be based off of. One could deconstruct any angle into these two parts, but I haven't convinced myself which way would be better. Mostly thinking in terms of undo/redo.

image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! We need two separate values here so that we can distinguish between angle: 45, rotations: 0 and angle: -45, rotations: 1, which are both 45 degree but represent different states in the UI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I've had some time to reflect on this, I think I would prefer the angle in radians as part of the transform, and in order to distinguish -45 from 45, the "tilt" can be saved as part of the UI state in degrees. This keeps the UI decoupled from the actual transform so it's easier to update the UI if needed.

@ajlende
Copy link
Contributor

ajlende commented Aug 2, 2024

I was playing around with more image croppers today, and the closest ones to what I had in mind for image block cropping were Adobe Express and Canva.

Adobe Express

Adobe Express has two resizable boxes, essentially; one for the crop region and one for the image. It showcases how rotation can be done in-canvas without a slider like Google.

The part that doesn't work for us is that the positioning post crop will be different for us since we're working with an element that's part of the regular DOM flow and rules instead of a canvas where everything is absolutely positioned.

Screen.Recording.2024-08-02.at.4.13.54.PM.mov

Canva

Canva "solves" the problem by not allowing the crop area to be changed while editing, so the size of the crop area in the page always matches the final result.

Canva also adds a feature that keeps the crop are in bounds of the image that Adobe Express doesn't handle.

Screen.Recording.2024-08-02.at.3.56.36.PM.mov

Google Photos

However, Google photos handles the reflow quite nicely by resizing the image on mouse up.

Screen.Recording.2024-08-02.at.4.39.35.PM.mov

Combining them

I think we should be able to combine the Adobe Express double box model with the Canva crop area bounds constraints and the Google Photos reflow mechanic to make something that will work in both the context of inline editing for the image block and as a fixed editor in the admin redesign.

@kevin940726
Copy link
Member Author

I think we should be able to combine the Adobe Express double box model with the Canva crop area bounds constraints and the Google Photos reflow mechanic to make something that will work in both the context of inline editing for the image block and as a fixed editor in the admin redesign.

What do you have in mind for using the double box model for inline editing? If we reflow(scale) the image after resizing then the image box will grow bigger to the point that it might be difficult to fit the box into the screen 🤔.

If the idea is to adopt the rotation button, then I think we can still do that using the Google Photos UX? Possibly something like a button rather than a slider below the cropper window?

I think we can use some design feedback here too 😆.

@talldan
Copy link
Contributor

talldan commented Aug 6, 2024

If we reflow(scale) the image after resizing then the image box will grow bigger to the point that it might be difficult to fit the box into the screen 🤔.

That's the kind of thing that concerns me too. Along with the possibility of having elements of the cropping tools overlapping other blocks. Engaging spotlight mode during cropping might be an option to keep focus on the image block.

@ajlende
Copy link
Contributor

ajlende commented Aug 6, 2024

If we reflow(scale) the image after resizing then the image box will grow bigger to the point that it might be difficult to fit the box into the screen 🤔.

That's the kind of thing that concerns me too. Along with the possibility of having elements of the cropping tools overlapping other blocks. Engaging spotlight mode during cropping might be an option to keep focus on the image block.

We do have a mode where the page is zoomed out, so we can scale the page to any size to make room for the "ghost" image outside of the page if needed. #63870 added an option for a fixed 50% scale with some other UI changes, but I don't see why we couldn't use that scaling to make more room for the contextual cropping.

@kevin940726
Copy link
Member Author

We do have a mode where the page is zoomed out

Wouldn't zoom-out mode also zoom out the image cropping area, thus making it smaller to interact with?

Imagine a somewhat extreme example with a small cropping area.

image

If we scale up the cropping area to match the content size, the image background could be large enough that the rotation button is too far below to interact with. A solution would be moving the rotation button just below the cropping area, but I think that's essentially the same as the Google Photos example? 🤔

@ajlende
Copy link
Contributor

ajlende commented Aug 7, 2024

Wouldn't zoom-out mode also zoom out the image cropping area, thus making it smaller to interact with?

Yes, but I don't expect zoom out would be required for cropping. You'd probably only want to switch to zoom out mode when you're cropping things like full-width images.

If we scale up the cropping area to match the content size, the image background could be large enough that the rotation button is too far below to interact with. A solution would be moving the rotation button just below the cropping area, but I think that's essentially the same as the Google Photos example?

That's a good point, especially since we don't really have an "infinite canvas" to work with like some of these design tools. My first reaction is that it wouldn't be a problem (from a usability perspective) to have both, but saying yes to everything can lead to a busy UI that's also hard to use. Would be good to get some design input on this.

Copy link

github-actions bot commented Aug 8, 2024

Size Change: +14.3 kB (+0.81%)

Total Size: 1.78 MB

Filename Size Change
build/block-editor/content-rtl.css 4.54 kB -12 B (-0.26%)
build/block-editor/content.css 4.54 kB -13 B (-0.29%)
build/block-editor/index.min.js 256 kB +1.12 kB (+0.44%)
build/block-editor/style-rtl.css 16.4 kB +109 B (+0.67%)
build/block-editor/style.css 16.4 kB +111 B (+0.68%)
build/block-library/blocks/comment-content/style-rtl.css 120 B +30 B (+33.33%) 🚨
build/block-library/blocks/comment-content/style.css 120 B +30 B (+33.33%) 🚨
build/block-library/blocks/latest-posts/editor-rtl.css 139 B -47 B (-25.27%) 🎉
build/block-library/blocks/latest-posts/editor.css 138 B -45 B (-24.59%) 🎉
build/block-library/blocks/navigation-link/editor-rtl.css 644 B -19 B (-2.87%)
build/block-library/blocks/navigation-link/editor.css 645 B -19 B (-2.86%)
build/block-library/blocks/navigation/editor-rtl.css 2.2 kB +15 B (+0.69%)
build/block-library/blocks/navigation/editor.css 2.2 kB +13 B (+0.59%)
build/block-library/blocks/quote/theme-rtl.css 233 B +12 B (+5.43%) 🔍
build/block-library/blocks/quote/theme.css 236 B +11 B (+4.89%) 🔍
build/block-library/blocks/search/editor-rtl.css 199 B +6 B (+3.11%)
build/block-library/blocks/search/editor.css 199 B +6 B (+3.11%)
build/block-library/blocks/tag-cloud/editor-rtl.css 144 B +81 B (+128.57%) 🆘
build/block-library/blocks/tag-cloud/editor.css 144 B +81 B (+128.57%) 🆘
build/block-library/blocks/template-part/editor-rtl.css 368 B -25 B (-6.36%)
build/block-library/blocks/template-part/editor.css 368 B -25 B (-6.36%)
build/block-library/editor-rtl.css 11.9 kB -16 B (-0.13%)
build/block-library/editor.css 11.8 kB -17 B (-0.14%)
build/block-library/index.min.js 217 kB +193 B (+0.09%)
build/block-library/style-rtl.css 14.7 kB +33 B (+0.22%)
build/block-library/style.css 14.7 kB +33 B (+0.22%)
build/block-library/theme-rtl.css 708 B +6 B (+0.85%)
build/block-library/theme.css 712 B +5 B (+0.71%)
build/blocks/index.min.js 52.4 kB +32 B (+0.06%)
build/components/index.min.js 231 kB +7.35 kB (+3.29%)
build/components/style-rtl.css 12.1 kB +25 B (+0.21%)
build/components/style.css 12.1 kB +24 B (+0.2%)
build/core-commands/index.min.js 2.82 kB +13 B (+0.46%)
build/edit-post/index.min.js 12.6 kB +19 B (+0.15%)
build/edit-site/index.min.js 217 kB +1.8 kB (+0.84%)
build/edit-site/posts-rtl.css 7.4 kB +556 B (+8.13%) 🔍
build/edit-site/posts.css 7.4 kB +550 B (+8.02%) 🔍
build/edit-site/style-rtl.css 12.7 kB +495 B (+4.05%)
build/edit-site/style.css 12.7 kB +497 B (+4.07%)
build/editor/index.min.js 101 kB +1.25 kB (+1.26%)
build/editor/style-rtl.css 9.36 kB +20 B (+0.21%)
build/editor/style.css 9.35 kB +20 B (+0.21%)
build/format-library/index.min.js 8.09 kB +16 B (+0.2%)
build/interactivity/debug.min.js 16.3 kB -249 B (-1.51%)
build/interactivity/index.min.js 13.2 kB -254 B (-1.89%)
build/interactivity/router.min.js 2.8 kB +1 B (+0.04%)
build/patterns/index.min.js 7.37 kB +7 B (+0.1%)
build/reusable-blocks/index.min.js 2.55 kB +14 B (+0.55%)
build/style-engine/index.min.js 2.04 kB +12 B (+0.59%)
build/widgets/index.min.js 7.2 kB +13 B (+0.18%)
build/block-library/blocks/comment-author-name/style-rtl.css 72 B +72 B (new file) 🆕
build/block-library/blocks/comment-author-name/style.css 72 B +72 B (new file) 🆕
build/block-library/blocks/comment-date/style-rtl.css 65 B +65 B (new file) 🆕
build/block-library/blocks/comment-date/style.css 65 B +65 B (new file) 🆕
build/block-library/blocks/post-author-name/style-rtl.css 69 B +69 B (new file) 🆕
build/block-library/blocks/post-author-name/style.css 69 B +69 B (new file) 🆕
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 951 B
build/annotations/index.min.js 2.26 kB
build/api-fetch/index.min.js 2.31 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 579 B
build/block-directory/index.min.js 7.29 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 394 B
build/block-editor/default-editor-styles.css 394 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 149 B
build/block-library/blocks/audio/editor.css 151 B
build/block-library/blocks/audio/style-rtl.css 132 B
build/block-library/blocks/audio/style.css 132 B
build/block-library/blocks/audio/theme-rtl.css 134 B
build/block-library/blocks/audio/theme.css 134 B
build/block-library/blocks/avatar/editor-rtl.css 115 B
build/block-library/blocks/avatar/editor.css 115 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/button/editor-rtl.css 310 B
build/block-library/blocks/button/editor.css 310 B
build/block-library/blocks/button/style-rtl.css 538 B
build/block-library/blocks/button/style.css 538 B
build/block-library/blocks/buttons/editor-rtl.css 336 B
build/block-library/blocks/buttons/editor.css 336 B
build/block-library/blocks/buttons/style-rtl.css 328 B
build/block-library/blocks/buttons/style.css 328 B
build/block-library/blocks/calendar/style-rtl.css 240 B
build/block-library/blocks/calendar/style.css 240 B
build/block-library/blocks/categories/editor-rtl.css 132 B
build/block-library/blocks/categories/editor.css 131 B
build/block-library/blocks/categories/style-rtl.css 152 B
build/block-library/blocks/categories/style.css 152 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 122 B
build/block-library/blocks/code/theme.css 122 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 420 B
build/block-library/blocks/columns/style.css 420 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 124 B
build/block-library/blocks/comment-author-avatar/editor.css 124 B
build/block-library/blocks/comment-template/style-rtl.css 200 B
build/block-library/blocks/comment-template/style.css 199 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 221 B
build/block-library/blocks/comments-pagination/editor.css 211 B
build/block-library/blocks/comments-pagination/style-rtl.css 234 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 832 B
build/block-library/blocks/comments/editor.css 832 B
build/block-library/blocks/comments/style-rtl.css 632 B
build/block-library/blocks/comments/style.css 631 B
build/block-library/blocks/cover/editor-rtl.css 668 B
build/block-library/blocks/cover/editor.css 669 B
build/block-library/blocks/cover/style-rtl.css 1.62 kB
build/block-library/blocks/cover/style.css 1.6 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 314 B
build/block-library/blocks/embed/editor.css 314 B
build/block-library/blocks/embed/style-rtl.css 419 B
build/block-library/blocks/embed/style.css 419 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 326 B
build/block-library/blocks/file/style-rtl.css 278 B
build/block-library/blocks/file/style.css 279 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 198 B
build/block-library/blocks/footnotes/style.css 197 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 229 B
build/block-library/blocks/form-input/style-rtl.css 342 B
build/block-library/blocks/form-input/style.css 342 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 344 B
build/block-library/blocks/form-submission-notification/editor.css 341 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 470 B
build/block-library/blocks/freeform/editor-rtl.css 2.6 kB
build/block-library/blocks/freeform/editor.css 2.6 kB
build/block-library/blocks/gallery/editor-rtl.css 955 B
build/block-library/blocks/gallery/editor.css 958 B
build/block-library/blocks/gallery/style-rtl.css 1.71 kB
build/block-library/blocks/gallery/style.css 1.71 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 344 B
build/block-library/blocks/group/editor.css 344 B
build/block-library/blocks/group/style-rtl.css 103 B
build/block-library/blocks/group/style.css 103 B
build/block-library/blocks/group/theme-rtl.css 79 B
build/block-library/blocks/group/theme.css 79 B
build/block-library/blocks/heading/style-rtl.css 188 B
build/block-library/blocks/heading/style.css 188 B
build/block-library/blocks/html/editor-rtl.css 346 B
build/block-library/blocks/html/editor.css 347 B
build/block-library/blocks/image/editor-rtl.css 894 B
build/block-library/blocks/image/editor.css 892 B
build/block-library/blocks/image/style-rtl.css 1.59 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 1.65 kB
build/block-library/blocks/latest-comments/style-rtl.css 355 B
build/block-library/blocks/latest-comments/style.css 354 B
build/block-library/blocks/latest-posts/style-rtl.css 509 B
build/block-library/blocks/latest-posts/style.css 510 B
build/block-library/blocks/list/style-rtl.css 107 B
build/block-library/blocks/list/style.css 107 B
build/block-library/blocks/loginout/style-rtl.css 61 B
build/block-library/blocks/loginout/style.css 61 B
build/block-library/blocks/media-text/editor-rtl.css 304 B
build/block-library/blocks/media-text/editor.css 303 B
build/block-library/blocks/media-text/style-rtl.css 516 B
build/block-library/blocks/media-text/style.css 515 B
build/block-library/blocks/more/editor-rtl.css 427 B
build/block-library/blocks/more/editor.css 427 B
build/block-library/blocks/navigation-link/style-rtl.css 192 B
build/block-library/blocks/navigation-link/style.css 191 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 295 B
build/block-library/blocks/navigation-submenu/editor.css 294 B
build/block-library/blocks/navigation/style-rtl.css 2.25 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/navigation/view.min.js 1.03 kB
build/block-library/blocks/nextpage/editor-rtl.css 392 B
build/block-library/blocks/nextpage/editor.css 392 B
build/block-library/blocks/page-list/editor-rtl.css 378 B
build/block-library/blocks/page-list/editor.css 378 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 236 B
build/block-library/blocks/paragraph/editor.css 236 B
build/block-library/blocks/paragraph/style-rtl.css 341 B
build/block-library/blocks/paragraph/style.css 340 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 527 B
build/block-library/blocks/post-comments-form/style.css 528 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-content/style-rtl.css 79 B
build/block-library/blocks/post-content/style.css 79 B
build/block-library/blocks/post-date/style-rtl.css 62 B
build/block-library/blocks/post-date/style.css 62 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 155 B
build/block-library/blocks/post-excerpt/style.css 155 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 726 B
build/block-library/blocks/post-featured-image/style-rtl.css 341 B
build/block-library/blocks/post-featured-image/style.css 341 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 399 B
build/block-library/blocks/post-template/style.css 398 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 70 B
build/block-library/blocks/post-time-to-read/style.css 70 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 134 B
build/block-library/blocks/pullquote/editor.css 134 B
build/block-library/blocks/pullquote/style-rtl.css 342 B
build/block-library/blocks/pullquote/style.css 342 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 121 B
build/block-library/blocks/query-pagination-numbers/editor.css 118 B
build/block-library/blocks/query-pagination/editor-rtl.css 220 B
build/block-library/blocks/query-pagination/editor.css 208 B
build/block-library/blocks/query-pagination/style-rtl.css 287 B
build/block-library/blocks/query-pagination/style.css 283 B
build/block-library/blocks/query-title/style-rtl.css 64 B
build/block-library/blocks/query-title/style.css 64 B
build/block-library/blocks/query/editor-rtl.css 452 B
build/block-library/blocks/query/editor.css 451 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 238 B
build/block-library/blocks/quote/style.css 238 B
build/block-library/blocks/read-more/style-rtl.css 138 B
build/block-library/blocks/read-more/style.css 138 B
build/block-library/blocks/rss/editor-rtl.css 101 B
build/block-library/blocks/rss/editor.css 101 B
build/block-library/blocks/rss/style-rtl.css 288 B
build/block-library/blocks/rss/style.css 287 B
build/block-library/blocks/search/style-rtl.css 672 B
build/block-library/blocks/search/style.css 671 B
build/block-library/blocks/search/theme-rtl.css 113 B
build/block-library/blocks/search/theme.css 113 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 100 B
build/block-library/blocks/separator/editor.css 100 B
build/block-library/blocks/separator/style-rtl.css 248 B
build/block-library/blocks/separator/style.css 248 B
build/block-library/blocks/separator/theme-rtl.css 195 B
build/block-library/blocks/separator/theme.css 195 B
build/block-library/blocks/shortcode/editor-rtl.css 286 B
build/block-library/blocks/shortcode/editor.css 286 B
build/block-library/blocks/site-logo/editor-rtl.css 806 B
build/block-library/blocks/site-logo/editor.css 803 B
build/block-library/blocks/site-logo/style-rtl.css 218 B
build/block-library/blocks/site-logo/style.css 218 B
build/block-library/blocks/site-tagline/editor-rtl.css 87 B
build/block-library/blocks/site-tagline/editor.css 87 B
build/block-library/blocks/site-tagline/style-rtl.css 65 B
build/block-library/blocks/site-tagline/style.css 65 B
build/block-library/blocks/site-title/editor-rtl.css 123 B
build/block-library/blocks/site-title/editor.css 123 B
build/block-library/blocks/site-title/style-rtl.css 90 B
build/block-library/blocks/site-title/style.css 90 B
build/block-library/blocks/social-link/editor-rtl.css 338 B
build/block-library/blocks/social-link/editor.css 338 B
build/block-library/blocks/social-links/editor-rtl.css 676 B
build/block-library/blocks/social-links/editor.css 675 B
build/block-library/blocks/social-links/style-rtl.css 1.51 kB
build/block-library/blocks/social-links/style.css 1.5 kB
build/block-library/blocks/spacer/editor-rtl.css 346 B
build/block-library/blocks/spacer/editor.css 346 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table-of-contents/style-rtl.css 83 B
build/block-library/blocks/table-of-contents/style.css 83 B
build/block-library/blocks/table/editor-rtl.css 394 B
build/block-library/blocks/table/editor.css 394 B
build/block-library/blocks/table/style-rtl.css 640 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/style-rtl.css 266 B
build/block-library/blocks/tag-cloud/style.css 265 B
build/block-library/blocks/template-part/theme-rtl.css 113 B
build/block-library/blocks/template-part/theme.css 113 B
build/block-library/blocks/term-description/style-rtl.css 126 B
build/block-library/blocks/term-description/style.css 126 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 165 B
build/block-library/blocks/text-columns/style.css 165 B
build/block-library/blocks/verse/style-rtl.css 98 B
build/block-library/blocks/verse/style.css 98 B
build/block-library/blocks/video/editor-rtl.css 541 B
build/block-library/blocks/video/editor.css 542 B
build/block-library/blocks/video/style-rtl.css 192 B
build/block-library/blocks/video/style.css 192 B
build/block-library/blocks/video/theme-rtl.css 134 B
build/block-library/blocks/video/theme.css 134 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.1 kB
build/block-library/common.css 1.1 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 16.1 kB
build/commands/style-rtl.css 955 B
build/commands/style.css 952 B
build/compose/index.min.js 12.9 kB
build/core-data/index.min.js 73.1 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.35 kB
build/customize-widgets/style.css 1.35 kB
build/data-controls/index.min.js 641 B
build/data/index.min.js 8.98 kB
build/date/index.min.js 18 kB
build/deprecated/index.min.js 458 B
build/dom-ready/index.min.js 325 B
build/dom/index.min.js 4.65 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 580 B
build/edit-post/style-rtl.css 2.31 kB
build/edit-post/style.css 2.31 kB
build/edit-widgets/index.min.js 17.7 kB
build/edit-widgets/style-rtl.css 4.2 kB
build/edit-widgets/style.css 4.2 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/style-rtl.css 476 B
build/format-library/style.css 476 B
build/hooks/index.min.js 1.54 kB
build/html-entities/index.min.js 445 B
build/i18n/index.min.js 3.58 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.78 kB
build/interactivity/navigation.min.js 1.16 kB
build/interactivity/query.min.js 742 B
build/interactivity/search.min.js 615 B
build/is-shallow-equal/index.min.js 526 B
build/keyboard-shortcuts/index.min.js 1.31 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.16 kB
build/list-reusable-blocks/style-rtl.css 846 B
build/list-reusable-blocks/style.css 846 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.3 kB
build/notices/index.min.js 946 B
build/nux/index.min.js 1.59 kB
build/nux/style-rtl.css 749 B
build/nux/style.css 745 B
build/patterns/style-rtl.css 687 B
build/patterns/style.css 685 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.9 kB
build/preferences/style-rtl.css 554 B
build/preferences/style.css 554 B
build/primitives/index.min.js 829 B
build/priority-queue/index.min.js 1.54 kB
build/private-apis/index.min.js 1.01 kB
build/react-i18n/index.min.js 630 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.76 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.1 kB
build/router/index.min.js 1.96 kB
build/server-side-render/index.min.js 1.94 kB
build/shortcode/index.min.js 1.4 kB
build/token-list/index.min.js 581 B
build/url/index.min.js 3.85 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react-jsx-runtime.min.js 560 B
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 965 B
build/warning/index.min.js 250 B
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@kevin940726
Copy link
Member Author

In recent commits, you can now test the new image cropper in the Image block. Enable the gutenberg experiment "Redesigned image cropper" under "Gutenberg" -> "Experiments" -> "Redesigned image cropper".

image

After enabling the experiment, this redesigned cropper will be the default cropper of the image block. Insert an image block and test it in the editor.

Kapture.2024-08-16.at.15.34.13.mp4

I hope this makes testing this PR easier for designers and contributors. Needless to mention, there are still lots of improvements, and the state is not meant to be the final design. We'll add more features and fix bugs as we continue to develop the feature. Thanks for testing! 🙇

@jasmussen
Copy link
Contributor

Thanks for working on this. This already feels vastly better than what exists. Nice work.

I did encounter a glitch, I was using a portrait image, and resized it first, in doing this, toggling cropping on/off resulted in differing aspect ratios:
cropping

One other aspect, when the images get very large, scrollbars get added. This is visible in your screenshots as well. Maybe this is fine? But it's worth testing this also on mobile, where I would worry that panning might pan the viewport rather than the image you're moving inside. Or worse yet, a bit of both which might get you in trouble. If we need to, can we simply crop off the edges outside your image frame? Right now they visually appear blurred, which is fancy, but in case it causes issues, simply not showing this might be fine.

Separately, it might be time to make progress on toolbar improvements. At present, it looks like this:

Image Block Toolbar, cropping before

Notably Link and Crop buttons disappear from the toolbar, when you're cropping. This is reasonable, but also a bit random, since text overlay remains. Cropping is effectively a mode of the block toolbar, so we might as well lean into that. Could we do this?

Image Block Toolbar, proposed cropping

Doing this would also better fit the zoom/rotate/aspect ratio tools which are currently missing in this implementation. Like so:

Image Block Toolbar, proposed cropping

@talldan
Copy link
Contributor

talldan commented Aug 19, 2024

This works nicely so far, really great work here.

There's a few little things I noticed from testing (you're probably aware some of them):

  • When engaging crop mode, there's an animation of some of the elements that doesn't look right:
Kapture.2024-08-19.at.15.20.33.mp4
  • When resizing I can see a couple of guide lines (one horizontal, one vertical), but they seem off-center and don't follow the rule of thirds system that most cropping tools use.
Kapture.2024-08-19.at.15.23.44.mp4
  • I also think it might be a good idea to show the guide lines whenever crop mode is active, or maybe show them when hovering the image while crop mode is active.

  • Also visible in the video above, the image shakes when dragging the handles a very tiny amount

  • The sibling inserters can get in the way of the drag handles. Not sure if there's a way to turn them off while cropping.

  • If you try cropping again while a previous crop operation is saving, the image can become stretched:

Kapture.2024-08-19.at.15.41.35.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Component System WordPress component system [Feature] Media Anything that impacts the experience of managing media [Type] Experimental Experimental feature or API.
Projects
Status: Next
Development

Successfully merging this pull request may close these issues.

6 participants