AnimationAdded in v15.1

Ripple Grid

Grid lines behind your content that the pointer sends ripples through.

Installation

Import the class, and @use the entry point in your global styles: without it the component renders unstyled.

import { Component } from '@angular/core';
import { WrRippleGrid } from 'ngwr/bits/ripple-grid';

@Component({ imports: [WrRippleGrid] })
export class MyComponent {}
Angular adaptation of an effect by David Haz / reactbits.dev.

Playground

Put it in a positioned box; it fills that box. Press anywhere in it, or move the pointer over the content in front of it.

Content above the grid

<section style="position: relative; min-height: 18rem; overflow: hidden">
  <wr-ripple-grid
    [cellSize]="40"
    [lineWidth]="1"
    [strength]="10"
    [speed]="320"
    [decay]="1.4"
  />
  <h1 style="position: relative">Content above the grid</h1>
</section>

Customize

Cell size
40 px
Line width
1.00 px
Strength
10 px
Speed
320 px/s
Decay
1.4
Idle interval
0 ms
Ripple on move
Line colour
Ripple colour

On its own

An idle interval sends a ring out from the centre every so often, so the grid moves before anyone touches it. Here moves are ignored, a press still ripples, and the button keeps every click.

Make some waves

A ring leaves the centre on its own; a press anywhere sends another.

Get started
<section class="hero">
  <wr-ripple-grid [idleInterval]="2400" [rippleOnMove]="false" />
  <div class="hero__content">
    <h2>Make some waves</h2>
    <p>A ring leaves the centre on its own; a press anywhere sends another.</p>
    <wr-btn color="primary">Get started</wr-btn>
  </div>
</section>

<style>
  .hero { position: relative; min-height: 20rem; overflow: hidden; }
  .hero__content {
    position: relative;
    display: grid;
    place-items: center;
    align-content: center;
    gap: 1rem;
    min-height: 20rem;
    padding: 2rem;
    text-align: center;
  }
  .hero__content > * { margin: 0; }
</style>

Light only

A strength of 0 keeps every line straight and only lights it. Colours take any CSS colour, a theme token included, and follow the colour scheme.

<section style="position: relative; min-height: 12rem; overflow: hidden">
  <wr-ripple-grid rippleColor="var(--wr-color-success)" [strength]="0" [cellSize]="24" />
</section>

API

NameDescriptionTypeDefault
cellSizeDistance between grid lines (px), never under 12.number40
lineColorLine colour. Unset, it follows the theme.string | nullnull
rippleColorColour a line takes where a ripple passes. Unset, it follows the theme.string | nullnull
lineWidthLine width (px), never under 0.25.number1
strengthHow far a fresh ripple from a press bends the lines (px); a moving pointer bends them 40% as far. 0 only lights them; negative bends them inward. Never far enough to fold a line over: about 0.3 of a cell (11.7px at the default), shared by ripples that overlap.number10
speedHow fast a ripple travels outward (px per second). 0 keeps it where it started.number320
decayHow fast a ripple fades, per second: its strength is multiplied by e^-decay each second.number1.4
rippleOnMoveWhether a moving pointer leaves ripples behind it, and not only a press.booleantrue
idleIntervalMilliseconds between the ripples sent out from the centre on their own, never under 500. 0 sends none.number0

CSS variables

Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/bits/ripple-grid's own element.

VariableDefaultDeclared on
--wr-ripple-grid-cell-size40px.wr-ripple-grid
--wr-ripple-grid-line-colorvar(--wr-border-base).wr-ripple-grid
--wr-ripple-grid-line-width1px.wr-ripple-grid
--wr-ripple-grid-ripple-colorvar(--wr-color-primary).wr-ripple-grid

See also