Skip to content

Commit

Permalink
fix(ripple): make ripples conform with specs (#2859)
Browse files Browse the repository at this point in the history
* fix(ripple): make ripples conform with specs

This makes the ripple service conform with the specifications and other Material reference implementations.

See https://material.io/guidelines/motion/material-motion.html#material-motion-how-does-material-move

This means the following:

 * Ripples now trigger on `mousedown`
 * Ripples now persists as long as the element is being hold.
 * No longer adds an unnecessary background ripple.
 * Removes the ugly `scale(0.00001)` for ripple animations

Not only visually the ripple has been changed. The whole renderer has been rewritten and now has a very simple API, that can be easily used by developers.

References #1434

* Fix linting and IE11 unsupported error

* Ensure style recalculation

* Address comments

* Address feedback

* Document that fade-out duration can't be modified through the speedFactor
  • Loading branch information
devversion authored and tinayuangao committed Feb 10, 2017
1 parent e728771 commit 6381948
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 659 deletions.
15 changes: 4 additions & 11 deletions src/demo-app/ripple/ripple-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,18 @@
<section>
Speed
<md-radio-group [(ngModel)]="rippleSpeed">
<md-radio-button name="demo-ripple-options" value="0.1">Slow</md-radio-button>
<md-radio-button name="demo-ripple-options" value="0.4">Slow</md-radio-button>
<md-radio-button name="demo-ripple-options" value="1">Normal</md-radio-button>
<md-radio-button name="demo-ripple-options" value="4">Fast</md-radio-button>
<md-radio-button name="demo-ripple-options" value="2.5">Fast</md-radio-button>
</md-radio-group>
</section>
<section>
<md-input-container>
<input mdInput placeholder="Max radius" aria-label="radius" [(ngModel)]="maxRadius">
<input mdInput placeholder="Ripple radius" aria-label="radius" [(ngModel)]="radius">
</md-input-container>
<md-input-container>
<input mdInput placeholder="Ripple color" aria-label="color" [(ngModel)]="rippleColor">
</md-input-container>
<md-input-container>
<input mdInput
placeholder="Ripple background"
aria-label="background"
[(ngModel)]="rippleBackgroundColor">
</md-input-container>
</section>
<section>
<button md-raised-button (click)="doManualRipple()">Manual ripple</button>
Expand All @@ -51,9 +45,8 @@
[mdRippleCentered]="centered"
[mdRippleDisabled]="disabled"
[mdRippleUnbounded]="unbounded"
[mdRippleMaxRadius]="maxRadius"
[mdRippleRadius]="radius"
[mdRippleColor]="rippleColor"
[mdRippleBackgroundColor]="rippleBackgroundColor"
[mdRippleSpeedFactor]="rippleSpeed">
Click me
</div>
Expand Down
11 changes: 5 additions & 6 deletions src/demo-app/ripple/ripple-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ import {MdRipple} from '@angular/material';
styleUrls: ['ripple-demo.css'],
})
export class RippleDemo {
@ViewChild(MdRipple) manualRipple: MdRipple;
@ViewChild(MdRipple) ripple: MdRipple;

centered = false;
disabled = false;
unbounded = false;
rounded = false;
maxRadius: number = null;
radius: number = null;
rippleSpeed = 1;
rippleColor = '';
rippleBackgroundColor = '';

disableButtonRipples = false;

doManualRipple() {
if (this.manualRipple) {
window.setTimeout(() => this.manualRipple.start(), 10);
window.setTimeout(() => this.manualRipple.end(0, 0), 500);
if (this.ripple) {
this.ripple.launch(0, 0, { centered: true });
}
}

}
4 changes: 1 addition & 3 deletions src/lib/button/button.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<span class="mat-button-wrapper"><ng-content></ng-content></span>
<div md-ripple *ngIf="!_isRippleDisabled()" class="mat-button-ripple"
[class.mat-button-ripple-round]="_isRoundButton()"
[mdRippleTrigger]="_getHostElement()"
[mdRippleColor]="_isRoundButton() ? 'rgba(255, 255, 255, 0.2)' : ''"
mdRippleBackgroundColor="rgba(0, 0, 0, 0)"></div>
[mdRippleTrigger]="_getHostElement()"></div>
<!-- the touchstart handler prevents the overlay from capturing the initial tap on touch devices -->
<div class="mat-button-focus-overlay" (touchstart)="$event.preventDefault()"></div>
6 changes: 3 additions & 3 deletions src/lib/checkbox/_checkbox-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@
}

.mat-checkbox:not(.mat-checkbox-disabled) {
&.mat-primary .mat-checkbox-ripple .mat-ripple-foreground {
&.mat-primary .mat-checkbox-ripple .mat-ripple-element {
background-color: mat-color($primary, 0.26);
}

&.mat-accent .mat-checkbox-ripple .mat-ripple-foreground {
&.mat-accent .mat-checkbox-ripple .mat-ripple-element {
background-color: mat-color($accent, 0.26);
}

&.mat-warn .mat-checkbox-ripple .mat-ripple-foreground {
&.mat-warn .mat-checkbox-ripple .mat-ripple-element {
background-color: mat-color($warn, 0.26);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/lib/checkbox/checkbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@
<div md-ripple *ngIf="!_isRippleDisabled()" class="mat-checkbox-ripple"
[mdRippleTrigger]="_getHostElement()"
[mdRippleCentered]="true"
[mdRippleSpeedFactor]="0.3"
mdRippleBackgroundColor="rgba(0, 0, 0, 0)"></div>
[mdRippleSpeedFactor]="0.3"></div>
<div class="mat-checkbox-frame"></div>
<div class="mat-checkbox-background">
<svg version="1.1"
Expand Down
4 changes: 2 additions & 2 deletions src/lib/core/option/option.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<ng-content></ng-content>
<div class="mat-option-ripple" *ngIf="!disabled" md-ripple mdRippleBackgroundColor="rgba(0,0,0,0)"
[mdRippleTrigger]="_getHostElement()"></div>
<div class="mat-option-ripple" *ngIf="!disabled" md-ripple [mdRippleTrigger]="_getHostElement()">
</div>
4 changes: 1 addition & 3 deletions src/lib/core/ripple/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ Properties:
| --- | --- | --- |
| `mdRippleTrigger` | Element | The DOM element that triggers the ripple when clicked. Defaults to the parent of the `md-ripple`.
| `mdRippleColor` | string | Custom color for foreground ripples
| `mdRippleBackgroundColor` | string | Custom color for the ripple background
| `mdRippleCentered` | boolean | If true, the ripple animation originates from the center of the `md-ripple` bounds rather than from the location of the click event.
| `mdRippleMaxRadius` | number | Optional fixed radius of foreground ripples when fully expanded. Mainly used in conjunction with `unbounded` attribute. If not set, ripples will expand from their origin to the most distant corner of the component's bounding rectangle.
| `mdRippleRadius` | number | Optional fixed radius of foreground ripples when fully expanded. Mainly used in conjunction with `unbounded` attribute. If not set, ripples will expand from their origin to the most distant corner of the component's bounding rectangle.
| `mdRippleUnbounded` | boolean | If true, foreground ripples will be visible outside the component's bounds.
| `mdRippleFocused` | boolean | If true, the background ripple is shown using the current theme's accent color to indicate focus.
| `mdRippleDisabled` | boolean | If true, click events on the trigger element will not activate ripples. The `start` and `end` methods can still be called to programmatically create ripples.
54 changes: 6 additions & 48 deletions src/lib/core/ripple/_ripple.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
@import '../theming/theming';


$mat-ripple-focused-opacity: 0.1;
$mat-ripple-background-fade-duration: 300ms;
$mat-ripple-background-default-color: rgba(0, 0, 0, 0.0588);
$mat-ripple-foreground-initial-opacity: 0.25;
$mat-ripple-foreground-default-color: rgba(0, 0, 0, 0.0588);

$mat-ripple-element-color: rgba(0, 0, 0, 0.1);

@mixin mat-ripple() {
// The host element of an md-ripple directive should always have a position of "absolute" or
Expand All @@ -19,55 +13,19 @@ $mat-ripple-foreground-default-color: rgba(0, 0, 0, 0.0588);
overflow: visible;
}

.mat-ripple-background {
background-color: $mat-ripple-background-default-color;
opacity: 0;
transition: opacity $mat-ripple-background-fade-duration linear;
.mat-ripple-element {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}

.mat-ripple-unbounded .mat-ripple-background {
display: none;
}

.mat-ripple-background.mat-ripple-active {
opacity: 1;
}

.mat-ripple-focused .mat-ripple-background {
opacity: 1;
}

.mat-ripple-foreground {
background-color: $mat-ripple-foreground-default-color;
border-radius: 50%;
pointer-events: none;
opacity: $mat-ripple-foreground-initial-opacity;
position: absolute;
// The transition duration is manually set based on the ripple size.
transition: opacity, transform 0ms cubic-bezier(0, 0, 0.2, 1);
}

.mat-ripple-foreground.mat-ripple-fade-in {
opacity: 1;
}
background-color: $mat-ripple-element-color;

.mat-ripple-foreground.mat-ripple-fade-out {
opacity: 0;
transition: opacity, transform 0ms cubic-bezier(0, 0, 0.2, 1);
transform: scale(0);
}
}

@mixin mat-ripple-theme($theme) {
$accent: map-get($theme, accent);

.mat-ripple-focused .mat-ripple-background {
background-color: mat-color($accent, $mat-ripple-focused-opacity);
}
}
@mixin mat-ripple-theme($theme) {}


// A mixin, which generates temporary ink ripple on a given component.
Expand Down
Loading

0 comments on commit 6381948

Please sign in to comment.