Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/time tooltip overflow #8530

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/css/components/_progress.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
// with the right edge of their parent element. However, in order to have them
// centered, they must be pulled further to the right via positioning (e.g.
// `right: -10px;`. This part is left to JavaScript.
float: right;
// float: right;
font-family: $text-font-family;

// The font-size should translate to a consistent 10px for time tooltips in
Expand All @@ -134,6 +134,8 @@
pointer-events: none;
position: absolute;
top: -3.4em;
right: 0;
transform: translateX(50%);
visibility: hidden;
z-index: 1;
}
Expand Down
69 changes: 25 additions & 44 deletions src/js/control-bar/progress-control/time-tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,58 +52,39 @@ class TimeTooltip extends Component {
* from the left edge of the {@link SeekBar}
*/
update(seekBarRect, seekBarPoint, content) {
const tooltipRect = Dom.findPosition(this.el_);
const playerRect = Dom.getBoundingClientRect(this.player_.el());
const seekBarPointPx = seekBarRect.width * seekBarPoint;
this.write(content);

// do nothing if either rect isn't available
// for example, if the player isn't in the DOM for testing
if (!playerRect || !tooltipRect) {
const seekBarRectWidth = seekBarRect.width;
const position = seekBarRectWidth * seekBarPoint;
const timeTooltipWidth = parseFloat(Dom.computedStyle(this.el(), 'width'));
const timeTooltipPosition = position + timeTooltipWidth / 2;
const isSeekBarSmallerThanTimeTooltip = seekBarRectWidth < timeTooltipWidth;

// Keeps the component centered if were not reaching the far left/right
// of the seek bar or if the seek bar is smaller than the time tooltip
if (
timeTooltipPosition >= timeTooltipWidth &&
timeTooltipPosition <= seekBarRectWidth &&
this.el().style.length ||
isSeekBarSmallerThanTimeTooltip
) {
this.el().style = '';
return;
}

// This is the space left of the `seekBarPoint` available within the bounds
// of the player. We calculate any gap between the left edge of the player
// and the left edge of the `SeekBar` and add the number of pixels in the
// `SeekBar` before hitting the `seekBarPoint`
const spaceLeftOfPoint = (seekBarRect.left - playerRect.left) + seekBarPointPx;

// This is the space right of the `seekBarPoint` available within the bounds
// of the player. We calculate the number of pixels from the `seekBarPoint`
// to the right edge of the `SeekBar` and add to that any gap between the
// right edge of the `SeekBar` and the player.
const spaceRightOfPoint = (seekBarRect.width - seekBarPointPx) +
(playerRect.right - seekBarRect.right);

// This is the number of pixels by which the tooltip will need to be pulled
// further to the right to center it over the `seekBarPoint`.
let pullTooltipBy = tooltipRect.width / 2;

// Adjust the `pullTooltipBy` distance to the left or right depending on
// the results of the space calculations above.
if (spaceLeftOfPoint < pullTooltipBy) {
pullTooltipBy += pullTooltipBy - spaceLeftOfPoint;
} else if (spaceRightOfPoint < pullTooltipBy) {
pullTooltipBy = spaceRightOfPoint;
}
// Avoid component right overflow
const isOverflowingRight = timeTooltipPosition >= seekBarRectWidth;

// Due to the imprecision of decimal/ratio based calculations and varying
// rounding behaviors, there are cases where the spacing adjustment is off
// by a pixel or two. This adds insurance to these calculations.
if (pullTooltipBy < 0) {
pullTooltipBy = 0;
} else if (pullTooltipBy > tooltipRect.width) {
pullTooltipBy = tooltipRect.width;
if (isOverflowingRight) {
this.el().style.transform = `translateX(calc(50% - ${Math.abs(seekBarRectWidth - timeTooltipPosition)}px))`;
}

// prevent small width fluctuations within 0.4px from
// changing the value below.
// This really helps for live to prevent the play
// progress time tooltip from jittering
pullTooltipBy = Math.round(pullTooltipBy);
// Avoid component left overflow
const isOverflowingLeft = timeTooltipPosition <= timeTooltipWidth;

this.el_.style.right = `-${pullTooltipBy}px`;
this.write(content);
if (isOverflowingLeft) {
this.el().style.transform = `translateX(calc(50% + ${Math.abs(timeTooltipPosition - timeTooltipWidth)}px))`;
}
}

/**
Expand Down