Components/BaseSurface

BaseSurface

A background layer with switchable materials and motion fallback.

VerifiedSince 0.3.4

Usage

Modes

mode picks the material: refraction (the default), glass, acrylic, blur backdrop blur, mask translucent overlay, mica, pure solid (flat is an alias), or plain, which paints no material. Each material's pipeline and cost are in Surface 8-Material Taxonomy & Gatekeepers.

Loading demo...

Advanced Lab

filter* props tune the filter layer, refraction* props the refraction layer, and preset="card" applies the card tuning.

Loading demo...

Fake Mode

fake paints the background on a pseudo-element, matching the existing .fake-background layering; slot content sits above it naturally. Under pure (flat) that base is opaque and under mask it follows the mask opacity; under blur, acrylic, glass and refraction it sits beneath the material at opacity, so the page behind still shows through to be blurred and refracted; mica paints its own opaque base and plain paints nothing, so neither takes it.

Loading demo...

Motion Fallback

When a surface moves with its element, backdrop-filter samples lag behind the element's position, and the filter layers drag a misaligned patch of backdrop along. With moving set, blur, glass and acrylic degrade to fallbackMode and recover smoothly when it stops; refraction keeps its mode and fades its filter layers out, then back in once it stops.

Loading demo...

Raw vs BaseSurface

When the motion state isn't available, turn on autoDetect and the surface senses motion itself (see the next section).

Loading demo...

Environment sensing

With autoDetect on, the surface combines five runtime signals: transforms on itself and its ancestors, the speed of a pressed pointer (above 1.2px/ms), window moves and resizes, a frame-budget probe, and power saving. The first three trigger the motion fallback, which starts to recover 140ms after the signal stops; under power saving or a reduced frame budget, refraction, glass and acrylic become blur, and under minimal they and blur become flat, returning to the declared material once the condition clears. How each signal is read is in Adaptive Surface Deduction & 120Hz Fallback.

A page receives no event when its window moves, so the host forwards one; a host that knows the power state can override the battery API's reading:

import { notifySurfaceWindowMotion, setSurfacePowerSaving } from '@talex-touch/tuffex'

// Once per BrowserWindow move (and will-move) event the main process relays to the renderer
notifySurfaceWindowMotion()

// From Electron's powerMonitor, say; null hands it back to the Battery Status API
setSurfacePowerSaving(true)

Flow light

flowLight lays a fixed brand-colour light (FlowLight) over the veil and under the edge, in any mode.

Loading demo...

System backdrop

A transparent Electron window lets the desktop show through its own system material (vibrancy on macOS, Mica on Windows), and a page's backdrop-filter cannot reach that material: the filter samples only the surface's own veil and lays the copy over that veil, so a 75% veil stacked twice is all but opaque and the desktop no longer shows through. systemBackdrop runs no backdrop-filter on the surface: the glass layer doesn't render and the filter layer keeps only its tint, leaving the blur to the system; the veil, mask, flow light and rim draw as usual. With nothing sampled from the page, moving and autoDetect have no effect either.

<!-- core-app's CoreBox: a transparent window, its surface over the system material -->
<TxBaseSurface system-backdrop fake color="var(--tx-fill-color)" :opacity="0.75" />

Best Practices

  • Prefer TxCard for product containers, since it owns container semantics and interaction; use TxBaseSurface only to tune material, fallback, or refraction directly.
  • Pass moving when the parent owns the animation state; use autoDetect only for motion whose state you can't reach, or to switch to a lighter material under power saving and dropped frames.
  • Keep fallbackMode="mask" so blur / glass / acrylic content stays readable in motion; use pure only when a flat color is acceptable.
  • Tune refraction through refractionStrength, refractionProfile, and refractionTone; keep RGB channel offsets for visual experiments.
  • Use refractionRenderer="css" only where its lower optical fidelity is acceptable.

API Reference

Props

PropTypeDefaultDescription
mode'pure' | 'mask' | 'blur' | 'glass' | 'refraction' | 'acrylic' | 'mica' | 'flat' | 'plain''refraction'Material: refraction, glass, acrylic, backdrop blur, mask, mica, solid (flat is the same as pure), or no material.
radiusstring | number-Corner radius; inherits from the parent when unset.
colorstring-Base color for the solid and mask layers, the acrylic tint and the mica base.
opacitynumber0.75Opacity in mask mode (0–1); acrylic's tint takes 0.8 of it; in fake mode, also the opacity of the base colour under the blur / acrylic / glass / refraction material.
fallbackMaskOpacitynumber-Opacity when degraded to mask (0–1).
blurnumber10Filter-layer blur radius in px; acrylic takes three times it.
filterSaturationnumber1.5Filter-layer saturation.
filterContrastnumber1Filter-layer contrast.
filterBrightnessnumber1Filter-layer brightness.
saturationnumber1.8Glass-layer saturation for glass and refraction.
brightnessnumber70Glass-layer brightness for glass and refraction; <= 3 is read as a multiplier.
backgroundOpacitynumber0Background opacity of the glass layer.
borderWidthnumber0.07Edge width factor of the glass layer.
displacenumber0.5Refraction displacement amount.
distortionScalenumber-180Refraction distortion scale.
redOffset / greenOffset / blueOffsetnumber0 / 10 / 20RGB channel offsets that control dispersion.
xChannel / yChannel'R' | 'G' | 'B''R' / 'G'Channels sampled by the displacement map.
mixBlendModestring'difference'Refraction blend mode.
refractionStrengthnumber62Refraction strength, 0–100.
refractionProfile'soft' | 'filmic' | 'cinematic''filmic'Refraction style preset.
refractionTone'mist' | 'balanced' | 'vivid''balanced'Refraction tone: vivid is clearer, mist softer.
refractionAnglenumber-24Main dispersion angle in degrees.
refractionLightX / refractionLightYnumber-Light anchor (0–1).
refractionHaloOpacitynumber-Halo opacity (0–1); the built-in filmic model applies when unset.
overlayOpacitynumber0Extra mask opacity for non-mask modes.
flowLight'corners' | 'rim' | 'aurora' | false-The flow light's variant; absent or false is off, any mode can have it.
flowLightIntensitynumber1Flow light strength, multiplying the theme opacity.
preset'default' | 'card''default'Visual preset; card applies the card tuning.
refractionRenderer'svg' | 'css''svg'Refraction renderer.
systemBackdropbooleanfalseThe surface sits on the window's own system material (vibrancy or Mica in a transparent Electron window): it runs no backdrop-filter and leaves the blur to the system; moving and autoDetect have no effect.
movingbooleanfalseMarks the surface as moving, which triggers the fallback.
fallbackMode'pure' | 'mask' | 'flat''mask'Mode used while moving; flat is the same as pure.
settleDelaynumber150Delay in ms before recovery after motion ends; never shorter than transitionDuration.
autoDetectbooleanfalseDegrades by environment: falls back in motion when the surface or an ancestor transforms, a pressed pointer moves fast, or the window moves or resizes; switches to a lighter material under power saving or dropped frames.
transitionDurationnumber299Recovery transition duration in ms.
fakebooleanfalseRenders the background on a pseudo-element.
fakeIndexnumber0z-index of the pseudo-element layer.
tagstring'div'Root element tag.

Slots

SlotPropsDescription
default-Surface content, rendered in .tx-base-surface__content above every material layer.

CSS Variables

VariableSourceDescription
--tx-surface-colorcolor prop or theme fallbackSolid, mask, acrylic tint and mica base color; defaults to var(--tx-fill-color-lighter, #fafafa).
--tx-surface-radiusradius propRadius of the root and every layer; numbers become px.
--tx-surface-transitiontransitionDuration propDuration of layer fades, background, and backdrop-filter transitions.
--tx-surface-filter-blurblur propBlur radius of the filter and refraction filter layers.
--tx-surface-filter-saturationfilterSaturation propFilter-layer saturation multiplier.
--tx-surface-filter-contrastfilterContrast propFilter-layer contrast multiplier.
--tx-surface-filter-brightnessfilterBrightness propFilter-layer brightness multiplier.
--tx-surface-mask-opacityopacity, fallbackMaskOpacity, or overlayOpacityCurrent mask opacity, clamped to 0..1.
--tx-surface-refraction-light-x / --tx-surface-refraction-light-yrefractionLightX / refractionLightY or angle modelRefraction light anchor in percent.
--tx-surface-refraction-strengthrefractionStrength modelOptical strength blended across rest, motion, and recovery.
--tx-surface-fake-indexfakeIndex propz-index of the pseudo-element layer.
--tx-surface-fake-bgcolor prop or theme fallbackBackground color of the pseudo-element.
--tx-surface-fake-opacity1 under pure and flat, 0 under mica and plain, the mask opacity under mask, opacity otherwiseOpacity of the pseudo-element.
--tx-surface-mask-opacity-percentmask opacity modelMask opacity as a percentage (internal; do not override).
--tx-surface-motion-cover-opacitymotion state modelOpacity of the refraction motion cover (internal).
--tx-surface-refraction-edge-opacityoptics modelOpacity of the refraction edge highlight (internal).
--tx-surface-refraction-streak-anglerefractionAngle modelRefraction streak angle, the angle plus 92deg (internal).
--tx-surface-refraction-{filter,mask}-{base,primary,secondary,veil}-weight / --tx-surface-refraction-streak-weightprofile/tone weight modelBlend weights of the optical layers (internal).
--tx-surface-refraction-*-gain / -boost / -base, --tx-surface-refraction-halo-opacity, --tx-surface-refraction-mask-effective-opacityprofile/tone derived valuesDerived outputs of the optical interpolation (internal).
--tx-surface-refraction-mask-colortheming hook (consumed)Base color of the refraction gradients; override it in themes (defaults to #fff shades).
--tx-surface-mica-primary-weight / --tx-surface-mica-harmonic-weighttheming hook (consumed)Strength of mica's brand glow at the top left and its neighbouring-hue glow at the bottom right; 12% / 8% by default.
--tx-surface-mica-harmonicthe brand hue +40°The neighbouring hue of mica's bottom-right glow; the brand itself where relative colour syntax is unsupported (internal).

Environment API

Import from @talex-touch/tuffex.

ExportSignatureWhen to use
notifySurfaceWindowMotion()() => voidCall it as the host forwards window moves; the window counts as still once 140ms pass without a call.
setSurfacePowerSaving(value)(value: boolean | null) => voidOverrides the power-saving reading from the host; null hands it back to the Battery Status API (not charging, at or below 20%).
getSurfaceEnvironment()() => { pointerMoving, windowMoving, powerSaving, frameTier }Reads the page's current environment as read-only refs; frameTier is 'ok' | 'reduced' | 'minimal'.
useSurfaceMotionGuard(emitFallback, options?)(emitFallback: (isFallback: boolean) => void, { settleMs? }) => { onMotionStart, onMotionEnd, dispose }For hosts that know when they move: drives moving with the asymmetric clock, calling back true at once on start and false after settleMs (140ms by default) of quiet.
SURFACE_POINTER_SPEED_THRESHOLD / SURFACE_MOTION_SETTLE_MS / SURFACE_LOW_BATTERY_LEVEL1.2 / 140 / 0.2The pointer speed threshold (px/ms), how long a motion signal stays quiet before it ends (ms), and the low-battery level.

Overview

  • pure and flat render only the root background; mask renders a mask layer with opacity clamped to 0..1; acrylic is a filter layer blurring three times as wide under a tint whose alpha carries fractal noise; mica paints the root with an opaque base and two glows anchored to the viewport (background-attachment: fixed), reading no backdrop but repainting with every scroll of its container, so keep it off bases that scroll; plain keeps only the radius and the overflow clip.
  • blur, glass and acrylic degrade while moving is set or autoDetect senses motion: fallbackMode="mask" prefers fallbackMaskOpacity, and pure and flat render no mask layer.
  • refraction keeps its mode in motion: the glass / blur layers that lose their sampling fade out, a translucent motion cover holds the weight, and both cross-fade back on settle.
  • Passing any of refractionStrength, refractionAngle, or refractionProfile switches to the derived refraction model; unset ones fall back to 62 / -24 / 'filmic'.
  • autoDetect listens on the root and every ancestor for their own transform / translate transitions (transitionstart / transitionend / transitioncancel) and watches their inline style with a MutationObserver; the pointer, window, frame-probe and battery listeners are page-wide, shared by every surface with autoDetect, and removed when the last one unmounts.
  • With systemBackdrop, the glass layer doesn't render and the filter layer's backdrop-filter is none, keeping its tint; neither the motion fallback nor environment sensing runs. The veil, mask, flow light and rim are unaffected.
  • Under high contrast (triggers in Theming), every mode but plain paints only the opaque root background, like pure: the glass, blur, mask, motion-cover and refraction-edge layers don't render, and the fake base shows at full opacity; plain gets no fill even then.

Technologies

  • Glass and refraction render through TxGlassSurface; fallback timing lives in base-surface-motion.ts, and the page-wide environment sensing and material degradation in surface-environment.ts.
  • Source: packages/tuffex/packages/components/src/base-surface/.
查看源码
packages/tuffex/packages/components/src/base-surface/index.ts