masked-reveal — скилл для Claude Code: что делает и установка
Скилл добавляет появление слов через маску при прокрутке с GSAP ScrollTrigger. Подходит для заголовков, hero-текста и коротких вводных блоков.
npx skills add MengTo/Skills --skill masked-reveal -a claude-codeЧто делает masked-reveal
masked-reveal разбивает текст на слова и оборачивает их в маски с overflow: hidden. При входе элемента в область просмотра слова поднимаются снизу по очереди через GSAP ScrollTrigger. Анимация запускается один раз, а исходный текст сохраняется в aria-label для скринридеров.
Внутри есть CSS для маски, JavaScript-функции splitMaskedReveal и initMaskedReveals, а также шаблон очистки GSAP-контекста для React через useLayoutEffect. Пробелы между словами сохраняются. Для анимации нужен GSAP с ScrollTrigger.
Скилл учитывает prefers-reduced-motion: при включённом режиме текст остаётся статичным. Не применяйте его к длинным абзацам или тексту со ссылками, кнопками и другой значимой разметкой. Если переносы строк зависят от шрифтов, инициализируйте эффект после их загрузки.
Какие задачи решает
- анимировать заголовок по словам при прокрутке
- скрыть слова в масках до запуска GSAP
- сохранить исходный текст для скринридеров
- учесть режим уменьшения движения
- очистить ScrollTrigger при смене React-маршрута
Примеры запросов агенту
- Добавь masked-reveal к короткому заголовку в
Hero.jsxи подключи анимацию через GSAP ScrollTrigger. - Разбери текст с
data-masked-revealна слова и запусти появление при входе в область просмотра. - Адаптируй masked-reveal для React так, чтобы GSAP-контекст очищался при размонтировании компонента.
Как установить masked-reveal
1Через Skills CLI (Vercel)
npx skills add MengTo/Skills --skill masked-reveal -a claude-code2Вручную: положить файлы
~/.claude/skills/masked-reveal/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/masked-reveal/
1Через Skills CLI (Vercel)
npx skills add MengTo/Skills --skill masked-reveal -a codex2Вручную: положить файлы
.agents/skills/masked-reveal/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add MengTo/Skills --skill masked-reveal -a cursor2Вручную: положить файлы
.cursor/skills/masked-reveal/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install MengTo/Skills masked-reveal2Вручную: положить файлы
.github/skills/masked-reveal/SKILL.md1Через Skills CLI (Vercel)
npx skills add MengTo/Skills --skill masked-reveal -a gemini-cli2Командой платформы
gemini skills install https://github.com/MengTo/Skills --path agent-skills/web-design/masked-revealВручную: положить файлы
.devin/skills/masked-reveal/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add MengTo/Skills --skill masked-reveal -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о masked-reveal
Как установить masked-reveal в Claude Code?
Выполните npx skills add MengTo/Skills --skill masked-reveal -a claude-code, затем повторите npx skills add MengTo/Skills --skill masked-reveal -a claude-code. Файл скилла находится по пути ~/.claude/skills/masked-reveal/SKILL.md.
Что делает masked-reveal?
Он создаёт поочерёдное появление слов через маску при прокрутке. Для этого используются GSAP и ScrollTrigger, а обработка текста сохраняет пробелы и добавляет исходную строку в aria-label.
Что произойдёт при включённом prefers-reduced-motion?
Анимация не запускается, а текст показывается статично без вертикального смещения.
Исходный текст
SKILL.md · MIT
---
name: masked-reveal
description: Create masked staggered word reveals on scroll with GSAP ScrollTrigger. Use when headings, hero copy, section titles, or editorial text should reveal word-by-word through an overflow mask as they enter the viewport.
---
# Masked Reveal
## Use When
- A headline or short text block needs a premium reveal on scroll.
- Words should rise through an invisible mask with a staggered sequence.
- The project already uses GSAP or needs ScrollTrigger-based motion.
## Motion Defaults
- Trigger: start when the text top reaches `82%` of the viewport.
- Duration: `0.7s` to `0.9s`.
- Stagger: `0.025s` to `0.045s` per word.
- Offset: `yPercent: 110` to `0`.
- Ease: `power3.out` or `expo.out`.
- Replay: reveal once by default.
## HTML
```html
<h1 class="masked-reveal" data-masked-reveal>
Design systems that feel alive from the first scroll.
</h1>
```
## CSS Mask
```css
.masked-reveal {
visibility: visible;
}
html.js .masked-reveal[data-masked-reveal] {
visibility: hidden;
}
html.js .masked-reveal.is-split {
visibility: visible;
}
.masked-reveal .word-mask {
display: inline-block;
overflow: hidden;
vertical-align: top;
}
.masked-reveal .word {
display: inline-block;
transform: translateY(110%);
will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
html.js .masked-reveal[data-masked-reveal] {
visibility: visible;
}
.masked-reveal .word {
transform: none;
}
}
```
## GSAP ScrollTrigger
This helper avoids the paid SplitText plugin and keeps spaces intact.
```js
document.documentElement.classList.add("js");
gsap.registerPlugin(ScrollTrigger);
function escapeHTML(value) {
return value
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function splitMaskedReveal(element) {
if (element.dataset.maskedRevealReady === "true") return;
const text = element.textContent.trim();
element.setAttribute("aria-label", text);
element.innerHTML = text
.split(/(\s+)/)
.map((part) => {
if (!part.trim()) return part;
return `<span class="word-mask" aria-hidden="true"><span class="word">${escapeHTML(part)}</span></span>`;
})
.join("");
element.dataset.maskedRevealReady = "true";
element.classList.add("is-split");
}
function initMaskedReveals(selector = "[data-masked-reveal]") {
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
document.querySelectorAll(selector).forEach((element) => {
splitMaskedReveal(element);
const words = element.querySelectorAll(".word");
gsap.set(element, { autoAlpha: 1 });
gsap.fromTo(
words,
{ yPercent: 110 },
{
yPercent: 0,
duration: 0.8,
ease: "power3.out",
stagger: 0.035,
scrollTrigger: {
trigger: element,
start: "top 82%",
once: true,
},
}
);
});
}
initMaskedReveals();
```
## React Cleanup Pattern
```js
useLayoutEffect(() => {
const ctx = gsap.context(() => {
initMaskedReveals("[data-masked-reveal]");
}, rootRef);
return () => ctx.revert();
}, []);
```
## Taste Rules
- Use on short headlines, labels, and section intros; avoid long paragraphs.
- Keep the vertical offset clean. Do not combine with blur unless the style explicitly calls for it.
- Stagger by word, not letter, for a calmer editorial feel.
- Initialize after fonts are loaded if line wrapping is critical.
- Use `ScrollTrigger.refresh()` after late-loading images or layout shifts.
- Do not split text that contains links, buttons, or meaningful inline markup.
## Quick Checks
- Text is hidden before GSAP initializes, then becomes visible with `autoAlpha: 1`.
- Screen readers get the original full text through `aria-label`.
- Spaces between words are preserved.
- Reduced-motion users see static text.
- ScrollTrigger is cleaned up in SPA routes.
© MengTo · MIT · MengTo/Skills