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

Dynamic page scaling in amp-story #12901

Merged
merged 16 commits into from Jan 30, 2018
Merged

Conversation

alanorozco
Copy link
Member

@alanorozco alanorozco commented Jan 18, 2018

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.
  • Keeps target dimensions at the story level.
  • Updates dimensions on viewport resize.
  • Applies scaling to direct amp-story-grid-layer descendants.
  • Backed by zoom or scale.
  • Uses CSS vars when possible so layers don't need to be updated on resize.
  • Lazily applied. Will not update dimensions for elements until they come in view.

Pending

  • Validation rules for opt-out. (Coming in separate PR).
  • Use scale on Firefox, as it has no support for zoom. Done.
  • Calculate relative layer size (currently assumes full container size). Done.

@alanorozco alanorozco force-pushed the scaling branch 3 times, most recently from 272bdb6 to c52e40b Compare January 18, 2018 22:50
@alanorozco alanorozco changed the title Work in progress: Implement amp-story dynamic page scaling Dynamic page scaling in amp-story Jan 18, 2018
* @return {boolean}
*/
function isScalingEnabled(page) {
return page.getAttribute('scaling') != 'disabled';
Copy link
Member Author

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 🤷

Copy link
Contributor

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.

Copy link
Contributor

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:

  1. Test the feature on ALL existing stories, without having to change their markup
  2. 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?

Copy link
Contributor

@newmuis newmuis left a 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 where zoom is unsupported. Can we actually check feature support instead of checking user agent? Or does Firefox claim they support zoom 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;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space before !important

Copy link
Member Author

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';
Copy link
Contributor

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;
Copy link
Contributor

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.

Copy link
Contributor

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}%`,
Copy link
Contributor

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.

@alanorozco
Copy link
Member Author

@newmuis PTAL

I'm not exactly sure about the scaling enabled API. I used outside-range since it seems accurate, but I also find it a little bit confusing.

updateRootProps() {
const {width, height, factor} = this.targetDimensions_;
this.vsync_.mutate(() => {
this.rootEl_.style.setProperty('--i-amphtml-story-width', px(width));
Copy link
Contributor

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.

Copy link
Member Author

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

@alanorozco alanorozco merged commit e4d34fc into ampproject:master Jan 30, 2018
@alanorozco alanorozco deleted the scaling branch January 30, 2018 00:27
@newmuis
Copy link
Contributor

newmuis commented Jan 30, 2018

Thanks @alanorozco!

gzgogo pushed a commit to gzgogo/amphtml that referenced this pull request Feb 14, 2018
gzgogo pushed a commit to gzgogo/amphtml that referenced this pull request Feb 14, 2018
gzgogo pushed a commit to gzgogo/amphtml that referenced this pull request Feb 14, 2018
RanAbram pushed a commit to RanAbram/amphtml that referenced this pull request Mar 12, 2018
protonate pushed a commit to protonate/amphtml that referenced this pull request Mar 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants