Перейти к содержимому

Текстуры

ASCII-свайп

Переход между двумя панелями интерфейса с акцентным ASCII-следом Opensophy.


ASCII-свайп

AsciiSweep выполняет переход между двумя HTML-панелями: движущаяся полоса ASCII-символов проявляет целевую панель и скрывает исходную. Эффект рисуется на WebGL2, а содержимое панелей остаётся обычной разметкой Svelte.

Интерактивное демо

Настройте переход прямо здесь: длительность, направление, ширину полосы, размер и набор символов, свечение и цвет свайпа. По умолчанию в демо используется фирменный розовый Opensophy.

OPENSOPHY / WORKFLOW
Люди принимают решения.

Общая рабочая область для обсуждения, проверки и совместного создания.

СозданиеВручную
ДоступПо ролям
OPENSOPHY / IGNITION
Идея становится действием.

Огненная карточка — акцентный режим для важных событий, смелых решений и быстрых запусков.

ЭнергияВысокая
СтатусЗапущено

Пропсы

Длительность
2.000с
Угол перехода
0°
Ширина полосы
0.280
Размер символов
2.000px
Цвет свайпа
Набор символов
Свечение
1.200
<script lang="ts">
  import AsciiSweep from "$lib/components/ui-registry/AsciiSweep.svelte";
  let index = 0;
</script>

<button onclick={() => (index = index === 0 ? 1 : 0)}>Switch panel</button>

<AsciiSweep {index} duration={2} color="#ff315b">
  {#snippet children()}<div>First panel</div>{/snippet}
  {#snippet alternate()}<div>Second panel</div>{/snippet}
</AsciiSweep>
<script lang="ts">
  import AsciiSweep from "$lib/components/ui-registry/AsciiSweep.svelte";
  let index = 0;
</script>

<button onclick={() => (index = index === 0 ? 1 : 0)}>Switch panel</button>

<AsciiSweep {index} duration={2} color="#ff315b">
  {#snippet children()}<div>First panel</div>{/snippet}
  {#snippet alternate()}<div>Second panel</div>{/snippet}
</AsciiSweep>

Использование

Две панели и переключение

Передайте основной контент через snippet children, второй — через alternate. Свойство index задаёт целевую панель: 0 или 1.

<script lang="ts">
	import AsciiSweep from '$lib/components/ui-registry/AsciiSweep.svelte';
	let index = 0;
</script>

<button onclick={() => (index = index === 0 ? 1 : 0)}>Переключить панель</button>

<AsciiSweep {index} duration={2} color="#74f7a1">
	{#snippet children()}<div>Первая панель</div>{/snippet}
	{#snippet alternate()}<div>Вторая панель</div>{/snippet}
</AsciiSweep>
<script lang="ts">
	import AsciiSweep from '$lib/components/ui-registry/AsciiSweep.svelte';
	let index = 0;
</script>

<button onclick={() => (index = index === 0 ? 1 : 0)}>Переключить панель</button>

<AsciiSweep {index} duration={2} color="#74f7a1">
	{#snippet children()}<div>Первая панель</div>{/snippet}
	{#snippet alternate()}<div>Вторая панель</div>{/snippet}
</AsciiSweep>

Направление и визуальные параметры

<AsciiSweep {index} angle={90} duration={1.6} band={0.32} softness={0.45} turbulence={0.5} trail={0.75} scale={2} charset="blocks" color="#ff315b" glow={1.2} tint={0.8} background="var(--background)">
	{#snippet children()}<div>Исходное содержимое</div>{/snippet}
	{#snippet alternate()}<div>Целевое содержимое</div>{/snippet}
</AsciiSweep>
<AsciiSweep {index} angle={90} duration={1.6} band={0.32} softness={0.45} turbulence={0.5} trail={0.75} scale={2} charset="blocks" color="#ff315b" glow={1.2} tint={0.8} background="var(--background)">
	{#snippet children()}<div>Исходное содержимое</div>{/snippet}
	{#snippet alternate()}<div>Целевое содержимое</div>{/snippet}
</AsciiSweep>

Ручное управление прогрессом

Задайте progress в диапазоне 0–1, чтобы управлять положением перехода извне. Значение -1 (по умолчанию) включает автоматическую анимацию по duration.

<AsciiSweep {index} progress={progress} duration={2}>
	{#snippet children()}<div>Панель A</div>{/snippet}
	{#snippet alternate()}<div>Панель B</div>{/snippet}
</AsciiSweep>
<AsciiSweep {index} progress={progress} duration={2}>
	{#snippet children()}<div>Панель A</div>{/snippet}
	{#snippet alternate()}<div>Панель B</div>{/snippet}
</AsciiSweep>

Пропсы

Переход

Пропс Тип По умолчанию Описание
index 0 | 1 0 Индекс целевой панели. Изменение запускает переход
angle number 0 Направление в градусах: 0 — слева направо, 90 — снизу вверх
duration number 2 Длительность перехода в секундах
progress number -1 Ручной прогресс от 0 до 1; -1 включает автоматическую анимацию
band number 0.28 Ширина полосы относительно пути (0–1)
softness number 0.45 Мягкость краёв полосы (0–1)
turbulence number 0.5 Неровность края, усиливает разрывы по строкам
trail number 0.75 Длина светящегося следа относительно полосы

Символы и свечение

Пропс Тип По умолчанию Описание
scale number 2 Размер пикселя символа в CSS-пикселях; глифы имеют сетку 5×5
spacing number 1 Пустой отступ вокруг символа (0–3)
charset ‘ascii’ | ‘blocks’ | ‘binary’ ascii Встроенный набор символов
glyphs number[] [] Пользовательский набор упакованных 5×5 bitmap-глифов; переопределяет charset
color string #4ade80 Цвет символов в любом CSS-формате; демо использует фирменный розовый #ff315b
tint number 0.75 Сила замены исходного цвета цветом символов (0–1)
glow number 2 Интенсивность фосфорного свечения (0–2)
aberration number 5 Хроматическое смещение в CSS-пикселях
flicker number 0.35 Интенсивность мерцания символов (0–1)
density number 0.9 Доля ячеек, загорающихся внутри полосы (0–1)

Обработка изображения

Пропс Тип По умолчанию Описание
displace number 14 Горизонтальное смещение строк в CSS-пикселях
contrast number 1.2 Контраст перед выбором глифа
brightness number 0 Смещение плотности перед выбором глифа (-1–1)
invert number 0 Инверсия плотности символов (0–1)
threshold number 0.1 Порог контраста для определения деталей
fade number 0.75 Насколько затемняется содержимое под полосой (0–1)
blend ‘auto’ | ‘add’ | ‘over’ auto Режим наложения: авто, аддитивный или поверх изображения
background string auto Цвет фона под содержимым или auto для чтения из DOM

События и атрибуты

Пропс Тип По умолчанию Описание
onSweepStart (to: number) => void — Вызывается при начале перехода
onSweepEnd (to: number) => void — Вызывается, когда целевая панель полностью показана
class string — Дополнительные CSS-классы контейнера

Instance API

Через bind:this можно получить экземпляр и управлять эффектом программно.

<script lang="ts">
	import AsciiSweep from '$lib/components/ui-registry/AsciiSweep.svelte';
	import type { AsciiSweepInstance } from '$lib/components/ui-registry/AsciiSweep.svelte';
	let sweep: AsciiSweepInstance;
</script>

<AsciiSweep bind:this={sweep} index={0}>
	{#snippet children()}<div>Первая панель</div>{/snippet}
	{#snippet alternate()}<div>Вторая панель</div>{/snippet}
</AsciiSweep>

<button onclick={() => sweep?.sweep(1, { angle: 90 })}>Показать вторую</button>
<button onclick={() => sweep?.capture()}>Обновить снимки</button>
<script lang="ts">
	import AsciiSweep from '$lib/components/ui-registry/AsciiSweep.svelte';
	import type { AsciiSweepInstance } from '$lib/components/ui-registry/AsciiSweep.svelte';
	let sweep: AsciiSweepInstance;
</script>

<AsciiSweep bind:this={sweep} index={0}>
	{#snippet children()}<div>Первая панель</div>{/snippet}
	{#snippet alternate()}<div>Вторая панель</div>{/snippet}
</AsciiSweep>

<button onclick={() => sweep?.sweep(1, { angle: 90 })}>Показать вторую</button>
<button onclick={() => sweep?.capture()}>Обновить снимки</button>
Метод Описание
setOptions(options: AsciiSweepOptions) Обновить параметры эффекта на лету
sweep(to: 0 или 1, options?) Перейти к панели 0 или 1; можно переопределить угол для одного перехода
current() Вернуть панель, на которой эффект остановился или к которой движется
capture() Повторно захватить содержимое обеих панелей
resize() Повторно измерить размеры canvas
destroy() Остановить цикл и освободить ресурсы GPU

Ограничения

  • Для точного захвата DOM в Canvas требуется экспериментальный HTML-in-Canvas API в браузере Chrome. Если он недоступен, компонент использует упрощённый fallback через Canvas 2D.
  • Компонент рассчитан на две панели. Содержимое слотов должно иметь определённые размеры, чтобы его можно было корректно захватить.
  • Эффект использует WebGL2; на устройствах без WebGL2 полноценный шейдерный переход недоступен.
  • Учитывайте стоимость захвата сложной DOM-разметки и медиа. Для стабильного результата задавайте панелям явные размеры.