-
Notifications
You must be signed in to change notification settings - Fork 65
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
feat: add aspect ratio support by calculating client-side #201
Conversation
* master: (29 commits) chore(deps): update dependency puppeteer to v1.9.0 (#200) chore(deps): update dependency sinon to v6.3.5 (#199) chore(deps): update dependency jest-extended to v0.11.0 (#198) chore(deps): update dependency sinon to v6 (#197) chore(deps): update dependency karma to v3 (#196) chore(deps): update dependency babel-eslint to v10 (#193) chore(deps): update jest monorepo to v23.6.0 (#191) chore(deps): update dependency webpack-cli to v3.1.2 (#190) chore(deps): update dependency webpack to v4.20.2 (#189) chore(deps): update dependency standard-version to v4.4.0 (#188) chore(deps): update dependency puppeteer to v1.8.0 (#187) chore(deps): update dependency jest-extended to v0.10.0 (#178) chore(deps): update dependency webpack-dev-server to v3.1.9 (#186) chore(deps): update dependency karma-webpack to v3.0.5 (#184) chore(deps): update dependency cross-env to v5.2.0 (#175) chore(deps): update dependency prettier to v1.14.3 (#182) chore(renovate): update automerge config (#185) chore(renovate): enable auto-merging (#183) chore(deps): update dependency babel-preset-env to v1.7.0 (#174) chore(travis): only run travis branch builds on master (#179) ...
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.
Left some questions & comments 🙂
src/react-imgix.js
Outdated
|
||
const [width, height] = aspectRatio.split(":"); | ||
|
||
return 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.
Don't want to be nitpicky, but this feels a bit obscure. 💭
Is there a reason for not using something like parseFloat
explicitly?
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.
Are you saying this should be return parseFloat(width) / parseFloat(height)
? I'm not quite understanding this comment
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.
I think he's saying that relying on the implicit type conversion here feels a bit cloudy, and I agree. I'd rather see the parseFloat()
calls in there, as you've stated.
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.
That is exactly what I trying to say!
Sorry, ironically I phrased it weirdly as well.
src/react-imgix.js
Outdated
return false; | ||
} | ||
const isValidFormat = str => !/^\d(\.\d+)?:\d(\.\d+)?$/.test(str); | ||
if (isValidFormat(aspectRatio)) { |
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.
Does isValidFormat
meant to be renamed to isInvalidFormat
?
That !
in front of regex is a bit hard to notice, it looks like it is a part of the regex.
Alternatively, I'm in favor of moving !
to condition, something like:
if (!isValidFormat(aspectRatio)) { ...
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.
Good catch 🙌
src/react-imgix.js
Outdated
* Parse an aspect ratio in the format w:h to a decimal. If false is returned, the aspect ratio is in the wrong format. | ||
*/ | ||
function parseAspectRatio(aspectRatio) { | ||
if (typeof aspectRatio == null) { |
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.
This is potentially redundant.
It would be sufficient to make sure that aspectRatio
is a string.
So check below would be sufficient on its own.
src/react-imgix.js
Outdated
...srcOptions, | ||
width: targetWidth | ||
}); | ||
}; | ||
const aspectRatioDecimal = aspectRatio && parseAspectRatio(aspectRatio); |
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.
Following on comments on type checks in parseAspectRatio
;
It seems to be sufficient to just pass aspectRatio
into parseAspectRatio
and throw warning if false
was returned.
}); | ||
}; | ||
const aspectRatioDecimal = aspectRatio && parseAspectRatio(aspectRatio); | ||
if (aspectRatio != null && aspectRatioDecimal === false) { |
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 above.
If all type checks just happen inside parseAspectRatio
, aspectRatio != null
can be removed.
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.
The reason for having aspectRatio != null
here is so that a warning is only thrown when the user has tried to pass something. e.g. it wouldn't throw a warning when no prop is passed, but it would when the user passes "". Do you think it's still valid? @maxkolyanov
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.
Good call! Totally makes sense to check if the prop is there, before showing a warning.
One question I guess is wouldn't it be equal to undefined
then instead of null
, if the prop is absent/not passed?
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.
Definitely! This is the reason for using !=
rather than !==
, as this covers both undefined
and null
.
i.e.
undefined != null // false -- this is what we want
undefined !== null // true -- this would break the conditional check
Does this make sense?
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.
Totally! Great work on PR, LGTM 👍
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.
Thanks @maxkolyanov! 🙌 thanks again for your work for the base for this PR.
src/react-imgix.js
Outdated
@@ -38,6 +38,7 @@ const COMMON_PROP_TYPES = { | |||
|
|||
const SHARED_IMGIX_AND_SOURCE_PROP_TYPES = { | |||
...COMMON_PROP_TYPES, | |||
aspectRatio: PropTypes.number, |
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.
It seems like aspectRatio
is a string
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.
This was fixed in a commit I didn't push 😬
src/react-imgix.js
Outdated
if (typeof aspectRatio !== "string") { | ||
return false; | ||
} | ||
const isValidFormat = str => /^\d(\.\d+)?:\d(\.\d+)?$/.test(str); |
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.
This doesn't allow inputs with more than one digit left of the decimal point, right? Should be /^\d+(\.\d+)?:\d+(\.\d+)?$/
, I think.
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.
Good catch!
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.
Can we also update the unit tests to make sure this is covered?
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.
Yep, all done!
src/react-imgix.js
Outdated
|
||
const [width, height] = aspectRatio.split(":"); | ||
|
||
return 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.
I think he's saying that relying on the implicit type conversion here feels a bit cloudy, and I agree. I'd rather see the parseFloat()
calls in there, as you've stated.
src/react-imgix.js
Outdated
aspectRatioDecimal && | ||
aspectRatioDecimal > 0 | ||
) { | ||
urlParams.height = Math.round(targetWidth / aspectRatioDecimal); |
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.
After discussing this with some other engineers internally, this should be Math.ceil()
to match the behavior in our backend when rounding dimensions.
@maxkolyanov @jayeb I think I've covered everything that was brought up. Can I please get another quick review? |
Description
This PR allows the developer to specify a desired aspect ratio (AR) when creating an image.
This PR is based off the awesome work from @maxkolyanov!
This fixes #161
API
The developer specifies the AR along with normal imgix params, such as
fit
.e.g.
The AR has to be specified in the form
number:number
. When an invalid AR is detected, no height values will be generated, and a warning is thrown.TODO
h
up to comply with API specNew Feature
feat(<area>): added new way to do this cool thing #issue-number
Steps to Test
Review changes to unit tests.