From 3ae2cee18880fff6e7e64f3fff5b83ea5dfd99ce Mon Sep 17 00:00:00 2001 From: Oscar Lorentzon Date: Mon, 25 Mar 2019 11:47:05 +0100 Subject: [PATCH] feat: use bezier curve for smooth field of view interpolation --- src/component/BearingComponent.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/component/BearingComponent.ts b/src/component/BearingComponent.ts index b5a50597..b8383250 100644 --- a/src/component/BearingComponent.ts +++ b/src/component/BearingComponent.ts @@ -1,5 +1,6 @@ import {distinctUntilChanged, map, switchMap, takeWhile, scan, skip} from "rxjs/operators"; import * as vd from "virtual-dom"; +import * as UnitBezier from "@mapbox/unitbezier"; import { Observable, @@ -69,6 +70,9 @@ export class BearingComponent extends Component { private _svgNamespace: string; private _distinctThreshold: number; + private _animationSpeed: number; + private _unitBezier: UnitBezier; + private _renderSubscription: Subscription; constructor(name: string, container: Container, navigator: Navigator) { @@ -79,6 +83,9 @@ export class BearingComponent extends Component { this._svgNamespace = "http://www.w3.org/2000/svg"; this._distinctThreshold = Math.PI / 360; + + this._animationSpeed = 0.075; + this._unitBezier = new UnitBezier(0.74, 0.67, 0.38, 0.96); } protected _activate(): void { @@ -168,7 +175,7 @@ export class BearingComponent extends Component { { alpha: 0, curr: [0, 0, 0], prev: [0, 0, 0] }), map( (state: NodeFovState): NodeFov => { - const alpha: number = state.alpha; + const alpha: number = this._unitBezier.solve(state.alpha); const curr: NodeFov = state.curr; const prev: NodeFov = state.prev; @@ -182,7 +189,7 @@ export class BearingComponent extends Component { map( (nbf: NodeFov): INodeFovOperation => { return (state: NodeFovState): NodeFovState => { - const a: number = state.alpha; + const a: number = this._unitBezier.solve(state.alpha); const c: NodeFov = state.curr; const p: NodeFov = state.prev; @@ -209,12 +216,16 @@ export class BearingComponent extends Component { skip(1), scan( (alpha: number): number => { - return alpha + 0.1; + return alpha + this._animationSpeed; }, 0), takeWhile( (alpha: number): boolean => { - return alpha <= 1 + 1e-6; + return alpha <= 1 + this._animationSpeed; + }), + map( + (alpha: number): number => { + return Math.min(alpha, 1); })); }), map(