Refactor helper methods for getting random values for a stage.
[WebKit-https.git] / PerformanceTests / Animometer / tests / master / resources / canvas-tests.js
1 (function() {
2
3 // === PAINT OBJECTS ===
4
5 function CanvasLineSegment(stage)
6 {
7     var circle = Stage.randomInt(0, 2);
8     this._color = ["#e01040", "#10c030", "#e05010"][circle];
9     this._lineWidth = Math.pow(Math.random(), 12) * 20 + 3;
10     this._omega = Math.random() * 3 + 0.2;
11     var theta = Stage.randomAngle();
12     this._cosTheta = Math.cos(theta);
13     this._sinTheta = Math.sin(theta);
14     this._startX = stage.circleRadius * this._cosTheta + (0.5 + circle) / 3 * stage.size.x;
15     this._startY = stage.circleRadius * this._sinTheta + stage.size.y / 2;
16     this._length = Math.pow(Math.random(), 8) * 40 + 20;
17     this._segmentDirection = Math.random() > 0.5 ? -1 : 1;
18 }
19
20 CanvasLineSegment.prototype.draw = function(context)
21 {
22     context.strokeStyle = this._color;
23     context.lineWidth = this._lineWidth;
24
25     this._length += Math.sin(Date.now()/100*this._omega);
26
27     context.beginPath();
28     context.moveTo(this._startX, this._startY);
29     context.lineTo(this._startX + this._segmentDirection * this._length * this._cosTheta,
30                    this._startY + this._segmentDirection * this._length * this._sinTheta);
31     context.stroke();
32 };
33
34 function CanvasArc(stage)
35 {
36     var maxX = 6, maxY = 3;
37     var distanceX = stage.size.x / maxX;
38     var distanceY = stage.size.y / (maxY + 1);
39     var randY = Stage.randomInt(0, maxY);
40     var randX = Stage.randomInt(0, maxX - 1 * (randY % 2));
41
42     this._point = new Point(distanceX * (randX + (randY % 2) / 2), distanceY * (randY + .5));
43
44     this._radius = 20 + Math.pow(Math.random(), 5) * (Math.min(distanceX, distanceY) / 1.8);
45     this._startAngle = Stage.randomAngle();
46     this._endAngle = Stage.randomAngle();
47     this._omega = (Math.random() - 0.5) * 0.3;
48     this._counterclockwise = Stage.randomBool();
49     var colors = ["#101010", "#808080", "#c0c0c0"];
50     colors.push(["#e01040", "#10c030", "#e05010"][(randX + Math.ceil(randY / 2)) % 3]);
51     this._color = colors[Math.floor(Math.random() * colors.length)];
52     this._lineWidth = 1 + Math.pow(Math.random(), 5) * 30;
53     this._doStroke = Stage.randomInt(0, 3) != 0;
54 };
55
56 CanvasArc.prototype.draw = function(context)
57 {
58     this._startAngle += this._omega;
59     this._endAngle += this._omega / 2;
60
61     if (this._doStroke) {
62         context.strokeStyle = this._color;
63         context.lineWidth = this._lineWidth;
64         context.beginPath();
65         context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
66         context.stroke();
67     } else {
68         context.fillStyle = this._color;
69         context.beginPath();
70         context.lineTo(this._point.x, this._point.y);
71         context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise);
72         context.lineTo(this._point.x, this._point.y);
73         context.fill();
74     }
75 };
76
77 // CanvasLinePoint contains no draw() method since it is either moveTo or
78 // lineTo depending on its index.
79 function CanvasLinePoint(stage, coordinateMaximum)
80 {
81     var X_LOOPS = 40;
82     var Y_LOOPS = 20;
83
84     var offsets = [[-2, -1], [2, 1], [-1, 0], [1, 0], [-1, 2], [1, -2]];
85     var offset = offsets[Math.floor(Math.random() * offsets.length)];
86
87     this.coordinate = new Point(X_LOOPS/2, Y_LOOPS/2);
88     if (stage.objects.length) {
89         var head = stage.objects[stage.objects.length - 1].coordinate;
90         this.coordinate.x = head.x;
91         this.coordinate.y = head.y;
92     }
93
94     var nextCoordinate = this.coordinate.x + offset[0];
95     if (nextCoordinate < 0 || nextCoordinate > X_LOOPS)
96         this.coordinate.x -= offset[0];
97     else
98         this.coordinate.x = nextCoordinate;
99     nextCoordinate = this.coordinate.y + offset[1];
100     if (nextCoordinate < 0 || nextCoordinate > Y_LOOPS)
101         this.coordinate.y -= offset[1];
102     else
103         this.coordinate.y = nextCoordinate;
104
105     var xOff = .25 * (this.coordinate.y % 2);
106     var randX = (xOff + this.coordinate.x) * stage.size.x / X_LOOPS;
107     var randY = this.coordinate.y * stage.size.y / Y_LOOPS;
108     var colors = ["#101010", "#808080", "#c0c0c0", "#101010", "#808080", "#c0c0c0", "#e01040"];
109     this.color = colors[Math.floor(Math.random() * colors.length)];
110
111     this.width = Math.pow(Math.random(), 5) * 20 + 1;
112     this.isSplit = Math.random() > 0.9;
113     this.point = new Point(randX, randY);
114 }
115
116 // === STAGES ===
117
118 CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage,
119     function()
120     {
121         SimpleCanvasStage.call(this, CanvasLineSegment);
122     }, {
123
124     initialize: function(benchmark)
125     {
126         SimpleCanvasStage.prototype.initialize.call(this, benchmark);
127         this.context.lineCap = benchmark.options["lineCap"] || "butt";
128         this.circleRadius = this.size.x / 3 / 2 - 20;
129     },
130
131     animate: function()
132     {
133         var context = this.context;
134         var stage = this;
135
136         context.clearRect(0, 0, this.size.x, this.size.y);
137         context.lineWidth = 30;
138         for(var i = 0; i < 3; i++) {
139             context.strokeStyle = ["#e01040", "#10c030", "#e05010"][i];
140             context.fillStyle = ["#70051d", "#016112", "#702701"][i];
141             context.beginPath();
142                 context.arc((0.5 + i) / 3 * stage.size.x, stage.size.y/2, stage.circleRadius, 0, Math.PI*2);
143             context.stroke();
144             context.fill();
145         }
146
147         this.objects.forEach(function(object) {
148             object.draw(context);
149         });
150     }
151 });
152
153 CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasStage,
154     function()
155     {
156         SimpleCanvasStage.call(this, CanvasLinePoint);
157     }, {
158
159     initialize: function(benchmark)
160     {
161         SimpleCanvasStage.prototype.initialize.call(this, benchmark);
162         this.context.lineJoin = benchmark.options["lineJoin"] || "bevel";
163         this.context.lineCap = benchmark.options["lineCap"] || "butt";
164     },
165
166     animate: function() {
167         var context = this.context;
168         var stage = this;
169
170         context.clearRect(0, 0, this.size.x, this.size.y);
171         context.beginPath();
172         this.objects.forEach(function(object, index) {
173             if (index == 0) {
174                 context.lineWidth = object.width;
175                 context.strokeStyle = object.color;
176                 context.moveTo(object.point.x, object.point.y);
177             } else {
178                 if (object.isSplit) {
179                     context.stroke();
180
181                     context.lineWidth = object.width;
182                     context.strokeStyle = object.color;
183                     context.beginPath();
184                 }
185
186                 context.lineTo(object.point.x, object.point.y);
187
188                 if (Math.random() > 0.999)
189                     object.isSplit = !object.isSplit;
190             }
191         });
192         context.stroke();
193     }
194 });
195
196 // === BENCHMARK ===
197
198 CanvasPathBenchmark = Utilities.createSubclass(Benchmark,
199     function(options)
200     {
201         var stage;
202         switch (options["pathType"]) {
203         case "line":
204             stage = new CanvasLineSegmentStage();
205             break;
206         case "linePath":
207             stage = new CanvasLinePathStage();
208             break;
209         case "arcs":
210             stage = new SimpleCanvasStage(CanvasArc);
211             break;
212         }
213
214         Benchmark.call(this, stage, options);
215     }
216 );
217
218 window.benchmarkClass = CanvasPathBenchmark;
219
220 })();