positionIndicatorRenderer.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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 or entire chart fits in view,
  16. // then we dont need to draw anything.
  17. return;
  18. }
  19. // Transform both views to their respective physical spaces
  20. const physicalConfigViewRect = Rect.From(configView).transformRect(
  21. configSpaceToPhysicalSpace
  22. );
  23. const physicalConfigRect = Rect.From(configSpace).transformRect(
  24. configSpaceToPhysicalSpace
  25. );
  26. const offsetRectForBorderWidth: [number, number, number, number] = [
  27. physicalConfigViewRect.x - this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  28. physicalConfigViewRect.y,
  29. physicalConfigViewRect.width +
  30. this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH,
  31. physicalConfigViewRect.height,
  32. ];
  33. // What we do to draw the "window" that the user is currently watching is we draw two rectangles, the
  34. // zoomed in view and the zoomed out view. The zoomed out view is the full view of the flamegraph, and the zoom
  35. // in view is whatever the user is currently looking at. Because the zoomed in view is a subset of the zoomed,
  36. // we just need to use the evenodd fill rule to paint inbetween the two rectangles.
  37. this.context.fillStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_COLOR;
  38. this.context.strokeStyle = this.theme.COLORS.MINIMAP_POSITION_OVERLAY_BORDER_COLOR;
  39. this.context.lineWidth = this.theme.SIZES.MINIMAP_POSITION_OVERLAY_BORDER_WIDTH;
  40. this.context.beginPath();
  41. this.context.rect(0, 0, physicalConfigRect.width, physicalConfigRect.height);
  42. this.context.rect(...offsetRectForBorderWidth);
  43. this.context.fill('evenodd');
  44. this.context.strokeRect(...offsetRectForBorderWidth);
  45. }
  46. }
  47. export {PositionIndicatorRenderer};