components icon indicating copy to clipboard operation
components copied to clipboard

fix(material/core): ripple coords when trigger is not the container

Open enten opened this issue 1 year ago • 0 comments
trafficstars

This pull request is a proposal to fix coordinates emitted from the trigger element when it's different than the container element.

Actual behavior

When a pointer down event (mousedown: MouseEvent or touchstart: TouchEvent) is emitted from the trigger element, its clientX and clientY properties are used to call RippleRender::fadeInRipple.

In case where the trigger element is the ripple container element, clientX and clientY are inside the container dom rect.

But when the trigger element is different than the ripple container element (a trigger element can be set by using matRippleTrigger input), clientX and clientY are outside the container dom rect.

Expeded behavior

In case where the trigger element is different than the ripple container element, using clientX and clientY properties and calculating an equivalent point in the container element before calling RippleRender::fadeInRipple.

Reproduction

StackBlitz link: https://stackblitz.com/edit/components-issue-gtvxae

  • The div "Ripple Container" is the ripple container: <div matRipple matRippleRadius="10" [matRippleTrigger]="trigger"></div>
  • The "Trigger Ripple" button is the ripple trigger: <button #trigger>Trigger Button</button>
  • When "Trigger Ripple" button is clicked, the ripple element (red dot in screenshot below) is positionned outside the ripple container dom rect (the ripple element is positionned inside the trigger dom rect)
  • When "Trigger Ripple with expected behavior" button is clicked, the clientX and clientY properties are fixed and the ripple element (green dot in screenshot below) is positionned correctly inside the ripple container dom rect

image

  /** Fix coordinates emitted from the trigger element when is not the container element. */
  private _fixCoordinatesEmittedFromTrigger(x: number, y: number): [number, number] {
    if (this._triggerElement && this._triggerElement !== this._containerElement) {
      const containerRect = (this._containerRect =
        this._containerRect || this._containerElement.getBoundingClientRect());
      const triggerRect = (this._triggerRect =
        this._triggerRect || this._triggerElement.getBoundingClientRect());
      x = ((x - triggerRect.left) / triggerRect.width) * containerRect.width + containerRect.left;
      y = ((y - triggerRect.top) / triggerRect.height) * containerRect.height + containerRect.top;
    }
    return [x, y];
  }
}

enten avatar May 08 '24 19:05 enten