blob: 040d9363b6301e6bc688688688ee6a4ae871d672 [file] [log] [blame]
Michail Schwab405002c2018-07-26 13:19:10 -04001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15export class Animation {
Primiano Tucci3cae4b62018-08-01 22:40:45 +010016 private startMs = 0;
17 private endMs = 0;
18 private lastFrameMs = 0;
19 private rafId = 0;
Michail Schwab405002c2018-07-26 13:19:10 -040020
21 constructor(private onAnimationStep: (timeSinceLastMs: number) => void) {}
22
Primiano Tucci3cae4b62018-08-01 22:40:45 +010023 start(durationMs: number) {
24 const nowMs = performance.now();
25
26 // If the animation is already happening, just update its end time.
27 if (nowMs <= this.endMs) {
28 this.endMs = nowMs + durationMs;
29 return;
Michail Schwab405002c2018-07-26 13:19:10 -040030 }
Primiano Tucci3cae4b62018-08-01 22:40:45 +010031 this.lastFrameMs = 0;
32 this.startMs = nowMs;
33 this.endMs = nowMs + durationMs;
34 this.rafId = requestAnimationFrame(this.onAnimationFrame.bind(this));
Michail Schwab405002c2018-07-26 13:19:10 -040035 }
36
37 stop() {
Primiano Tucci3cae4b62018-08-01 22:40:45 +010038 this.endMs = 0;
39 cancelAnimationFrame(this.rafId);
Michail Schwab405002c2018-07-26 13:19:10 -040040 }
41
Primiano Tucci3cae4b62018-08-01 22:40:45 +010042 get startTimeMs(): number {
43 return this.startMs;
Michail Schwab405002c2018-07-26 13:19:10 -040044 }
45
Primiano Tucci3cae4b62018-08-01 22:40:45 +010046 private onAnimationFrame(nowMs: number) {
47 if (nowMs < this.endMs) {
48 this.rafId = requestAnimationFrame(this.onAnimationFrame.bind(this));
Michail Schwab405002c2018-07-26 13:19:10 -040049 }
Primiano Tucci3cae4b62018-08-01 22:40:45 +010050 this.onAnimationStep(nowMs - (this.lastFrameMs || nowMs));
51 this.lastFrameMs = nowMs;
Michail Schwab405002c2018-07-26 13:19:10 -040052 }
Primiano Tucci3cae4b62018-08-01 22:40:45 +010053}