Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/docs/public/angular-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 29 additions & 69 deletions apps/docs/src/app/pages/(home).page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,13 @@ const COPY = {
featNote:
"You could write all of this glue yourself. Most Angular apps that animate end up doing exactly that, one component at a time.",
features: [
{
title: 'Scoped by default',
body: "Fifty instances of a component, each animating <code>'.icon'</code>? Each one only touches its own. Selectors stop at the host, just like component styles.",
},
{
title: 'Signal-driven',
body: 'Your signals already drive the template. Read one in the callback and it drives the animation too: change it and the animation replays against the freshly rendered DOM.',
},
{
title: 'No cleanup needed',
body: 'Leave the route and every tween, ScrollTrigger, and text split reverts, the same way Angular tears down the view. Forgetting cleanup stops being a bug you can write.',
},
{
title: 'SSR ready',
body: "No 'window is not defined' at build time, no isPlatformBrowser guards. Animation code waits until there's a browser.",
},
{
title: 'Nothing new to learn',
body: "You're writing GSAP, not a translation of it. Docs, forum answers, and CodePens work verbatim.",
},
{
title: 'Tree-shakeable',
body: 'Use two directives and the other ten leave your bundle. Plugins cost bytes only when you import them.',
},
{
title: 'Zero change detection cost',
body: "A tween at 60fps never schedules a change detection pass. GSAP's ticker does the work; no zone.js, no rxjs in the library.",
},
'Scoped by default',
'Signal-driven',
'No cleanup needed',
'SSR ready',
'Nothing new to learn',
'Tree-shakeable',
'Zero change detection cost',
],
},
es: {
Expand All @@ -83,34 +62,13 @@ const COPY = {
featNote:
'Todo este pegamento lo podr铆as escribir t煤. La mayor铆a de las apps Angular que animan terminan haciendo justo eso, componente por componente.',
features: [
{
title: 'Scoped por defecto',
body: "驴Cincuenta instancias de un componente, cada una animando <code>'.icon'</code>? Cada una toca solo el suyo. Los selectores se detienen en el host, igual que los estilos del componente.",
},
{
title: 'Dirigido por signals',
body: 'Tus signals ya dirigen el template. Lee uno en el callback y dirige tambi茅n la animaci贸n: c谩mbialo y la animaci贸n se repite contra el DOM reci茅n pintado.',
},
{
title: 'Sin limpieza manual',
body: 'Sal de la ruta y cada tween, ScrollTrigger y divisi贸n de texto se revierte, igual que Angular desmonta la vista. Olvidar la limpieza deja de ser un bug posible.',
},
{
title: 'Listo para SSR',
body: "Sin 'window is not defined' al compilar, sin isPlatformBrowser. El c贸digo de animaci贸n espera a que haya navegador.",
},
{
title: 'Nada nuevo que aprender',
body: 'Escribes GSAP, no una traducci贸n. Docs, respuestas de foros y CodePens funcionan tal cual.',
},
{
title: 'Tree-shakeable',
body: 'Usa dos directivas y las otras diez salen del bundle. Los plugins cuestan bytes solo cuando los importas.',
},
{
title: 'Cero costo en change detection',
body: 'Un tween a 60fps nunca agenda un pase de change detection. El ticker de GSAP hace el trabajo; sin zone.js, sin rxjs en la librer铆a.',
},
'Scoped por defecto',
'Dirigido por signals',
'Sin limpieza manual',
'Listo para SSR',
'Nada nuevo que aprender',
'Tree-shakeable',
'Cero costo en change detection',
],
},
} as const;
Expand Down Expand Up @@ -180,11 +138,16 @@ const COPY = {
<p class="eyebrow">{{ c.featEyebrow }}</p>
<h2 class="feat-title">{{ c.featTitle }}</h2>
<p class="feat-note">{{ c.featNote }}</p>
<ul stagger="0.08" on="scroll" preset="fade-up" [distance]="40">
@for (f of c.features; track f.title) {
<ul
stagger="0.07"
on="scroll"
preset="scale-in"
ease="back.out(2.2)"
[duration]="0.5"
>
@for (f of c.features; track f) {
<li class="feature" hover>
<h3>{{ f.title }}</h3>
<p [innerHTML]="f.body"></p>
<h3>{{ f }}</h3>
</li>
}
</ul>
Expand Down Expand Up @@ -370,22 +333,19 @@ const COPY = {
}

.feature {
display: grid;
place-items: center;
text-align: center;
background: var(--card);
border: var(--bw) solid var(--ink);
border-radius: 12px;
box-shadow: var(--shadow-sm);
padding: 1.4rem;
padding: 1.6rem 1.2rem;

h3 {
font-size: 1.05rem;
font-weight: 700;
margin-bottom: 0.5rem;
}

p {
font-size: 1.15rem;
font-weight: 800;
margin: 0;
font-size: 0.92rem;
color: var(--ink-soft);
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions apps/docs/src/app/pages/svg.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ export const routeMeta: RouteMeta = {

const SHAPES = [
{
d: 'M200 170 C 225 120, 300 125, 305 165 C 310 205, 250 235, 215 210 C 185 190, 175 195, 200 170 Z',
// the Angular mark (apps/docs/public/angular-icon.svg), rescaled into this viewBox
d: 'M302.8 130.6l-4 59.8L262.3 111.7l40.5 18.9ZM277.3 208l-27.3 15.8 -27.7 -15.8 5.3 -13.6h44.4l5.3 13.6ZM250 141.6l14.1 35.2H235.5l14.5 -35.2ZM200.7 190.4L196.8 130.6 237.2 111.7 200.7 190.4Z',
fill: '--pulse',
},
{
d: 'M200 170 C 225 120, 300 125, 305 165 C 310 205, 250 235, 215 210 C 185 190, 175 195, 200 170 Z',
fill: '--arc',
},
{
d: 'M250 110 L262 150 L305 150 L272 176 L284 216 L250 192 L216 216 L228 176 L195 150 L238 150 Z',
fill: '--ember',
},
{
d: 'M262 108 L214 170 L244 170 L226 218 L288 152 L254 152 Z',
fill: '--arc',
fill: '--kinetic',
},
] as const;

Expand All @@ -28,7 +33,7 @@ const COPY = {
eyebrow: 'Example 路 SVG',
title: 'SVG animation',
intro:
'SVG is regular DOM to GSAP: strokes draw in with DrawSVG, shapes morph with MorphSVG, and elements ride paths with MotionPath. All three plugins are registered once in <code>provideGsap</code>.',
'SVG is regular DOM to GSAP: strokes draw in with DrawSVG, shapes morph with MorphSVG, and elements ride paths with MotionPath. All three plugins are registered once in <code>provideGsap</code>. The floating shape starts as the Angular mark; Morph cycles it through the others.',
morph: 'Morph',
how: 'How this works',
explain: [
Expand All @@ -41,7 +46,7 @@ const COPY = {
eyebrow: 'Ejemplo 路 SVG',
title: 'Animaci贸n de SVG',
intro:
'Para GSAP el SVG es DOM normal: los trazos se dibujan con DrawSVG, las formas se transforman con MorphSVG y los elementos recorren rutas con MotionPath. Los tres plugins se registran una vez en <code>provideGsap</code>.',
'Para GSAP el SVG es DOM normal: los trazos se dibujan con DrawSVG, las formas se transforman con MorphSVG y los elementos recorren rutas con MotionPath. Los tres plugins se registran una vez en <code>provideGsap</code>. La forma flotante empieza como el logo de Angular; Transformar la pasa por las dem谩s.',
morph: 'Transformar',
how: 'C贸mo funciona',
explain: [
Expand Down