Exclusivo

Wind Text <mv-wind-text>

Texto cujas letras se comportam como grama (ou uma bandeira) num único campo de vento compartilhado por toda a página: a rolagem envia rajadas cuja frente varre o texto no sentido da rolagem, o cursor sopra localmente numa grade de velocidades advectada que se dissipa, cada letra se curva sobre a linha de base com a própria mola e alguns grãos de pólen levantam voo onde o vento sopra.

CategoriaTexto animado
TipoWeb Component (<mv-wind-text>)
Statusestável
Keywordsexclusive, wind, text, typography, scroll, cursor, spring, fluid, particles, pollen, editorial, headline

When to use

  • An editorial headline should sway like grass or a flag in response to scroll and cursor
  • An organic or nature brand wants a gentle ambient breeze with drifting pollen

Avoid when

  • The text contains links or buttons; they are flattened to plain text
  • Long paragraphs at full strength; swaying letters hurt reading, so keep strength low or skip it

Instalação

node scripts/add.mjs wind-text --out ./src/marvelous

Agente de IA com o servidor MCP do Marvelous UI: install_components({ slugs: ["wind-text"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Arquivos copiados (dependências incluídas): tokens/tokens.css, core/base.css, core/canvas.js, core/dom.js, core/element.js, core/i18n.js, core/motion.js, core/observe.js, components/wind-text/wind-text.js, components/wind-text/wind-text.css.

Uso

Marcação de referência, para usar como ponto de partida e personalizar com atributos, data-* e variáveis CSS:

<section id="wind-demo" class="wt-hero" lang="en">
  <style>
    .wt-hero { position: relative; overflow: hidden; width: min(100%, 64rem); margin-inline: auto; padding: clamp(2rem, 1rem + 5vw, 4.5rem) clamp(1.25rem, 1rem + 4vw, 4rem) 3rem; border-radius: var(--mv-radius-2xl); border: 1px solid var(--mv-border);
      background:
        radial-gradient(120% 70% at 85% 110%, color-mix(in oklch, var(--mv-success) 16%, transparent), transparent 60%),
        radial-gradient(90% 60% at 0% 0%, color-mix(in oklch, var(--mv-warning) 12%, transparent), transparent 65%),
        var(--mv-surface);
      font-family: var(--mv-font-sans); }
    .wt-kicker { margin: 0 0 1.25rem; display: flex; gap: .625rem; align-items: center; font-size: var(--mv-text-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--mv-fg-muted); font-weight: var(--mv-weight-semibold); }
    .wt-kicker::before { content: ""; width: 1.75rem; height: 1px; background: currentColor; opacity: .6; }
    .wt-title { margin: 0; max-width: 15ch; font-size: clamp(2.75rem, 1.5rem + 5.2vw, 5.25rem); line-height: 1.02; letter-spacing: -0.035em; font-weight: 800; color: var(--mv-fg); text-wrap: balance; }
    .wt-title em { font-style: normal; color: color-mix(in oklch, var(--mv-success) 78%, var(--mv-fg)); }
    .wt-lede { margin: 1.5rem 0 0; max-width: 40rem; font-size: var(--mv-text-lg); line-height: 1.6; color: var(--mv-fg-muted); }
    .wt-actions { margin-top: 2rem; display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
    .wt-hint { margin-left: auto; font-size: var(--mv-text-xs); color: var(--mv-fg-subtle); }
    .wt-meadow { position: absolute; inset: auto 0 0 0; height: 5rem; pointer-events: none; opacity: .5;
      background: repeating-linear-gradient(90deg, color-mix(in oklch, var(--mv-success) 30%, transparent) 0 1px, transparent 1px 9px);
      mask-image: linear-gradient(to top, #000, transparent); }
  </style>
  <p class="wt-kicker">Highland Seed Co. · Spring 2026 catalog</p>
  <h2 class="wt-title"><mv-wind-text strength="1.25" pollen="26">Sow to every <em>wind.</em></mv-wind-text></h2>
  <p class="wt-lede"><mv-wind-text strength="0.55" pollen="8">Open-pollinated heirloom seeds, grown without chemicals in the Vermont hills. Every packet saves an old variety from oblivion: Brandywine tomato, scarlet runner bean, bearded Red Fife wheat.</mv-wind-text></p>
  <div class="wt-actions">
    <a class="mv-button" href="#wind-demo">Browse the catalog</a>
    <button class="mv-button" data-variant="outline" type="button" data-gust>Make it blow</button>
    <span class="wt-hint">Move your mouse or scroll</span>
  </div>
  <div class="wt-meadow" aria-hidden="true"></div>
</section>
<script type="module">
  const root = document.getElementById("wind-demo");
  const { gust } = await customElements.whenDefined("mv-wind-text");
  let dir = 1;
  root.querySelector("[data-gust]").addEventListener("click", () => { gust(1.3, dir); dir = -dir; });
  // A first gust on arrival so the idea reads instantly.
  setTimeout(() => gust(1.1, 1), 350);
</script>

API

Attributes

NameTipoPadrãoDescrição
variantgrass | flaggrassgrass: each letter bends and sways around its base; flag: a wave runs along the line like a pennant.
strengthnumber1Letter flexibility (0 to 3): 0.5 for a paragraph, 1.2 for a big headline.
pollennumber18Maximum number of pollen/dust grains in flight (0 = none).
breezenumber0Constant ambient breeze (0 to 1). Above 0, the animation runs as long as the text is visible.

Methods

NameDescrição
gust(strength = 1, direction = 1)Sends a gust across every instance (direction 1 → right, −1 → left). Also available as a static: MvWindText.gust().

Content structure

NameDescrição
(text)Plain text; inline tags (em, strong, span) are kept visually, links and buttons are flattened to text.

CSS classes

NameDescrição
mv-wind-text-word / -charGenerated words (non-breaking) and letters; letters pivot near the baseline (transform-origin 50% 84%).
mv-wind-text-canvasPollen canvas, overflowing by 64 px.

CSS variables

NamePadrãoDescrição
--mv-wind-text-pollenvar(--mv-warning)Pollen grain color.

Accessibility

The text is exposed only once, through a visually hidden copy; the animated letters and the canvas are aria-hidden, purely decorative, with no interaction required. One wind field, one loop and passive listeners for the whole page; the loop stops as soon as the air is calm and the letters are upright, and only computes visible instances. On touch devices, only scrolling blows. Reduced motion: no animation, letters stay still and perfectly readable. Forced colors: the pollen canvas is hidden. Known limits: the text is read once, on first connection (to change it, render a new element, for example with a key in your framework); links and buttons inside are flattened to plain text, and inline formatting is not announced by screen readers (the hidden copy is plain text).

Esta página foi traduzida com IA. Informar um problema de tradução