<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://androman.pro/wp-content/themes/androman/assets/feed.xsl?ver=0.9.4" type="text/xsl"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ScrollTrigger &#8212; ANDROMAN.PRO</title>
	<atom:link href="https://androman.pro/tag/scrolltrigger/feed/" rel="self" type="application/rss+xml" />
	<link>https://androman.pro</link>
	<description>Независимый 1С-архитектор и AI-автоматизация корпоративных процессов: аудит, PoC на реальных данных, проверка качества и внедрение. · build 0.9.4</description>
	<lastBuildDate>Tue, 05 May 2026 11:57:19 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Cyberpunk reveal-анимации — полный тур по эффектам</title>
		<link>https://androman.pro/2026/04/30/cyberpunk-anim-demo/</link>
					<comments>https://androman.pro/2026/04/30/cyberpunk-anim-demo/#respond</comments>
		
		<dc:creator><![CDATA[Androman.pro]]></dc:creator>
		<pubDate>Wed, 29 Apr 2026 21:00:00 +0000</pubDate>
				<category><![CDATA[дев-лог]]></category>
		<category><![CDATA[лаборатория]]></category>
		<category><![CDATA[creative-code]]></category>
		<category><![CDATA[GSAP]]></category>
		<category><![CDATA[ScrollTrigger]]></category>
		<category><![CDATA[vibe-coding]]></category>
		<category><![CDATA[киберпанк]]></category>
		<guid isPermaLink="false">https://androman.pro/2026/04/30/cyberpunk-anim-demo/</guid>

					<description><![CDATA[Шесть scroll-анимаций для постов блога — decoder, glitch, scanline, CRT power-on, stutter, pin. Собрал всё в одном тест-посте чтобы посмотреть как живёт на реальном длинном контенте.]]></description>
										<content:encoded><![CDATA[<p>Пока делал блог, написал шесть анимаций для постов. Захотел посмотреть как они все вместе смотрятся на реальном длинном тексте — специально под это сделал этот пост. Ничего особенного, просто скролли вниз.</p>
<p>Шесть эффектов: символьный дешифратор на главном заголовке, цветовые помехи на подзаголовках, сканирующая линия на блоках кода, включение ЭЛТ-монитора на картинках, прерывистое появление параграфов и прилипающие заголовки при прокрутке. Почти каждый раздел ниже показывает что-то новое.</p>
<h2>01 / Установка соединения</h2>
<p><img decoding="async" alt="lava-orb WebGL preview" src="https://androman.pro/wp-content/themes/androman/assets/lab-previews/lava-orb.png"></p>
<p>Когда страница загружается, главный заголовок делает ту же штуку что и на главной <code>androman.pro</code> — символы из мусорной кучи (<code>█▓▒░#@$%&amp;*+=!?&gt;</code>) по одному встают на свои места, и каждый зафиксированный символ на мгновение вспыхивает голубым. Через ~1.5 секунды заголовок устаканивается с лёгким свечением.</p>
<p>Мета-строка сверху (дата, тег, время чтения) при загрузке расширяется по расстоянию между буквами — как на печатной машинке, не плавное появление. Потом обложка (если есть) делает включение старого ЭЛТ-монитора: сжатая в полоску картинка за 1.6 секунды разворачивается в полный размер с вспышкой яркости.</p>
<h3>1.1 Что под капотом</h3>
<p>Сами эффекты — связка из двух частей: GSAP ScrollTrigger (библиотека анимаций + модуль отслеживания прокрутки) следит когда элемент въезжает в видимую область страницы, и навешивает CSS-класс. А CSS-анимации с <code>steps()</code> делают саму картинку. Анимации выполняются на видеокарте и не подвисают при нагрузке на страницу.</p>
<pre class="highlight"><code class="language-javascript">// Helper: trigger CSS class on scroll-into-view
function triggerOnScroll(selector, className, opts){
  gsap.utils.toArray(selector).forEach(function(el){
    ScrollTrigger.create({
      trigger: el,
      start: opts.start || 'top 88%',
      once: opts.once !== false,
      onEnter: function(){
        el.classList.remove(className);
        void el.offsetWidth;  // reflow gimmick
        el.classList.add(className);
      }
    });
  });
}

// h2/h3 — RGB glitch shift
triggerOnScroll('.post-content &gt; h2, .post-content &gt; h3', 'cyber-glitch');

// Code blocks — scanline reveal
triggerOnScroll('.post-content &gt; pre', 'cyber-scan');
</code></pre>
<p>Ключевой трюк — <code>steps(N)</code> в CSS-анимации. Обычное плавное движение (<code>ease-out</code>) даёт современный мягкий переход, а <code>steps(5)</code> или <code>steps(10)</code> — прерывистое, покадровое. Как анимация в старом мультике, не как iOS.</p>
<h2>02 / Киберпанк-приёмы</h2>
<p>Если разобрать что отделяет «киберпанк» от «современная анимация в блоге», то приёмы вполне конкретные. Не один универсальный, а набор:</p>
<ul>
<li><strong>RGB shift</strong> — красный, зелёный и синий каналы текста чуть съезжают в разные стороны, как помехи на плохом сигнале</li>
<li><strong>Scanline</strong> — горизонтальная светящаяся линия проходит сверху вниз и «открывает» элемент</li>
<li><strong>Decoder</strong> — символы из мусорной кучи по одному встают на свои места, каждый вспыхивает при фиксации</li>
<li><strong>CRT power-on</strong> — как включается старый ЭЛТ-монитор: сначала тонкая полоска, потом резкое разворачивание с вспышкой яркости</li>
<li><strong>Stutter</strong> — покадровое, прерывистое движение вместо плавного</li>
<li><strong>Flicker</strong> — прозрачность дёргается 0 → 0.4 → 0 → 0.7 → 1, имитация плохого сигнала</li>
</ul>
<p>Те же приёмы я уже использовал в своих WebGL-экспериментах (<a href="https://andromanpro.github.io/lava-orb/">lava-orb</a>, <a href="https://andromanpro.github.io/orb-2048/">orb-2048</a>, <a href="https://andromanpro.github.io/fire-particle-editor/">fire-particle-editor</a>) — теперь перенёс в посты блога.</p>
<h3>2.1 Прилипающий заголовок раздела</h3>
<p>Самый полезный трюк для длинных постов — когда подзаголовок доезжает до верха страницы, он там «прилипает» и остаётся на виду пока читаешь раздел. Как только следующий подзаголовок подъезжает снизу — предыдущий отпускается. Всегда видно в каком разделе находишься.</p>
<pre class="highlight"><code class="language-javascript">gsap.utils.toArray('.post-content &gt; h2').forEach(function(h2, idx, arr){
  var nextH2 = arr[idx + 1] || null;
  ScrollTrigger.create({
    trigger: h2,
    start: 'top 60px',
    endTrigger: nextH2 || '.post-content',
    end: 'top 60px',
    pin: h2,
    pinSpacing: false,
    pinType: 'fixed'
  });
});
</code></pre>
<p>Работает только если подзаголовки идут один за другим — что норма для длинного поста. На короткой странице с одним подзаголовком просто ничего не происходит.</p>
<h2>03 / Анимации, привязанные к прокрутке</h2>
<p><img decoding="async" alt="fire-particle-editor preview" src="https://androman.pro/wp-content/themes/androman/assets/lab-previews/fire-particle-editor.png"></p>
<p>Помимо «запустить при появлении» есть второй режим — привязка к прокрутке. Эффект не запускается резко, а плавно следует за позицией скролла. Медленно скроллишь — медленный эффект. Быстро — быстрый.</p>
<p>Обложка поста на этом сайте работает в этом режиме: лёгкий параллакс (картинка движется чуть медленнее текста) и нарастающее свечение при уходе из видимой области. Едва заметно, но убирает ощущение статичной вставки.</p>
<blockquote>
<p>Чем сильнее привязка к прокрутке, тем тоньше должен быть эффект. Резкие изменения цвета или позиции при быстром скролле — укачивает. Лучше: прозрачность, тени, смещение на 5-15px. Большие движения — только для разовых эффектов при появлении.</p>
</blockquote>
<h3>3.1 Когда этот режим не подходит</h3>
<p>Привязка к прокрутке не работает для:</p>
<ol>
<li>Текстовых эффектов (дешифратор, печатная машинка) — дёргается когда скроллишь туда-сюда</li>
<li>Блоков кода с подсветкой синтаксиса — библиотека подсветки расставляет теги при инициализации и конфликтует с анимацией появления</li>
<li>Полей ввода — анимация смещения сбивает фокус</li>
</ol>
<p>Для всего этого — разовый запуск при появлении: <code>toggleActions: 'play none none reverse'</code> или <code>once: true</code>.</p>
<h2>04 / Производительность</h2>
<p>GSAP вместе с модулем прокрутки весит ~30 КБ в сжатом виде и загружается с внешнего CDN — сети серверов по всему миру, откуда файлы отдаются быстро и кэшируются в браузере. Для повторного посетителя загрузка нулевая: файл уже лежит в кэше с прошлого раза.</p>
<p>На остальных страницах (главная, архив, лаборатория) GSAP <strong>не подгружается вообще</strong> — в теме стоит проверка, что библиотека нужна только на страницах отдельных постов. Поэтому показатели скорости главной страницы не страдают.</p>
<pre class="highlight"><code class="language-php">if ( is_singular( 'post' ) ) {
    wp_enqueue_style( 'androman-single-cyber', /* ... */ );
    wp_enqueue_script( 'gsap-core',          /* CDN */ );
    wp_enqueue_script( 'gsap-scrolltrigger', /* CDN */ );
    wp_enqueue_script( 'androman-single-anim', /* local */ );
}
</code></pre>
<h3>4.1 Режим без анимаций</h3>
<p>В Windows, macOS и Android есть системная настройка «уменьшить анимации» — для людей, которым мигание и движение на экране некомфортно. В эффектах это учтено. В CSS прописан override для этого режима:</p>
<pre class="highlight"><code class="language-css">@media (prefers-reduced-motion: reduce) {
  .cyber-glitch, .cyber-scan, .cyber-crt,
  .cyber-stutter-p, .cyber-stutter-x,
  .cyber-meta-in, .cyber-flicker {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    filter: none !important;
  }
}
</code></pre>
<p>И в JavaScript: если включён этот режим, скрипт анимаций сразу завершает работу не запуская ничего. Все элементы которые должны были «появляться» — сразу видны. Контент доступен, анимаций нет.</p>
<h2>05 / Что дальше</h2>
<p>Тестовый пост — для разовой проверки. Пожил на длинном тексте, выглядит как надо.</p>
<p>Следующее что хочу попробовать — звук: короткий клик когда символ дешифратора встаёт на место, тихий гул при CRT-включении. Плюс пасхалка: <code>↑↑↓↓←→←→BA</code> включает «режим старого ЭЛТ» на всём сайте — полосы сканирования, насыщенность +40%, чуть больше контраста. Ещё есть идея с магнитным курсором (~30 строк) и 3D-наклоном карточек лаборатории при наведении. Каждое — на час. Пока в списке, не в расписании.</p>
<h2>06 / Сравнение CRT vs default</h2>
<p>Слева — картинка <strong>без эффекта</strong> (помечена <code>class="no-anim"</code>). Справа — <strong>с CRT power-on</strong>: scaleY 0.02→1 (как ЭЛТ-монитор включается из тонкой линии), brightness peak 2.2, saturate 0→1.2→1, hue-rotate 20°→0, blur 2px→0. Длительность <strong>1.6s</strong>.</p>
<p>Кликни <strong>«▷ REPLAY»</strong> чтобы пересмотреть эффект на правой картинке.</p>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 24px 0; align-items: start;">
<figure style="margin: 0;">
    <img decoding="async" class="no-anim" src="https://androman.pro/wp-content/themes/androman/assets/lab-previews/orb-2048.png" alt="Без эффекта" style="width:100%; height:auto; border-radius:8px; display:block;"><figcaption style="margin-top: 8px; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--text-muted); letter-spacing: 0.1em; text-align: center;">// БЕЗ ЭФФЕКТА</figcaption></figure>
<figure style="margin: 0;">
    <img decoding="async" id="crt-demo-img" src="https://androman.pro/wp-content/themes/androman/assets/lab-previews/orb-2048.png" alt="С CRT power-on" style="width:100%; height:auto; border-radius:8px; display:block;"><figcaption style="margin-top: 8px; font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--cyan); letter-spacing: 0.1em; text-align: center;">// CRT POWER-ON</figcaption><div style="text-align: center; margin-top: 6px;">
      <button type="button" class="cyber-crt-replay" data-target="#crt-demo-img">▷ REPLAY</button>
    </div>
</figure>
</div>
<p><em>// END OF TRANSMISSION · скролл назад оставит тебя на текущей секции</em></p>
<p>Работает как надо — живёт в теме. Большую часть времени потратил не на написание, а на подбор тайминга: на коротком тексте эти вещи не видны, а на длинном сразу понятно где слишком резко, а где не хватает. Этот пост и был для этого.</p>


<p style="margin-top:1em;font-family:monospace;font-size:0.9em;">→ <a href="https://androman.pro/2026/04/30/cyberpunk-anim-demo/">открыть на androman.pro</a></p>]]></content:encoded>
					
					<wfw:commentRss>https://androman.pro/2026/04/30/cyberpunk-anim-demo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
