Per-field aspect ratio and per-usage crop for image fields #2448
Replies: 1 comment 4 replies
|
This sounds good. For the open questions:
Now for "where the ratio is stored", that's where I would like to dive deeper. In the current proposal, admins must create fields for each usage that requires a different aspect ratio / crop. I am imagining collections with 5+ image fields that editors have to fill in. Not only is it annoying but it can also be a data integrity issue where editors (accidentally or intentionally) select different images for those usage-based fields, when the admin intended them to be the same image just with a customized crop. The other thing I would mention, which could be out-of-scope, is a minimum size for the crop so editors don't end up cropping it in a way that makes it blurry. That might also constrain the image selection itself if it can't satisfy all the usages. Otherwise I think this a good addition. Thank you! |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Splitting this out of #990 as @MA2153 suggested there, and picking up @rob-j-oliver's point that a focal point wants to be "per usage".
Problem
The same photo gets used in slots with different shapes — a wide banner, a 4:3 slide, a tall card. One focal point stored on the media item cannot serve all three: the point that keeps a subject centred in a 7:4 banner is not the one that keeps it centred in a 2:3 card. #990 §4 proposes a normalized
{ x, y }on the media item, which is the right primitive but resolves to one answer per image rather than one per place it appears.There is also nothing telling an editor what shape a slot expects, or why. A portrait photo dropped into a banner field is accepted happily, and the page either letterboxes it or crops it somewhere unfortunate. The first anyone knows is when they look at the published page.
Proposal
1. One field, named crops. A crop is a framing of one image, not a separate image, so the field declares the usages rather than the schema growing a field per usage. These are not constraints on a value, so they sit in
optionsbeside the other widget configuration rather than invalidation:The slug is the stable identifier templates ask for. The label and description are only ever shown to editors, and the description is what stops someone centring a face exactly where the title will land.
2. One selection, one dialog. The editor picks a single image and adjusts each named crop against that same picture — a preview per usage. Where a field declares no crops, behaviour is unchanged.
3. The crop is stored as fractions of the source. All four numbers are in the range 0–1:
x,yare the top-left corner of the crop rectangle,w,hits size. The region in pixels is(x·W, y·H, w·W, h·H)for a source ofW × H:{ "id": "01J5...", "crops": { "banner": { "x": 0.12, "y": 0.08, "w": 0.76, "h": 0.62 }, "card": { "x": 0.55, "y": 0.10, "w": 0.40, "h": 0.90 } } }Fractions rather than pixels so a crop survives its source being replaced by a different resolution of the same image. The ratio is not stored, because the definition fixes it: the editor can move and scale the frame, never reshape it. A stored value whose implied ratio no longer matches its definition is how a changed definition is detected — the focal point covers until someone re-crops.
Any crop the editor has not adjusted falls back to the media-level focal point from #990.
4. Templates ask by name.
Applied at render time — no derivative is stored. On Cloudflare that means the
IMAGESbinding'sfit/gravity; #2228 was a prerequisite, since the endpoint droppedfitentirely and cover-crops silently did not happen on that platform.Per-field ratios still make sense where the images genuinely differ: a portrait headshot beside a landscape hero are two fields because they are two photos, not two framings of one. The two ideas compose.
5. A minimum crop size, stored with the ratio.
minWidthis the smallest useful crop width in source pixels — in practice the largest width a template ever renders that crop at, below which the renderer is upscaling. Height needs no storing; the ratio implies it. One number drives both checks:minWidthcannot satisfy it however it is framed, so the picker says so before the editor invests any effort.minWidthfor that usage.Current state, for anyone picking this up
There is no cropper in the admin today. The
aspectRatiothat appears in the bundle belongs to the rich-text image block's width/height lock, andcropappears only as an icon name, so this is a new surface rather than an extension of an existing one.Open: does a crop value belong to the field or the media item?
A maintainer call, since it changes the storage shape.
On the field value — the same photo can be framed differently in two entries. Maximum control, and the editor re-crops every time they reuse an image.
On the media item — one crop per template per image, reused everywhere that image appears. Far less repetitive, and an image's banner framing is decided once. The cost is that two entries cannot frame the same photo differently, which may well be a feature.
The media item is the more natural home to my eye — how a photo should be framed as a banner is usually a property of the photo rather than of the page, and #990's focal point already lives there, so fallback and override would sit together.
Why bother
Aspect ratio is the one image property a CMS can enforce that an editor cannot reason about from a file picker. Format and size are fixable after the fact by a delivery pipeline (#1547); a badly framed crop is not, because the information about what mattered in the frame is gone.
All reactions