Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 41 additions & 14 deletions extensions/amp-story/1.0/background-blur.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {whenUpgradedToCustomElement} from '../../../src/amp-element-helpers';
const CANVAS_SIZE = 3;

/** @const {number} */
const DURATION_MS = 200;
const DURATION_MS = 400;

/** @const {string} */
const CLASS_NAME = 'BACKGROUND-BLUR';
Expand All @@ -44,6 +44,10 @@ export class BackgroundBlur {
/** @private @const {!Element} */
this.canvas_ = null;

/** @private @const {Element} */
this.offscreenCanvas_ = this.win_.document.createElement('canvas');
this.offscreenCanvas_.width = this.offscreenCanvas_.height = CANVAS_SIZE;

/** @private {?number} */
this.currentRAF_ = null;

Expand Down Expand Up @@ -106,19 +110,10 @@ export class BackgroundBlur {
* @param {?Element} fillElement
*/
animate_(fillElement) {
const context = this.canvas_.getContext('2d');

const draw = (easing) => {
context.globalAlpha = easing;
context.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
if (fillElement) {
context.drawImage(fillElement, 0, 0, CANVAS_SIZE, CANVAS_SIZE);
}
};

this.drawOffscreenCanvas_(fillElement);
// Do not animate on first load.
if (this.firstLoad_) {
draw(1 /** easing **/);
this.drawCanvas_(1 /** easing **/);
this.firstLoad_ = false;
return;
}
Expand All @@ -131,8 +126,8 @@ export class BackgroundBlur {
}
const elapsed = currTime - startTime;
if (elapsed < DURATION_MS) {
const easing = 1 - Math.pow(1 - elapsed / DURATION_MS, 2);
draw(easing);
const easing = elapsed / DURATION_MS;
this.drawCanvas_(easing);
this.currentRAF_ = requestAnimationFrame(nextFrame);
}
};
Expand All @@ -141,6 +136,38 @@ export class BackgroundBlur {
this.currentRAF_ = requestAnimationFrame(nextFrame);
}

/**
* Draws to the canvas with opacity.
* @private
* @param {number} alphaPercentage
*/
drawCanvas_(alphaPercentage) {
const context = this.canvas_.getContext('2d');
context.globalAlpha = alphaPercentage;
context.drawImage(this.offscreenCanvas_, 0, 0, CANVAS_SIZE, CANVAS_SIZE);
}

/**
* Composes the image offscreen at 100% opacity, then uses it for fading in.
* If these draw calls are done with opacity, a flash would be visible.
* This is due to the black fill being a high contrast compared to the image.
* The black fill is always needed in case the image is a transparent png.
* @private
* @param {?Element} fillElement
*/
drawOffscreenCanvas_(fillElement) {
const context = this.offscreenCanvas_.getContext('2d');
// A black background in drawn first in case the image is a transparent PNG.
context.fillStyle = 'black';
context.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
if (fillElement) {
context.drawImage(fillElement, 0, 0, CANVAS_SIZE, CANVAS_SIZE);
// For background protection.
context.fillStyle = 'rgba(0, 0, 0, .3)';
context.fillRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);
}
}

/**
* Get active page's biggest amp-img element.
* @private
Expand Down