1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/base/utils.html">
9
10<script>
11'use strict';
12
13tr.exportTo('tr.ui', function() {
14  function TimelineDisplayTransform(opt_that) {
15    if (opt_that) {
16      this.set(opt_that);
17      return;
18    }
19    this.scaleX = 1;
20    this.panX = 0;
21    this.panY = 0;
22  }
23
24  TimelineDisplayTransform.prototype = {
25    set: function(that) {
26      this.scaleX = that.scaleX;
27      this.panX = that.panX;
28      this.panY = that.panY;
29    },
30
31    clone: function() {
32      return new TimelineDisplayTransform(this);
33    },
34
35    equals: function(that) {
36      var eq = true;
37      if (that === undefined || that === null)
38        return false;
39      eq &= this.panX === that.panX;
40      eq &= this.panY === that.panY;
41      eq &= this.scaleX === that.scaleX;
42      return !!eq;
43    },
44
45    almostEquals: function(that) {
46      var eq = true;
47      if (that === undefined || that === null)
48        return false;
49      eq &= Math.abs(this.panX - that.panX) < 0.001;
50      eq &= Math.abs(this.panY - that.panY) < 0.001;
51      eq &= Math.abs(this.scaleX - that.scaleX) < 0.001;
52      return !!eq;
53    },
54
55    incrementPanXInViewUnits: function(xDeltaView) {
56      this.panX += this.xViewVectorToWorld(xDeltaView);
57    },
58
59    xPanWorldPosToViewPos: function(worldX, viewX, viewWidth) {
60      if (typeof viewX == 'string') {
61        if (viewX === 'left') {
62          viewX = 0;
63        } else if (viewX === 'center') {
64          viewX = viewWidth / 2;
65        } else if (viewX === 'right') {
66          viewX = viewWidth - 1;
67        } else {
68          throw new Error('viewX must be left|center|right or number.');
69        }
70      }
71      this.panX = (viewX / this.scaleX) - worldX;
72    },
73
74    xPanWorldBoundsIntoView: function(worldMin, worldMax, viewWidth) {
75      if (this.xWorldToView(worldMin) < 0)
76        this.xPanWorldPosToViewPos(worldMin, 'left', viewWidth);
77      else if (this.xWorldToView(worldMax) > viewWidth)
78        this.xPanWorldPosToViewPos(worldMax, 'right', viewWidth);
79    },
80
81    xSetWorldBounds: function(worldMin, worldMax, viewWidth) {
82      var worldWidth = worldMax - worldMin;
83      var scaleX = viewWidth / worldWidth;
84      var panX = -worldMin;
85      this.setPanAndScale(panX, scaleX);
86    },
87
88    setPanAndScale: function(p, s) {
89      this.scaleX = s;
90      this.panX = p;
91    },
92
93    xWorldToView: function(x) {
94      return (x + this.panX) * this.scaleX;
95    },
96
97    xWorldVectorToView: function(x) {
98      return x * this.scaleX;
99    },
100
101    xViewToWorld: function(x) {
102      return (x / this.scaleX) - this.panX;
103    },
104
105    xViewVectorToWorld: function(x) {
106      return x / this.scaleX;
107    },
108
109    applyTransformToCanvas: function(ctx) {
110      ctx.transform(this.scaleX, 0, 0, 1, this.panX * this.scaleX, 0);
111    }
112  };
113
114  return {
115    TimelineDisplayTransform: TimelineDisplayTransform
116  };
117});
118</script>
119