• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 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<link rel="import" href="/tracing/base/base.html">
8<script>
9'use strict';
10
11tr.exportTo('tr.b', function() {
12  function clamp01(value) {
13    return Math.max(0, Math.min(1, value));
14  }
15
16  function Color(opt_r, opt_g, opt_b, opt_a) {
17    this.r = Math.floor(opt_r) || 0;
18    this.g = Math.floor(opt_g) || 0;
19    this.b = Math.floor(opt_b) || 0;
20    this.a = opt_a;
21  }
22
23  Color.fromString = function(str) {
24    var tmp;
25    var values;
26    if (str.substr(0, 4) == 'rgb(') {
27      tmp = str.substr(4, str.length - 5);
28      values = tmp.split(',').map(function(v) {
29        return v.replace(/^\s+/, '', 'g');
30      });
31      if (values.length != 3)
32        throw new Error('Malformatted rgb-expression');
33      return new Color(
34          parseInt(values[0]),
35          parseInt(values[1]),
36          parseInt(values[2]));
37    } else if (str.substr(0, 5) == 'rgba(') {
38      tmp = str.substr(5, str.length - 6);
39      values = tmp.split(',').map(function(v) {
40        return v.replace(/^\s+/, '', 'g');
41      });
42      if (values.length != 4)
43        throw new Error('Malformatted rgb-expression');
44      return new Color(
45          parseInt(values[0]),
46          parseInt(values[1]),
47          parseInt(values[2]),
48          parseFloat(values[3]));
49    } else if (str[0] == '#' && str.length == 7) {
50      return new Color(
51          parseInt(str.substr(1, 2), 16),
52          parseInt(str.substr(3, 2), 16),
53          parseInt(str.substr(5, 2), 16));
54    } else {
55      throw new Error('Unrecognized string format.');
56    }
57  };
58
59  Color.lerp = function(a, b, percent) {
60    if (a.a !== undefined && b.a !== undefined)
61      return Color.lerpRGBA(a, b, percent);
62    return Color.lerpRGB(a, b, percent);
63  };
64
65  Color.lerpRGB = function(a, b, percent) {
66    return new Color(
67        ((b.r - a.r) * percent) + a.r,
68        ((b.g - a.g) * percent) + a.g,
69        ((b.b - a.b) * percent) + a.b);
70  };
71
72  Color.lerpRGBA = function(a, b, percent) {
73    return new Color(
74        ((b.r - a.r) * percent) + a.r,
75        ((b.g - a.g) * percent) + a.g,
76        ((b.b - a.b) * percent) + a.b,
77        ((b.a - a.a) * percent) + a.a);
78  };
79
80  Color.fromDict = function(dict) {
81    return new Color(dict.r, dict.g, dict.b, dict.a);
82  };
83
84  /**
85   * Converts an HSL triplet with alpha to an RGB color.
86   * |h| Hue value in [0, 1].
87   * |s| Saturation value in [0, 1].
88   * |l| Lightness in [0, 1].
89   * |a| Alpha in [0, 1]
90   */
91  Color.fromHSLExplicit = function(h, s, l, a) {
92    var r, g, b;
93    function hue2rgb(p, q, t) {
94      if (t < 0) t += 1;
95      if (t > 1) t -= 1;
96      if (t < 1 / 6) return p + (q - p) * 6 * t;
97      if (t < 1 / 2) return q;
98      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
99      return p;
100    }
101
102    if (s === 0) {
103      r = g = b = l;
104    } else {
105        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
106        var p = 2 * l - q;
107        r = hue2rgb(p, q, h + 1 / 3);
108        g = hue2rgb(p, q, h);
109        b = hue2rgb(p, q, h - 1 / 3);
110    }
111
112    return new Color(Math.floor(r * 255),
113                     Math.floor(g * 255),
114                     Math.floor(b * 255), a);
115  }
116
117  Color.fromHSL = function(hsl) {
118    return Color.fromHSLExplicit(hsl.h, hsl.s, hsl.l, hsl.a);
119  }
120
121  Color.prototype = {
122    clone: function() {
123      var c = new Color();
124      c.r = this.r;
125      c.g = this.g;
126      c.b = this.b;
127      c.a = this.a;
128      return c;
129    },
130
131    blendOver: function(bgColor) {
132      var oneMinusThisAlpha = 1 - this.a;
133      var outA = this.a + bgColor.a * oneMinusThisAlpha;
134      var bgBlend = (bgColor.a * oneMinusThisAlpha) / bgColor.a;
135      return new Color(
136          this.r * this.a + bgColor.r * bgBlend,
137          this.g * this.a + bgColor.g * bgBlend,
138          this.b * this.a + bgColor.b * bgBlend,
139          outA);
140    },
141
142    brighten: function(opt_k) {
143      var k;
144      k = opt_k || 0.45;
145
146      return new Color(
147          Math.min(255, this.r + Math.floor(this.r * k)),
148          Math.min(255, this.g + Math.floor(this.g * k)),
149          Math.min(255, this.b + Math.floor(this.b * k)),
150          this.a);
151    },
152
153    lighten: function(k, opt_max_l) {
154      var max_l = opt_max_l !== undefined ? opt_max_l : 1.0;
155      var hsl = this.toHSL();
156      hsl.l = clamp01(hsl.l + k);
157      return Color.fromHSL(hsl);
158    },
159
160    darken: function(opt_k) {
161      var k;
162      if (opt_k !== undefined)
163        k = opt_k;
164      else
165        k = 0.45;
166
167      return new Color(
168          Math.min(255, this.r - Math.floor(this.r * k)),
169          Math.min(255, this.g - Math.floor(this.g * k)),
170          Math.min(255, this.b - Math.floor(this.b * k)),
171          this.a);
172    },
173
174    desaturate: function(opt_desaturateFactor) {
175      var desaturateFactor;
176      if (opt_desaturateFactor !== undefined)
177        desaturateFactor = opt_desaturateFactor;
178      else
179        desaturateFactor = 1;
180
181      var hsl = this.toHSL();
182      hsl.s = clamp01(hsl.s * (1 - desaturateFactor));
183      return Color.fromHSL(hsl);
184    },
185
186    withAlpha: function(a) {
187      return new Color(this.r, this.g, this.b, a);
188    },
189
190    toString: function() {
191      if (this.a !== undefined) {
192        return 'rgba(' +
193            this.r + ',' + this.g + ',' +
194            this.b + ',' + this.a + ')';
195      }
196      return 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';
197    },
198
199    /**
200     * Returns a dict {h, s, l, a} with:
201     * |h| Hue value in [0, 1].
202     * |s| Saturation value in [0, 1].
203     * |l| Lightness in [0, 1].
204     * |a| Alpha in [0, 1]
205     */
206    toHSL: function() {
207      var r = this.r / 255;
208      var g = this.g / 255;
209      var b = this.b / 255;
210
211      var max = Math.max(r, g, b);
212      var min = Math.min(r, g, b);
213
214      var h, s;
215      var l = (max + min) / 2;
216      if (min === max) {
217        h = 0;
218        s = 0;
219      } else {
220        var delta = max - min;
221        if (l > 0.5)
222          s = delta / (2 - max - min);
223        else
224          s = delta / (max + min);
225
226        if (r === max) {
227          h = (g - b) / delta;
228          if (g < b)
229            h += 6;
230        } else if (g === max) {
231          h = 2 + ((b - r) / delta);
232        } else {
233          h = 4 + ((r - g) / delta);
234        }
235        h /= 6;
236      }
237
238      return {h: h, s: s, l: l, a: this.a};
239    },
240
241    toStringWithAlphaOverride: function(alpha) {
242      return 'rgba(' +
243          this.r + ',' + this.g + ',' +
244          this.b + ',' + alpha + ')';
245    }
246  };
247
248  return {
249    Color: Color
250  };
251});
252</script>
253