12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Use of this source code is governed by a BSD-style license that can be 32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// found in the LICENSE file. 42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis'use strict'; 62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.requireStylesheet('tracing.tracks.ruler_track'); 82da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 96833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennisbase.require('tracing.constants'); 1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('tracing.tracks.track'); 116833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennisbase.require('tracing.tracks.heading_track'); 122da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui'); 132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1488448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.exportTo('tracing.tracks', function() { 152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 174849cead45edf85cf2a61526c0b716eb637f74baJeff Brown * A track that displays the ruler. 182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 196833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis * @extends {HeadingTrack} 202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 226833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var RulerTrack = ui.define('ruler-track', tracing.tracks.HeadingTrack); 232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var logOf10 = Math.log(10); 252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function log10(x) { 262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return Math.log(x) / logOf10; 272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 294849cead45edf85cf2a61526c0b716eb637f74baJeff Brown RulerTrack.prototype = { 306833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis __proto__: tracing.tracks.HeadingTrack.prototype, 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis decorate: function(viewport) { 336833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis tracing.tracks.HeadingTrack.prototype.decorate.call(this, viewport); 344849cead45edf85cf2a61526c0b716eb637f74baJeff Brown this.classList.add('ruler-track'); 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.strings_secs_ = []; 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.strings_msecs_ = []; 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.addEventListener('mousedown', this.onMouseDown); 3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.viewportMarkersChange_ = this.viewportMarkersChange_.bind(this); 4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis viewport.addEventListener('markersChange', this.viewportMarkersChange_); 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis detach: function() { 456833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis tracing.tracks.HeadingTrack.prototype.detach.call(this); 4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.viewport.removeEventListener('markersChange', 4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.viewportMarkersChange_); 4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis viewportMarkersChange_: function() { 5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (this.viewport.markers.length < 2) 5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.classList.remove('ruler-track-with-distance-measurements'); 5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis else 5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.classList.add('ruler-track-with-distance-measurements'); 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis onMouseDown: function(e) { 586833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis if (e.button !== 0) 592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.placeAndBeginDraggingMarker(e.clientX); 612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis placeAndBeginDraggingMarker: function(clientX) { 6488448d9ae4dfff1805045790ef5f32495d62abccJeff Brown var pixelRatio = window.devicePixelRatio || 1; 656833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 666833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var viewX = 676833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis (clientX - this.offsetLeft - tracing.constants.HEADING_WIDTH) * 686833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis pixelRatio; 6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var worldX = this.viewport.xViewToWorld(viewX); 7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var marker = this.viewport.findMarkerNear(worldX, 6); 716833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var createdMarker = false; 732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var movedMarker = false; 742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!marker) { 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis marker = this.viewport.addMarker(worldX); 762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis createdMarker = true; 772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis marker.selected = true; 792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var onMouseMove = function(e) { 816833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var viewX = 826833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis (e.clientX - this.offsetLeft - tracing.constants.HEADING_WIDTH) * 836833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis pixelRatio; 846833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var worldX = this.viewport.xViewToWorld(viewX); 856833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis marker.positionWorld = worldX; 872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis movedMarker = true; 886833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis }.bind(this); 892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var onMouseUp = function(e) { 912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis marker.selected = false; 922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!movedMarker && !createdMarker) 936833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis this.viewport.removeMarker(marker); 946833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.removeEventListener('mouseup', onMouseUp); 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.removeEventListener('mousemove', onMouseMove); 976833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis }.bind(this); 982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.addEventListener('mouseup', onMouseUp); 1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis document.addEventListener('mousemove', onMouseMove); 1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis drawLine_: function(ctx, x1, y1, x2, y2, color) { 1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.beginPath(); 1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.moveTo(x1, y1); 1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(x2, y2); 1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.closePath(); 1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.strokeStyle = color; 1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.stroke(); 1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis drawArrow_: function(ctx, x1, y1, x2, y2, arrowWidth, color) { 1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.drawLine_(ctx, x1, y1, x2, y2, color); 1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var dx = x2 - x1; 1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var dy = y2 - y1; 1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var len = Math.sqrt(dx * dx + dy * dy); 1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var perc = (len - 10) / len; 1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var bx = x1 + perc * dx; 1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var by = y1 + perc * dy; 1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var ux = dx / len; 1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var uy = dy / len; 1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var ax = uy * arrowWidth; 1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var ay = -ux * arrowWidth; 1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.beginPath(); 1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillStyle = color; 1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.moveTo(bx + ax, by + ay); 1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(x2, y2); 1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(bx - ax, by - ay); 1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(bx + ax, by + ay); 1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.closePath(); 1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fill(); 1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1366833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis draw: function(type, viewLWorld, viewRWorld) { 1376833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis switch (type) { 1386833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis case tracing.tracks.DrawType.SLICE: 1396833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis this.drawSlices_(viewLWorld, viewRWorld); 1406833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis break; 1416833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis } 1426833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis }, 1436833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 1446833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis drawSlices_: function(viewLWorld, viewRWorld) { 14566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var ctx = this.context(); 14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var pixelRatio = window.devicePixelRatio || 1; 1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var bounds = this.getBoundingClientRect(); 14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var width = bounds.width * pixelRatio; 15066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var height = bounds.height * pixelRatio; 1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1524849cead45edf85cf2a61526c0b716eb637f74baJeff Brown var measurements = this.classList.contains( 1534849cead45edf85cf2a61526c0b716eb637f74baJeff Brown 'ruler-track-with-distance-measurements'); 1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 15566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var rulerHeight = measurements ? height / 2 : height; 1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var vp = this.viewport; 15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis vp.drawMarkerArrows(ctx, viewLWorld, viewRWorld, rulerHeight); 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 16088448d9ae4dfff1805045790ef5f32495d62abccJeff Brown var idealMajorMarkDistancePix = 150 * pixelRatio; 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var idealMajorMarkDistanceWorld = 1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis vp.xViewVectorToWorld(idealMajorMarkDistancePix); 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var majorMarkDistanceWorld; 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var unit; 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var unitDivisor; 1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var tickLabels; 1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // The conservative guess is the nearest enclosing 0.1, 1, 10, 100, etc. 1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var conservativeGuess = 1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Math.pow(10, Math.ceil(log10(idealMajorMarkDistanceWorld))); 1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Once we have a conservative guess, consider things that evenly add up 1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // to the conservative guess, e.g. 0.5, 0.2, 0.1 Pick the one that still 1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // exceeds the ideal mark distance. 1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var divisors = [10, 5, 2, 1]; 1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < divisors.length; ++i) { 1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var tightenedGuess = conservativeGuess / divisors[i]; 1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (vp.xWorldVectorToView(tightenedGuess) < idealMajorMarkDistancePix) 1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis majorMarkDistanceWorld = conservativeGuess / divisors[i - 1]; 1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis break; 1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var tickLabels = undefined; 1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (majorMarkDistanceWorld < 100) { 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unit = 'ms'; 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unitDivisor = 1; 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tickLabels = this.strings_msecs_; 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } else { 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unit = 's'; 1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unitDivisor = 1000; 1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tickLabels = this.strings_secs_; 1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var numTicksPerMajor = 5; 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var minorMarkDistanceWorld = majorMarkDistanceWorld / numTicksPerMajor; 1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var minorMarkDistancePx = vp.xWorldVectorToView(minorMarkDistanceWorld); 1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var firstMajorMark = 2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Math.floor(viewLWorld / majorMarkDistanceWorld) * 2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis majorMarkDistanceWorld; 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var minorTickH = Math.floor(height * 0.25); 2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillStyle = 'rgb(0, 0, 0)'; 2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.strokeStyle = 'rgb(0, 0, 0)'; 2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.textAlign = 'left'; 2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.textBaseline = 'top'; 2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var pixelRatio = window.devicePixelRatio || 1; 2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.font = (9 * pixelRatio) + 'px sans-serif'; 2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Each iteration of this loop draws one major mark 2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // and numTicksPerMajor minor ticks. 2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Rendering can't be done in world space because canvas transforms 2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // affect line width. So, do the conversions manually. 2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var curX = firstMajorMark; 2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis curX < viewRWorld; 2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis curX += majorMarkDistanceWorld) { 2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var curXView = Math.floor(vp.xWorldToView(curX)); 2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var unitValue = curX / unitDivisor; 2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var roundedUnitValue = Math.floor(unitValue * 100000) / 100000; 2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!tickLabels[roundedUnitValue]) 2292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tickLabels[roundedUnitValue] = roundedUnitValue + ' ' + unit; 2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillText(tickLabels[roundedUnitValue], 2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis curXView + 2 * pixelRatio, 0); 2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.beginPath(); 2332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Major mark 2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.moveTo(curXView, 0); 2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(curXView, rulerHeight); 2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Minor marks 2392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 1; i < numTicksPerMajor; ++i) { 2402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var xView = Math.floor(curXView + minorMarkDistancePx * i); 2412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.moveTo(xView, rulerHeight - minorTickH); 2422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(xView, rulerHeight); 2432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.stroke(); 2462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2476833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis // Draw bottom bar. 2486833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.moveTo(0, rulerHeight); 2496833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.lineTo(width, rulerHeight); 2506833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.stroke(); 2512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Give distance between directly adjacent markers. 2532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (measurements) { 2542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Obtain a sorted array of markers 2552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var sortedMarkers = vp.markers.slice(); 2562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis sortedMarkers.sort(function(a, b) { 2572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return a.positionWorld_ - b.positionWorld_; 2582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }); 2592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Distance Variables. 2612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var displayDistance; 2622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var unitDivisor; 2632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var displayTextColor = 'rgb(0,0,0)'; 2642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var measurementsPosY = rulerHeight + 2; 2652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Arrow Variables. 2672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var arrowSpacing = 10; 2682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var arrowColor = 'rgb(128,121,121)'; 2692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var arrowPosY = measurementsPosY + 4; 2702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var arrowWidthView = 3; 2712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var spaceForArrowsView = 2 * (arrowWidthView + arrowSpacing); 2722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (i = 0; i < sortedMarkers.length - 1; i++) { 2742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var rightMarker = sortedMarkers[i + 1]; 2752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var leftMarker = sortedMarkers[i]; 2762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var distanceBetweenMarkers = 2772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis rightMarker.positionWorld - leftMarker.positionWorld; 2782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var distanceBetweenMarkersView = 2792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis vp.xWorldVectorToView(distanceBetweenMarkers); 2802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var positionInMiddleOfMarkers = leftMarker.positionWorld + 2822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis distanceBetweenMarkers / 2; 2832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var positionInMiddleOfMarkersView = 2842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis vp.xWorldToView(positionInMiddleOfMarkers); 2852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Determine units. 2872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (distanceBetweenMarkers < 100) { 2882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unit = 'ms'; 2892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unitDivisor = 1; 2902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } else { 2912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unit = 's'; 2922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis unitDivisor = 1000; 2932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Calculate display value to print. 2952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis displayDistance = distanceBetweenMarkers / unitDivisor; 2962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var roundedDisplayDistance = 2972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis Math.abs((Math.floor(displayDistance * 1000) / 1000)); 2982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textToDraw = roundedDisplayDistance + ' ' + unit; 2992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textWidthView = ctx.measureText(textToDraw).width; 3002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textWidthWorld = vp.xViewVectorToWorld(textWidthView); 3012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var spaceForArrowsAndTextView = textWidthView + 3022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis spaceForArrowsView + arrowSpacing; 3032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Set text positions. 3052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textLeft = leftMarker.positionWorld + 3062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis (distanceBetweenMarkers / 2) - (textWidthWorld / 2); 3072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textRight = textLeft + textWidthWorld; 3082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textPosY = measurementsPosY; 3092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textLeftView = vp.xWorldToView(textLeft); 3102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textRightView = vp.xWorldToView(textRight); 3112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var leftMarkerView = vp.xWorldToView(leftMarker.positionWorld); 3122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var rightMarkerView = vp.xWorldToView(rightMarker.positionWorld); 3132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textDrawn = false; 3142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (spaceForArrowsAndTextView <= distanceBetweenMarkersView) { 3162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Print the display distance text. 3172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillStyle = displayTextColor; 3182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillText(textToDraw, textLeftView, textPosY); 3192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis textDrawn = true; 3202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (spaceForArrowsView <= distanceBetweenMarkersView) { 3232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var leftArrowStart; 3242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var rightArrowStart; 3252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (textDrawn) { 3262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis leftArrowStart = textLeftView - arrowSpacing; 3272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis rightArrowStart = textRightView + arrowSpacing; 3282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } else { 3292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis leftArrowStart = positionInMiddleOfMarkersView; 3302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis rightArrowStart = positionInMiddleOfMarkersView; 3312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Draw left arrow. 3332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.drawArrow_(ctx, leftArrowStart, arrowPosY, 3342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis leftMarkerView, arrowPosY, arrowWidthView, arrowColor); 3352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Draw right arrow. 3362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.drawArrow_(ctx, rightArrowStart, arrowPosY, 3372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis rightMarkerView, arrowPosY, arrowWidthView, arrowColor); 3382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3406833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis // Draw bottom bar. 3416833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.moveTo(0, rulerHeight * 2); 3426833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.lineTo(width, rulerHeight * 2); 3436833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis ctx.stroke(); 3442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 3462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 3482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Adds items intersecting the given range to a selection. 3492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {number} loVX Lower X bound of the interval to search, in 3502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * viewspace. 3512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {number} hiVX Upper X bound of the interval to search, in 3522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * viewspace. 3532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {number} loVY Lower Y bound of the interval to search, in 3542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * viewspace. 3552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {number} hiVY Upper Y bound of the interval to search, in 3562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * viewspace. 35788448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * @param {Selection} selection Selection to which to add hits. 3582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 3592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addIntersectingItemsInRangeToSelection: function( 3602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis loVX, hiVX, loY, hiY, selection) { 3614849cead45edf85cf2a61526c0b716eb637f74baJeff Brown // Does nothing. There's nothing interesting to pick on the ruler 3622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // track. 3632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 3642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addAllObjectsMatchingFilterToSelection: function(filter, selection) { 3662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 3682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return { 3704849cead45edf85cf2a61526c0b716eb637f74baJeff Brown RulerTrack: RulerTrack 3712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 3722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis}); 373