From 55d01aa0f391f62e697031c51d058405049eabc2 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Mon, 16 Aug 2021 13:20:07 -0400 Subject: [PATCH] Scheduling profiler: Canvas views clip by default (#22100) --- .../src/content-views/SnapshotsView.js | 1 + .../src/content-views/SuspenseEventsView.js | 13 ------------- .../src/view-base/View.js | 17 +++++++++++++++++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/react-devtools-scheduling-profiler/src/content-views/SnapshotsView.js b/packages/react-devtools-scheduling-profiler/src/content-views/SnapshotsView.js index c0d48e0616b16..fbaa7c5d83570 100644 --- a/packages/react-devtools-scheduling-profiler/src/content-views/SnapshotsView.js +++ b/packages/react-devtools-scheduling-profiler/src/content-views/SnapshotsView.js @@ -118,6 +118,7 @@ export class SnapshotsView extends View { const visibleArea = this.visibleArea; // Prevent snapshot from visibly overflowing its container when clipped. + // View clips by default, but since this view may draw async (on Image load) we re-clip. const shouldClip = !rectEqualToRect(imageRect, visibleArea); if (shouldClip) { const clippedRect = intersectionOfRects(imageRect, visibleArea); diff --git a/packages/react-devtools-scheduling-profiler/src/content-views/SuspenseEventsView.js b/packages/react-devtools-scheduling-profiler/src/content-views/SuspenseEventsView.js index db234e4cebecf..b7237079c5d5b 100644 --- a/packages/react-devtools-scheduling-profiler/src/content-views/SuspenseEventsView.js +++ b/packages/react-devtools-scheduling-profiler/src/content-views/SuspenseEventsView.js @@ -168,18 +168,6 @@ export class SuspenseEventsView extends View { return; // Not in view } - const drawableRect = intersectionOfRects(suspenseRect, rect); - - // Clip diamonds so they don't overflow if the view has been resized (smaller). - const region = new Path2D(); - region.rect( - drawableRect.origin.x, - drawableRect.origin.y, - drawableRect.size.width, - drawableRect.size.height, - ); - context.save(); - context.clip(region); context.beginPath(); context.fillStyle = fillStyle; context.moveTo(xStart, y - halfSize); @@ -187,7 +175,6 @@ export class SuspenseEventsView extends View { context.lineTo(xStart, y + halfSize); context.lineTo(xStart - halfSize, y); context.fill(); - context.restore(); } else { const xStop = timestampToPosition( timestamp + duration, diff --git a/packages/react-devtools-scheduling-profiler/src/view-base/View.js b/packages/react-devtools-scheduling-profiler/src/view-base/View.js index b78af9d1e24ac..8dcda731efbc3 100644 --- a/packages/react-devtools-scheduling-profiler/src/view-base/View.js +++ b/packages/react-devtools-scheduling-profiler/src/view-base/View.js @@ -199,7 +199,24 @@ export class View { this.layoutSubviews(); if (this._needsDisplay) this._needsDisplay = false; if (this._subviewsNeedDisplay) this._subviewsNeedDisplay = false; + + // Clip anything drawn by the view to prevent it from overflowing its visible area. + const visibleArea = this.visibleArea; + const region = new Path2D(); + region.rect( + visibleArea.origin.x, + visibleArea.origin.y, + visibleArea.size.width, + visibleArea.size.height, + ); + context.save(); + context.clip(region); + context.beginPath(); + this.draw(context, viewRefs); + + // Stop clipping + context.restore(); } }