positionIndicatorRenderer.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import {mat3} from 'gl-matrix';
  2. import {FlamegraphTheme} from '../flamegraph/flamegraphTheme';
  3. import {getContext, Rect} from '../gl/utils';
  4. class PositionIndicatorRenderer {
  5. canvas: HTMLCanvasElement;
  6. context: CanvasRenderingContext2D;
  7. theme: FlamegraphTheme;
  8. constructor(canvas: HTMLCanvasElement, theme: FlamegraphTheme) {
  9. this.canvas = canvas;
  10. this.theme = theme;
  11. this.context = getContext(this.canvas, '2d');
  12. }
  13. draw(configView: Rect, configSpace: Rect, configSpaceToPhysicalSpace: mat3): void {
  14. if (configView.equals(configSpace)) {
  15. // User is not zoomed in, so we dont need to draw anything.
  16. return;
  17. }
  18. // Transform both views to their respective physical spaces
  19. const physicalConfigViewRect = Rect.From(configView).transformRect(
  20. configSpaceToPhysicalSpace
  21. );
  22. const physicalConfigRect = Rect.From(configSpace).transformRect(
  23. configSpaceToPhysicalSpace
  24. );
  25. const offsetRectForBorderWidth: [number, number, number, number] = [
  26. physicalConfigViewRect.x - this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  27. physicalConfigViewRect.y,
  28. physicalConfigViewRect.width +
  29. this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  30. physicalConfigViewRect.height,
  31. ];
  32. // What we do to draw the "window" that the user is currently watching is we draw two rectangles, the
  33. // zoomed in view and the zoomed out view. The zoomed out view is the full view of the flamegraph, and the zoom
  34. // in view is whatever the user is currently looking at. Because the zoomed in view is a subset of the zoomed,
  35. // we just need to use the evenodd fill rule to paint inbetween the two rectangles.
  36. this.context.fillStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_COLOR;
  37. this.context.strokeStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_BORDER_COLOR;
  38. this.context.lineWidth = this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH;
  39. this.context.beginPath();
  40. this.context.rect(0, 0, physicalConfigRect.width, physicalConfigRect.height);
  41. this.context.rect(...offsetRectForBorderWidth);
  42. this.context.fill('evenodd');
  43. this.context.strokeRect(...offsetRectForBorderWidth);
  44. }
  45. }
  46. export {PositionIndicatorRenderer};