LineArt

A geometric drawing in faint hairlines, for a banner, an empty state or a header.

BetaSince 1.0.0
On this page

Import

import { LineArt } from '@envsemble/envui';

Usage

drawing names one of the sixteen drawings, listed in order as lineArtDrawings, such as golden-section. The drawing fills its container's box: the box sets its size and shape, and the drawing covers it.

ProjectBanner.tsx
import { LineArt, PageHeader, Surface } from '@envsemble/envui';

export default function ProjectBanner() {
  return (
    // The banner holds the drawing at its end, across about half its width; the header stays
    // above it, and its text keeps to the start.
    <Surface
      background="default"
      padding={6}
      style={{ position: 'relative', overflow: 'hidden', inlineSize: '100%' }}
    >
      <LineArt
        drawing="golden-section"
        style={{ position: 'absolute', insetBlock: 0, insetInlineEnd: 0, inlineSize: '48%' }}
      />
      <PageHeader
        title="Website refresh"
        headingLevel={3}
        description="New pages, faster search and a lighter look, due in March."
        style={{ position: 'relative', maxInlineSize: '50%' }}
      />
    </Surface>
  );
}

align is end, the default, start or center: where the drawing sits as its box crops it, as preserveAspectRatio with slice on a sheet of 480 by 330. Right to left, the drawing is mirrored. label makes it role="img", named by the label; without one it is aria-hidden.

The drawings

DrawingIn code
Golden sectiongolden-section
Square, circle, trianglesquare-circle-triangle
Whirling squareswhirling-squares
Triangle and circlestriangle-and-circles
Ford circlesford-circles
Harmonic divisionharmonic-division
Pappus chainpappus-chain
Root rectanglesroot-rectangles
Sacred cutsacred-cut
Gothic tracerygothic-tracery
Quartered squarequartered-square
Graded quadtreegraded-quadtree
Monochordmonochord
Logarithmic gridlogarithmic-grid
Pointed arcadepointed-arcade
Root-two halvingroot-two-halving

Motion

motion moves the drawing's lines, one beat after another in the order of its construction, as it mounts or as motion changes; without it, the drawing is still.

  • appear draws the lines in, from nothing to the whole drawing, the lines that frame it first.
  • disappear draws them out, from the whole drawing to nothing, the other way round, and leaves nothing drawn.
  • loop draws them in, holds the drawing whole a moment, and draws them out, for as long as it is set; each turn begins where the last one ends, with nothing drawn.
  • play runs each line out past its end and draws it in again, the drawing whole throughout, and ends on the still.

onMotionEnd is called once appear, disappear or play has finished, such as to unmount a drawing that has disappeared, or to play it again by setting motion to undefined and back. Where reduced motion is preferred, it is called at once.

function EmptyStateArt({ leaving, onGone }: { leaving: boolean; onGone: () => void }) {
  return (
    <LineArt
      drawing="pappus-chain"
      motion={leaving ? 'disappear' : 'appear'}
      onMotionEnd={() => {
        if (leaving) onGone();
      }}
    />
  );
}

A drawing for each screen

To vary the drawing between screens and keep it the same on each, pick it by the screen's place in the application's order. Neighbours never share a drawing, and none recurs within sixteen screens.

const drawing = lineArtDrawings[screenIndex % lineArtDrawings.length]!;

Composition

In a banner or a header, give the drawing a box at the end and keep the text above it: the container is positioned and clips, the drawing is placed absolutely across part of it, such as inset-block: 0; inset-inline-end: 0; inline-size: 48%, and the text after it is positioned so it paints over the drawing. Keep the text clear of the drawing, such as with a max-inline-size.

Customize

The root is env-line-art, an SVG with data-drawing and data-align, whose shapes draw with stroke: var(--env-color-border-muted), stroke-width: 1px and vector-effect: non-scaling-stroke, and stroke: GrayText in forced colors. Its width and height are its box's, 100% of its container by default; set them, or its style, to place it.

In motion, the root also has data-motion, and data-turn, in or out, in a loop. A motion takes --env-line-art-duration, calc(var(--env-motion-duration-slow) * 10) by default, and play half as long again; set it on the drawing to slow it down or speed it up. Each line is a dash of pathLength="1", moved by stroke-dashoffset, so nothing but the lines moves.

Words in code

WordsIn code
Line art<LineArt drawing="golden-section" />
Monochorddrawing="monochord", from lineArtDrawings
At the endalign="end", the default
At the startalign="start"
Centredalign="center"
Per screenlineArtDrawings[index % lineArtDrawings.length]
Describedlabel="…"
Appearingmotion="appear"
Disappearingmotion="disappear"
In and outmotion="loop"
Playingmotion="play"

Accessibility

You provide

  • A label only where the drawing is content, such as a figure about geometry.
  • The text around it, which keeps its contrast: never place it behind text.

envUI provides

  • aria-hidden="true" on the drawing, which takes no focus and no pointer.
  • With label, role="img" and aria-label, so it is read as an image of that name.
  • Where reduced motion is preferred, no motion: each shows where it ends at once, and a loop keeps the drawing whole.

Props

LineArt

A geometric drawing in hairlines that fills its container's box, for a banner's end, an empty state or the background of a header: its lines in the muted edge color in every theme, one device pixel wide at any size, and the system's gray text color in forced colors. It covers the box, resting on its foot and cropped from its start by default, and is hidden from assistive technology unless a label makes it an image. With `motion`, its lines draw themselves in, out, or in and out again.

PropTypeDescription
drawingrequired
LineArtDrawing
The drawing, one of lineArtDrawings, such as golden-section or harmonic-division.
alignDefault 'end'
'start''center''end'
Where the drawing sits in its box when the box's shape crops it: at the end, at the start or in the center, flipped in right-to-left text, as the drawing itself is. It is cropped from the other side, or from both, and always rests on the box's foot, cropped from its top.
label
string
What the drawing shows, for a drawing that is content rather than decoration: it makes the drawing an image named by it. Without it, the drawing is hidden from assistive technology.
motion
'appear''disappear''loop''play'
How the drawing moves as it mounts or as this changes, its lines one after another in the order of its construction: `appear` draws them in, from nothing to the whole drawing; `disappear` draws them out, from the whole drawing to nothing, where it stays; `loop` draws them in and out again for as long as it is set, ending each round where the next begins; and `play` runs each line out past its end and draws it in again, the drawing whole throughout, ending on the still. Without it, the drawing is still. Where reduced motion is preferred, the drawing shows where the motion ends at once, and stays whole for `loop`.
onMotionEnd
() => void
Called once `appear`, `disappear` or `play` has finished, at once where reduced motion is preferred, such as to unmount a drawing that has disappeared or to play it again later.

Also accepts the native props of <svg>, such as ref, className and aria-* attributes.

Part names

Each part's class and state attributes are public and versioned, for an application's CSS to style.

env-line-art
The drawing: an SVG of hairlines that fills its container's box.
data-align
center · end · start
data-drawing
ford-circles · golden-section · gothic-tracery · graded-quadtree · harmonic-division · logarithmic-grid · monochord · pappus-chain · pointed-arcade · quartered-square · root-rectangles · root-two-halving · sacred-cut · square-circle-triangle · triangle-and-circles · whirling-squares
data-motion
appear · disappear · loop · play
data-turn
in · out

Changelog

1.0.0

LineArt, sixteen geometric drawings in hairlines, with drawing, align and label, and lineArtDrawings; motion, appear, disappear, loop or play, and onMotionEnd.