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
Dynamic page scaling in amp-story #12901
Conversation
272bdb6
to
c52e40b
Compare
* @return {boolean} | ||
*/ | ||
function isScalingEnabled(page) { | ||
return page.getAttribute('scaling') != 'disabled'; |
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.
Not super convinced about this API 🤷
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 this is okay, at least for now. Thinking about it more, we definitely want to try it as opt-out behind an experiment first, so that we don't need publishers to republish stories in order to evaluate the feature.
That said, maybe we should brainstorm the explicit values we expect? This is logically kind of similar to object-fit
, so maybe we can steal their API?
- No scaling can be
scaling="none"
- This implementation is like
scaling="contain"
(or, at least for now, omitting the attribute altogether) - We can add other modes later if we choose to
- Maybe we should name it accordingly?
content-fit
?
Not really sure about any of the details here, but I think we should check that the attribute is some concrete value instead of checking that it's not disabled.
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.
Actually, maybe we can do both opt-in and opt-out? Assuming the attribute names from above (though I'm not particularly set on those names), we can do:
Experiment OFF | Experiment ON | |
---|---|---|
(no attribute) | scaling disabled | scaling enabled |
scaling="none" |
scaling disabled | scaling disabled |
scaling="contain" |
scaling enabled | scaling enabled |
In other words, explicitly setting a value is always respected, but the default (no attribute) case is controlled by the experiment. This will allow us to meet two goals:
- Test the feature on ALL existing stories, without having to change their markup
- Allow publishers to publish new stories making use of the feature, by explicitly opting in on a story-by-story basis
WDYT? Is this feasible? Can we move the experiment check to isScalingEnabled
?
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.
For your pending items:
- I think validation can come in a separate PR? As long as the experiment is in place, the opt out API doesn't need to be valid.
- SGTM to use
scale
wherezoom
is unsupported. Can we actually check feature support instead of checking user agent? Or does Firefox claim they supportzoom
but actually not support our use case? - I think we will soon-ish be adding layers that are not full container size. All layers are currently full container size, though. I'll leave it up to you whether you want to tackle that in this PR or separately.
max-height: 75vh !important; | ||
max-width: calc(3/5 * 75vh) !important; | ||
min-width: 320px !important; | ||
min-height: 533px !important; | ||
} | ||
|
||
[desktop] > amp-story-page, | ||
[desktop] .i-amphtml-story-page-sentinel { | ||
left: 50%!important; |
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.
nit: space before !important
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.
Reverted CSS changes.
* @return {boolean} | ||
*/ | ||
function isScalingEnabled(page) { | ||
return page.getAttribute('scaling') != 'disabled'; |
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 this is okay, at least for now. Thinking about it more, we definitely want to try it as opt-out behind an experiment first, so that we don't need publishers to republish stories in order to evaluate the feature.
That said, maybe we should brainstorm the explicit values we expect? This is logically kind of similar to object-fit
, so maybe we can steal their API?
- No scaling can be
scaling="none"
- This implementation is like
scaling="contain"
(or, at least for now, omitting the attribute altogether) - We can add other modes later if we choose to
- Maybe we should name it accordingly?
content-fit
?
Not really sure about any of the details here, but I think we should check that the attribute is some concrete value instead of checking that it's not disabled.
|
||
|
||
/** @private @const {number} */ | ||
const MIN_LAYER_WIDTH_PX = 380; |
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.
How did we pick these min/max values? Is there a way to keep these in sync with the actual min/max widths that we allow in our UIs? e.g. I think the mobile UI can go larger than 520 before it hits the desktop breakpoint, and I think it can go smaller than 380 as well.
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.
Ignore this; I got it backwards. I thought we were scaling within the range min...max, but we're scaling outside the range min...max.
const style = { | ||
'width': px(width), | ||
'height': px(height), | ||
'zoom': `${factor * 100}%`, |
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.
FWIW, I think you can use decimal zooms (e.g. 0.9) instead of percentage (e.g. 90%), so you may just be able to use factor
directly.
@newmuis PTAL I'm not exactly sure about the scaling enabled API. I used |
updateRootProps() { | ||
const {width, height, factor} = this.targetDimensions_; | ||
this.vsync_.mutate(() => { | ||
this.rootEl_.style.setProperty('--i-amphtml-story-width', px(width)); |
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.
Is the goal that this is user-overridable? I think the fact that it's --i-amphtml-*
will make the doc invalid if people try to override this.
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's not user-overridable. The purpose of using CSS vars is to prevent the layers from being updated on resize, since they reference a css var that is defined at the story element level
Thanks @alanorozco! |
Scales pages so that they are sized within a pixel range, but rendered at the correct visual dimensions.
Guarded by
amp-story-scaling
experiment flag.Can be turned on at the page level:
<amp-story-page scaling="relative">
.Implementation
Uses a sentinel sizer element.Uses active page for sizing.amp-story-grid-layer
descendants.zoom
orscale
.Pending
UseDone.scale
on Firefox, as it has no support forzoom
.Calculate relative layer size (currently assumes full container size).Done.