Skip to content
Open
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
142 changes: 81 additions & 61 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,81 @@ const skillsMap = [...SKILLS_MAP].sort((a: any, b: any) => {
await navigator.clipboard.writeText('npx autoskills')
})

function PrintAsciiWithAnimation (ascii: string[], id: string) {
const START_COLOR = '#3f3f46' // zinc-700 (gris clarito)
const END_COLOR = '#f4f4f5' // zinc-100 (blanco)

const logo = document.getElementById(id)
if (!logo) {
// Element not in DOM yet, wait for it
const observer = new MutationObserver(() => {
const el = document.getElementById(id)
if (el) {
observer.disconnect()
runAnimation(el)
}
})
observer.observe(document.body, { childList: true, subtree: true })
return
}
runAnimation(logo)

function runAnimation(logo: HTMLElement) {
const cols = Math.max(...ascii.map(l => l.length))
const rows = ascii.length

// Build grid
const grid: HTMLSpanElement[][] = []
for (const line of ascii) {
const row: HTMLSpanElement[] = []
const lineEl = document.createElement('div')
lineEl.style.height = '1lh'
lineEl.style.lineHeight = '1'
for (let c = 0; c < cols; c++) {
const ch = line[c] ?? ' '
const span = document.createElement('span')
span.textContent = ch
span.style.color = START_COLOR
lineEl.appendChild(span)
row.push(span)
}
logo.appendChild(lineEl)
grid.push(row)
}

// Diagonal sweep: top-left to bottom-right, gray → white
const maxDist = cols + rows
const SPEED = 0.9
let frame = 0
const totalFrames = Math.ceil((maxDist + 10) / SPEED)

function animate() {
const waveFront = frame * SPEED

for (let r = 0; r < rows; r++) {
for (let c = 0; c < grid[r].length; c++) {
const dist = c + r * 3
const progress = Math.max(0, Math.min(1, (waveFront - dist) / 10))

const gray = Math.round(63 + progress * (244 - 63))
grid[r][c].style.color = `rgb(${gray},${gray},${gray})`
}
}

frame++
if (frame <= totalFrames) {
requestAnimationFrame(animate)
} else {
for (let r = 0; r < rows; r++)
for (let c = 0; c < grid[r].length; c++)
grid[r][c].style.color = END_COLOR
}
}

requestAnimationFrame(animate)
}
}

// ── ASCII logo animation ─────────────────────────────────
{
const LOGO_LINES = [
Expand All @@ -375,61 +450,7 @@ const skillsMap = [...SKILLS_MAP].sort((a: any, b: any) => {
'╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚══════╝',
]

const START_COLOR = '#3f3f46' // zinc-700 (gris clarito)
const END_COLOR = '#f4f4f5' // zinc-100 (blanco)

const logo = document.getElementById('ascii-logo')!
const cols = Math.max(...LOGO_LINES.map(l => l.length))
const rows = LOGO_LINES.length

// Build grid
const grid: HTMLSpanElement[][] = []
for (const line of LOGO_LINES) {
const row: HTMLSpanElement[] = []
const lineEl = document.createElement('div')
lineEl.style.height = '1lh'
for (let c = 0; c < cols; c++) {
const ch = line[c] ?? ' '
const span = document.createElement('span')
span.textContent = ch
span.style.color = START_COLOR
lineEl.appendChild(span)
row.push(span)
}
logo.appendChild(lineEl)
grid.push(row)
}

// Diagonal sweep: top-left to bottom-right, gray → white
const maxDist = cols + rows
const SPEED = 0.9
let frame = 0
const totalFrames = Math.ceil((maxDist + 10) / SPEED)

function animate() {
const waveFront = frame * SPEED

for (let r = 0; r < rows; r++) {
for (let c = 0; c < grid[r].length; c++) {
const dist = c + r * 3
const progress = Math.max(0, Math.min(1, (waveFront - dist) / 10))

const gray = Math.round(63 + progress * (244 - 63))
grid[r][c].style.color = `rgb(${gray},${gray},${gray})`
}
}

frame++
if (frame <= totalFrames) {
requestAnimationFrame(animate)
} else {
for (let r = 0; r < rows; r++)
for (let c = 0; c < grid[r].length; c++)
grid[r][c].style.color = END_COLOR
}
}

requestAnimationFrame(animate)
PrintAsciiWithAnimation(LOGO_LINES, 'ascii-logo')
}

// ── Terminal animation ────────────────────────────────────
Expand Down Expand Up @@ -459,11 +480,9 @@ const skillsMap = [...SKILLS_MAP].sort((a: any, b: any) => {
const bannerGap = ' '.repeat(Math.max(1, 39 - bannerTitle.length - ver.length - 3))

const BANNER = [
s(C.cy, ' ╔═══════════════════════════════════════╗'),
s(C.cy, ' ║') + s(C.yw, bannerTitle) + bannerGap + s(C.z6, ver) + ' ' + s(C.cy, '║'),
s(C.cy, ' ║') + s(C.z5, ' Auto-install the best AI skills ') + s(C.cy, '║'),
s(C.cy, ' ║') + s(C.z5, ' for your project ') + s(C.cy, '║'),
s(C.cy, ' ╚═══════════════════════════════════════╝'),
" ┌─┐┬ ┬┌┬┐┌─┐┌─┐┬┌─┬┬ ┬ ┌─┐",
" ├─┤│ │ │ │ │└─┐├┴┐││ │ └─┐",
" ┴ ┴└─┘ ┴ └─┘└─┘┴ ┴┴┴─┘┴─┘└─┘",
]

const TECH_NAMES = ['Next.js', 'React', 'Tailwind CSS', 'TypeScript', 'Supabase', 'Astro']
Expand Down Expand Up @@ -506,7 +525,8 @@ const skillsMap = [...SKILLS_MAP].sort((a: any, b: any) => {

// Banner
d(500, '')
for (const line of BANNER) d(30, line)
d(30, '<pre id="term-ascii"></pre>')
PrintAsciiWithAnimation(BANNER, 'term-ascii')
d(0, '')

// Detected technologies
Expand Down
Loading