Skip to content

Commit

Permalink
✨Adds smoothing to amp-orientation-observer (#24606)
Browse files Browse the repository at this point in the history
* Added smoothing to amp-orientation-observer

* Added smoothing to the examples

* Type check fixes

* Fixed a test

* Requested change to the validator rule
  • Loading branch information
wassgha committed Sep 30, 2019
1 parent 37af858 commit c543dd9
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 73 deletions.
4 changes: 2 additions & 2 deletions examples/amp-orientation-observer-3d-parallax.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@
</amp-animation>
<amp-orientation-observer
on="beta:stars.seekTo(percent=event.percent);gamma:stars.seekTo(percent=event.percent);"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<amp-orientation-observer
on="beta:text.seekTo(percent=event.percent);gamma:text.seekTo(percent=event.percent);"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>

<div class="spacer"></div>
Expand Down
2 changes: 1 addition & 1 deletion examples/amp-orientation-observer-amp-3d-gltf.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@

<main>
<div>
<amp-orientation-observer on="gamma:model.setModelRotation(y=event.percent);" intersection-ratios="1" layout="nodisplay">
<amp-orientation-observer on="gamma:model.setModelRotation(y=event.percent);" intersection-ratios="1" layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<amp-3d-gltf id="model" layout="fixed" width="320" height="240" alpha="true" antialiasing="true" autoRotate="false" enableZoom="true" src="https://webgears-3d.github.io/3d-gltf-static/m/DamagedHelmet.glb"></amp-3d-gltf>
</div>
Expand Down
2 changes: 1 addition & 1 deletion examples/amp-orientation-observer-panorama.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<amp-orientation-observer
gamma-range="-90 90"
on="gamma:gammaAnim.seekTo(percent=event.percent)"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<div class="panorama">
<amp-img alt="A view of the mountains"
Expand Down
2 changes: 1 addition & 1 deletion examples/amp-orientation-observer-scroll.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<amp-orientation-observer
beta-range="0 180"
on="beta:clockAnim1.seekTo(percent=event.percent)"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
</div>
<div id="ipsum">
Expand Down
6 changes: 3 additions & 3 deletions examples/amp-orientation-observer.amp.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ <h3>Rotate phone along y axis</h3>
<amp-orientation-observer
beta-range="0 180"
on="beta:clockAnim1.seekTo(percent=event.percent)"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<amp-img layout="responsive" width=2 height=1.5 src="./img/clock.jpg">
<div class="clock-hand rotate-1"></div>
Expand All @@ -134,7 +134,7 @@ <h3>Rotate phone along x axis</h3>
<div id="clock-scene-1" class="clock-scene">
<amp-orientation-observer
on="gamma:clockAnim2.seekTo(percent=event.percent)"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<amp-img layout="responsive" width=2 height=1.5 src="./img/clock.jpg">
<div class="clock-hand rotate-2"></div>
Expand All @@ -148,7 +148,7 @@ <h3>Rotate phone horizontally</h3>
<amp-orientation-observer
alpha-range="0 360"
on="alpha:clockAnim3.seekTo(percent=event.percent)"
layout="nodisplay">
layout="nodisplay" smoothing="5">
</amp-orientation-observer>
<amp-img layout="responsive" width=2 height=1.5 src="./img/clock.jpg">
<div class="clock-hand rotate-3"></div>
Expand Down
156 changes: 141 additions & 15 deletions extensions/amp-orientation-observer/0.1/amp-orientation-observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@

import {ActionTrust} from '../../../src/action-constants';
import {Services} from '../../../src/services';
import {clamp, sum} from '../../../src/utils/math';
import {createCustomEvent} from '../../../src/event-helper';
import {dict} from '../../../src/utils/object';
import {userAssert} from '../../../src/log';

const TAG = 'amp-orientation-observer';
const DEVICE_REST_ORIENTATION_ALPHA_VALUE = 180;
const DEVICE_REST_ORIENTATION_BETA_VALUE = 0;
const DEVICE_REST_ORIENTATION_GAMMA_VALUE = 0;
const DEFAULT_REST_ALPHA = 180;
const DEFAULT_REST_BETA = 0;
const DEFAULT_REST_GAMMA = 0;
const DELTA_CONST = 0.1;
const DEFAULT_SMOOTHING_PTS = 4;

export class AmpOrientationObserver extends AMP.BaseElement {
/** @param {!AmpElement} element */
Expand All @@ -47,13 +49,36 @@ export class AmpOrientationObserver extends AMP.BaseElement {
this.gammaRange_ = [-90, 90];

/** @private {number} */
this.alphaValue_ = DEVICE_REST_ORIENTATION_ALPHA_VALUE;
this.alphaValue_ = DEFAULT_REST_ALPHA;

/** @private {number} */
this.betaValue_ = DEVICE_REST_ORIENTATION_BETA_VALUE;
this.betaValue_ = DEFAULT_REST_BETA;

/** @private {number} */
this.gammaValue_ = DEVICE_REST_ORIENTATION_GAMMA_VALUE;
this.gammaValue_ = DEFAULT_REST_GAMMA;

/** @private {number} */
this.restAlphaValue_ = DEFAULT_REST_ALPHA;

/** @private {number} */
this.restBetaValue_ = DEFAULT_REST_BETA;

/** @private {number} */
this.restGammaValue_ = DEFAULT_REST_GAMMA;

/** @private {Array} */
this.alphaSmoothingPoints_ = [];

/** @private {Array} */
this.betaSmoothingPoints_ = [];

/** @private {Array} */
this.gammaSmoothingPoints_ = [];

/** @private {?number} */
this.smoothing_ = this.element.hasAttribute('smoothing')
? Number(this.element.getAttribute('smoothing')) || DEFAULT_SMOOTHING_PTS
: null;
}

/** @override */
Expand Down Expand Up @@ -109,26 +134,127 @@ export class AmpOrientationObserver extends AMP.BaseElement {
*/
deviceOrientationHandler_(event) {
if (event instanceof DeviceOrientationEvent) {
if (Math.abs(event.alpha - this.alphaValue_) > DELTA_CONST) {
this.alphaValue_ = /** @type {number} */ (event.alpha);
const {screen} = this.win;

const {alpha} = event;
let {gamma, beta} = event;

// Detect the implementation of orientation angle
const angle =
'orientation' in screen ? screen.orientation.angle : screen.orientation;

// Reverse gamma/beta if the device is in landscape
if (this.win.orientation == 90 || this.win.orientation == -90) {
const tmp = gamma;
gamma = beta;
beta = tmp;
}

// Flip signs of the angles if the phone is in 'reverse landscape' or
// 'reverse portrait'
if (angle < 0) {
gamma = -gamma;
beta = -beta;
}

if (Math.abs(alpha - this.alphaValue_) > DELTA_CONST) {
if (this.smoothing_) {
this.alphaValue_ = this.smoothedAlphaValue_(
/** @type {number} */ (alpha)
);
} else {
this.alphaValue_ = /** @type {number} */ (alpha);
}
this.triggerEvent_('alpha', this.alphaValue_, this.alphaRange_);
}
if (Math.abs(event.beta - this.betaValue_) > DELTA_CONST) {
this.betaValue_ = /** @type {number} */ (event.beta);
if (Math.abs(beta - this.betaValue_) > DELTA_CONST) {
if (this.smoothing_) {
this.betaValue_ = this.smoothedBetaValue_(
/** @type {number} */ (beta)
);
} else {
this.betaValue_ = /** @type {number} */ (beta);
}
this.triggerEvent_('beta', this.betaValue_, this.betaRange_);
}
if (Math.abs(event.gamma - this.gammaValue_) > DELTA_CONST) {
this.gammaValue_ = /** @type {number} */ (event.gamma);
if (Math.abs(gamma - this.gammaValue_) > DELTA_CONST) {
if (this.smoothing_) {
this.gammaValue_ = this.smoothedGammaValue_(
/** @type {number} */ (gamma)
);
} else {
this.gammaValue_ = /** @type {number} */ (gamma);
}
this.triggerEvent_('gamma', this.gammaValue_, this.gammaRange_);
}
}
}

/**
* Calculates a moving average over previous values of the alpha value
* @param {number} alpha
* @return {number}
*/
smoothedAlphaValue_(alpha) {
if (this.alphaSmoothingPoints_.length > this.smoothing_) {
this.alphaSmoothingPoints_.shift();
}
this.alphaSmoothingPoints_.push(alpha);
const avgAlpha = sum(this.alphaSmoothingPoints_) / this.smoothing_;
if (
this.alphaSmoothingPoints_.length > this.smoothing_ &&
this.restAlphaValue_ == DEFAULT_REST_ALPHA
) {
this.restAlphaValue_ = avgAlpha;
}
return avgAlpha - this.restAlphaValue_;
}

/**
* Calculates a moving average over previous values of the beta value
* @param {number} beta
* @return {number}
*/
smoothedBetaValue_(beta) {
if (this.betaSmoothingPoints_.length > this.smoothing_) {
this.betaSmoothingPoints_.shift();
}
this.betaSmoothingPoints_.push(beta);
const avgBeta = sum(this.betaSmoothingPoints_) / this.smoothing_;
if (
this.betaSmoothingPoints_.length > this.smoothing_ &&
this.restBetaValue_ == DEFAULT_REST_BETA
) {
this.restBetaValue_ = avgBeta;
}
return avgBeta - this.restBetaValue_;
}

/**
* Calculates a moving average over previous values of the gamma value
* @param {number} gamma
* @return {number}
*/
smoothedGammaValue_(gamma) {
if (this.gammaSmoothingPoints_.length > this.smoothing_) {
this.gammaSmoothingPoints_.shift();
}
this.gammaSmoothingPoints_.push(gamma);
const avgGamma = sum(this.betaSmoothingPoints_) / this.smoothing_;
if (
this.gammaSmoothingPoints_.length > this.smoothing_ &&
this.restGammaValue_ == DEFAULT_REST_BETA
) {
this.restGammaValue_ = avgGamma;
}
return avgGamma - this.restGammaValue_;
}

/**
* Dispatches the event to signify change in the device orientation
* along alpha axis.
* along a certain axis.
* @param {string} eventName
* @param {?number} eventValue
* @param {number} eventValue
* @param {Array} eventRange
* @private
*/
Expand All @@ -141,7 +267,7 @@ export class AmpOrientationObserver extends AMP.BaseElement {
this.win,
`${TAG}.${eventName}`,
dict({
'angle': eventValue.toFixed(),
'angle': clamp(eventValue, eventRange[0], eventRange[1]).toFixed(),
'percent': percentValue / (eventRange[1] - eventRange[0]),
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ describes.realWin(
return '-90 90';
}
},
hasAttribute(attr) {
if (attr == 'smoothing') {
return false;
}
},
};
elem.ownerDocument = {
defaultView: env.win,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
<amp-orientation-observer layout="nodisplay" alpha-range="0 90" on="alpha:foo(angle=event.angle);beta:bar;gamma:baz"></amp-orientation-observer>
<amp-orientation-observer layout="nodisplay" beta-range="0 90" on="alpha:foo;beta:bar(percent=event.percent);gamma:baz"></amp-orientation-observer>
<amp-orientation-observer layout="nodisplay" beta-range="0 90" on="alpha:foo;beta:bar(angle=event.angle);gamma:baz"></amp-orientation-observer>
<amp-orientation-observer layout="nodisplay" smoothing="5"></amp-orientation-observer>
<amp-orientation-observer layout="nodisplay" smoothing></amp-orientation-observer>

<!-- Invalid: missing required layout value -->
<amp-orientation-observer></amp-orientation-observer>
Expand Down Expand Up @@ -70,5 +72,11 @@
<amp-orientation-observer gamma-range="100 100 100" layout="nodisplay"></amp-orientation-observer>
<amp-orientation-observer gamma-range="a 100" layout="nodisplay"></amp-orientation-observer>
<amp-orientation-observer gamma-range="a b" layout="nodisplay"></amp-orientation-observer>

<!-- Invalid: smoothing value not valid -->
<amp-orientation-observer smoothing="b" layout="nodisplay"></amp-orientation-observer>
<amp-orientation-observer smoothing="2.5" layout="nodisplay"></amp-orientation-observer>
<amp-orientation-observer smoothing="0.5" layout="nodisplay"></amp-orientation-observer>
<amp-orientation-observer smoothing="-5" layout="nodisplay"></amp-orientation-observer>
</body>
</html>

0 comments on commit c543dd9

Please sign in to comment.