-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Image Block: Adding image resizing handles #2213
Conversation
257b482
to
8a20ead
Compare
Holy guacamole you're so fast it's hard to keep up! This works really really well. I can't decide whether we should change the block behavior when the image has no alignment. But it does bring some challenges with it, when it comes to floats and centering: It seems right now we hard-code a width when we float. Can we undo that? I have a bad feeling we might need to revisit the full-wide hack we've been using, or at least rethink how images float in such a world. Which is on me, but let's see what we can do with the floated block width for now... Thanks Riad! |
8a20ead
to
efe35da
Compare
@jasmussen Fixed the demo content bug but for the All the help here would be appreciated (I don't have all the context about this hack) and maybe we could still ship this and resolve the left/right fixed width in another PR by changing the hack. |
.eslintrc.json
Outdated
@@ -24,7 +24,8 @@ | |||
"wp": true, | |||
"wpApiSettings": true, | |||
"window": true, | |||
"document": true | |||
"document": true, | |||
"Image": true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See also: #1008
It was intentional to remove all globals and encourage to access through window
, i.e. window.Image
. Could be easy to think one had assigned a local Image
variable but in fact it's referencing the global (as in the case of event
bug of #1007). I guess same could be said of document
(window.document
), but... ¯\_(ツ)_/¯
blocks/library/image/image-size.js
Outdated
this.image.onload = () => { | ||
const maxWidth = this.container.clientWidth; | ||
const ratio = this.image.height / this.image.width; | ||
const width = this.image.width < maxWidth ? this.image.width : maxWidth; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Math.min
could come in handy here:
const width = Math.min( maxWidth, this.image.width );
blocks/library/image/image-size.js
Outdated
const maxWidth = this.container.clientWidth; | ||
const ratio = this.image.height / this.image.width; | ||
const width = this.image.width < maxWidth ? this.image.width : maxWidth; | ||
const height = this.image.width < maxWidth ? this.image.height : maxWidth * ratio; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note about Math.min
, but also: Is maxWidth
the correct value to test against? Or should maxHeight
be a separate variable maxHeight = maxWidth * ratio
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maxWidth
is the correct value, we adapt the height only if the image don't fit in the container's width.
blocks/library/image/image-size.js
Outdated
const ratio = this.image.height / this.image.width; | ||
const width = this.image.width < maxWidth ? this.image.width : maxWidth; | ||
const height = this.image.width < maxWidth ? this.image.height : maxWidth * ratio; | ||
this.setState( { width, height } ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the component has unmounted by this point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a componentWillUnmount
call.
Edit: I have a typo there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, missed that. Is changing the src
while the request is in flight enough to prevent onload
from being called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And setting the src
to a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blocks/library/image/index.js
Outdated
lockAspectRatio | ||
onResize={ ( event, { size } ) => setAttributes( size ) } | ||
> | ||
<img src={ url } alt={ alt } onClick={ setFocus } /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: We could create a single reference to this element to share between condition above and here:
diff --git a/blocks/library/image/index.js b/blocks/library/image/index.js
index f6985bc8..766fb8aa 100644
--- a/blocks/library/image/index.js
+++ b/blocks/library/image/index.js
@@ -178,8 +178,9 @@ registerBlockType( 'core/image', {
<figure key="image" className={ classes }>
<ImageSize src={ url }>
{ ( originalWidth = width, originalHeight = height ) => {
+ const img = <img src={ url } alt={ alt } onClick={ setFocus } />;
if ( ! originalHeight || ! originalWidth ) {
- return <img src={ url } alt={ alt } onClick={ setFocus } />;
+ return img;
}
return (
<ResizableBox
@@ -188,7 +189,7 @@ registerBlockType( 'core/image', {
lockAspectRatio
onResize={ ( event, { size } ) => setAttributes( size ) }
>
- <img src={ url } alt={ alt } onClick={ setFocus } />
+ { img }
</ResizableBox>
);
} }
@jasmussen also maybe "wide" and "full-width" could clear the resized values. |
Disabled the resizing for wide/full alignments but there're still some glitches for the left/right alignments. |
Not sure I understand @mtias's fix but I found that always applying "data-resized" to the wrapper makes the component behave like I wanted. |
@youknowriad if the image is not resized we'd want the 370px max-width to apply when floated. |
@mtias I'm not sure this is true, floating means "only floating" for me and frontend styling doesn't include this max-width. |
Yes, it hasn't been applied to front-end, and we may want to revise that, but that was the intention of having the max-width, because if the image is larger than the text column, it doesn't look floated at all. |
@mtias What about setting the |
Let's try it. |
Ok updated, It works well IMO but there's one caveat: I had to add a 'resized' attribute to the image to differentiate between explicitely resized image and a size set automatically when applying float alignments. This boolean is used when moving to "center" alignment: if we explicitly resized the image, we keep the size unless we reset it. |
cabd5d5
to
d247219
Compare
There's some small remaining issue where we set a right value in the width/height attributes but the component is not rerendered accordingly unless we refresh. |
There are a couple of issues still. But if we believe these are issues we can address, then it's worth getting this in as a first pass, and then iterating. If, on the other hand, any of these sound like we can't address them easily, might be worth rethinking.
2 and 4 seem like they can be fixed both, by applying mininum and maximum dimensions. |
Codecov Report
@@ Coverage Diff @@
## master #2213 +/- ##
==========================================
- Coverage 25.35% 25.28% -0.07%
==========================================
Files 151 152 +1
Lines 4701 4797 +96
Branches 792 816 +24
==========================================
+ Hits 1192 1213 +21
- Misses 2967 3026 +59
- Partials 542 558 +16
Continue to review full report at Codecov.
|
d247219
to
2eda5e7
Compare
@jasmussen Updated with another approach that seems simpler and more robust. Mind taking a look? |
2eda5e7
to
0a3dac3
Compare
Per slack discussion: I set the minimum width/height to 20px and the max-width to the image width. |
Thank you for working on this. I'd love for the minimum dimensions to be 10px rather than 20px. But more importantly than those dimensions, I think, is that the handle detaches if you scale it smaller than what appears to be 20px height, and when you then scale up again, the handle sits in the air: Scaling up works 200% better now! It's almost perfect. But we may need scaling more scaling handles, or we're stuck when you make the image too big: It'd be nice (though not necessary for this PR) that the handles are hidden until you select the block. For reference, here's what TinyMCE does: Note how if you scale larger than the viewport, the sizing is discarded. |
TinyMCE limits scaling to the editor width and not the browser viewport. So, this seems more logic to me. For us, this might mean limit the scaling to the editor's content area size (which is 700px IIRC) but again, this means the user can't scale more than this even if it's theme allows it. Also, the difference with TinyMCE is that Tinymce's size is flexible (it grows if you resize the window) which is not the case for our editor's content area. I'm looking at the issues above |
0a3dac3
to
3e0d3e7
Compare
This is fixed
This is fixed
This can't be done with the current resizing library I'm using :(. Two options: find another library or write our own. The second one could be difficult to do. I'm looking at alternatives. |
To be clear, it's fine to improvements in this area in separate non-milestoned PRs.
Bummer. Hmm. Can we choose which corner the handle sits on? The big problem right now is that it's very easy to scale the image so large that the handle comes out of view, and then you can't scale it down. Perhaps we do need to limit the size to the editor width, so as to prevent this from happening. Not saying it has to be perfect, looking for quick fixes here. |
@jasmussen Found a better library, let me know what do you think? |
🎉🎉🎉🎉 Oh my science this latest one is AMAZING! It feels completely solid! I think this can go in virtually as is! A future improvement could be to improve this: and this: That is it'd be nice if the caption field was no larger than the image itself, and when the image is selected it seems like we might want to remove the 370px altogether on floats (which lets us remove the !important that Matías added). The thing is, the max size on floated images is something we added because we didn't have a good resizing/insert thumbnail play. Now that we have good resizing, I don't think we need it. |
Do you mean we should resize the whole "figure" node (image + caption) instead of resizing the image (current behaviour)? What do you suggest to fix those? |
I'm not sure what the best way to improve this is. The idea would be that the caption field is no wider than the image. But let's explore this separately, and it doesn't have to be in the milestones. |
I think this is fine. If themes were to modify this, it would no longer be 700px in the editor. |
… the alignment change
… of the inserted image
dd646b7
to
06b88c3
Compare
Not sure I understand, do you think this is ok to ship or is there anything else I should look at? |
I meant not going beyond the width set on blocks that don't have wide/full alignment. |
👍 Understood and updated to constrain the resizing within the canvas. The value is hard-coded right now but we could easily make it overridable later. |
Love it, I think it's good to go! We do definitely want ro revisit the max dimensions, but let's do that as part of a larger editor width discussion. I know there's a ticket for this separetely too. As it stands, this PR feels solid 👌 |
closes #600
Implementation notes
ImageSize
component)Testing instructions
Questions
Should we resize the container (image + caption) or just the image?