Files
lucide/docs/.vitepress/theme/components/overrides/HeroMatrix.vue
Eric Fennis 484f2c9cd3 docs(version-1): Version 1 website (#4142)
* Update images

* Adjust color

* update accessebility

* Add matrix hero

* Add typescript documentation

* Add basics section to vue pages

* Add svelte docs

* Fix dynamic sidebar

* Add animation?

* Some adjustments

* Adjust animation

* Updates docs

* Add scaledown animation

* Add docs for vue types

* Fix layout accessibility page

* fix framework select

* adjust easing home animation

* Write docs for Vue

* Adjust animation home

* Adjust home hero animation

* Finish svelte docs

* Add solid pages

* remove spiral animation component

* Add group icons

* Added solid docs

* update preact docs

* Adjust examples preact docs

* Add snackplayer

* Get new editor

* Save this

* Add examples

* Adjust styling

* setup custom sandpack

* Add script

* Format files

* Make sandpack plugin work

* migrate react docs

* Fix svelte and solid examples

* Migrate to solid packages

* Add darkmode package logos

* Fix bug in selector

* migrate vue examples

* migrate advanced vue items

* migrate preact and svelte examples

* Add astro docs

* adding more docs on guide for lucide library

* Fix home animation

* Cleanup

* Added resources page, with more details and content

* Add hero badge for Version 1

* Fix vercel json

* Update missing paths

* Fix build?

* Replace lucide-vue-next

* Fix build

* Add some docs

* update markdown

* Setup angular docs

* Add basic angular docs

* Adjust code examples

* Update title and descriptions

* Update accessibility link

* Update title and description

* Add og image

* Fix alignment

* Add migration guides

* Adjust version 1 markdown file

* Add migration guide to the main list

* Minor fixes

* Update docs

* Apply feedback

* Select icons

* Add pointer events none

* Fix package links homepage

* Format code

* Fix types

* Fix focus

* Fix build

* Fix focus

* Apply feedback

* Adjust imports

* Adjust imports

* Fix search

* Apply feedback

* Fix import in font docs

* Small fixes

* docs(guide): added easter egg icon. stay tuned, guys 😉

* Add llm txt plugin

* Adjust logo top

* docs(version-1): upgraded @lucide/angular guide for v1 website (#4144)

* docs(guide/angular): rewrite some angular documentation

* docs(guide/angular): extens angular guide with combining icons & icon provider guides

* docs(guide/angular): fix angular sandbox, still needs @lucide/angular release tho

* docs(guide/angular): rework the getting started page a bit more, refactor some more prop=>input occurences

* docs(guide/angular): context provider => provideLucideConfig

* Update docs/guide/angular/migration.md

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Update docs/guide/angular/advanced/combining-icons.md

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* docs(guide/angular): rework a11y for better flow & pacing

* docs(guide/angular): salvage original phrase, it has better flow

* docs(guide/angular): some more a11y nitpicking

* docs(guide/angular): reduce llm fatigue

* docs(guides/angular): fix app component selector

* docs(guides/angular): fix angular sandpacks

* Add sandpack angular to improve tree-shakable stack

* Update docs/guide/angular/getting-started.md

* docs(guides/angular): fix user import in combinding icons guide

* docs(guides/angular): fix nested SVG phrasing

* Update docs/guide/angular/advanced/with-lucide-lab.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/guide/angular/advanced/filled-icons.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* docs(guides/angular): fix createLucideIcon guide

* docs(guides/angular): upgrade all relevant angular sandpack demos

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix(docs): add autogenerated OG images to gitignore

* fix(docs): unify the case of "Lucide" & "Lucide Lab" over all docs and readmes

* Fix build

* Add next tag to all installation guides

* Add top bar notification

* Minor fixes

* Update text

* Add todos

* Update og image

* Adjust install command

* Color top bar

* fix(docs): ignore all OG images, expect general.png

* fix(docs): fix the package list, hide @lucide/icons, downgrade angular logo, link to v0 guide, fix package title alignment

* Update docs/.vitepress/theme/components/base/LayoutTop.vue

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/guide/react/advanced/dynamic-icon-component.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update CONTRIBUTING.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update docs/.vitepress/sidebar/resources.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix code example

* fix(docs): version 1 => Version 1

* feat(docs): add angular to new features in v1

* Fix next line issue

* feat(docs): fix typo (code example_s_)

* Fix deadlink

* feat(docs): fix some more typos and irky grammar

* feat(docs): fix lowercase lucide in sidebar 😅

* Update docs/guide/version-1.md

Co-authored-by: Karsa <contact@karsa.org>

---------

Co-authored-by: Karsa <contact@karsa.org>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-20 17:04:28 +01:00

249 lines
5.4 KiB
Vue

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, type Component } from 'vue';
import {
heart,
star,
zap,
code,
feather,
cloud,
sun,
moon,
camera,
music,
video,
globe,
layers,
package as packageIcon,
compass,
command,
terminal,
database,
server,
cpu,
lock,
key,
shield,
wifi,
download,
upload,
search,
settings,
users,
mail,
bell,
calendar,
clock,
gitBranch,
funnel,
bookmark,
tag,
sparkles,
} from '../../../data/iconNodes';
import createElement from 'lucide/src/createElement';
import { IconNode } from 'lucide';
const icons: Component[] = [
heart, star, zap, code, feather, cloud, sun, moon, camera, music,
video, globe, layers, packageIcon, compass, command, terminal, database,
server, cpu, lock, key, shield, wifi, download, upload, search,
settings, users, mail, bell, calendar, clock, gitBranch, funnel,
bookmark, tag, sparkles,
];
const svgs = icons.map(icon => {
const element = createElement(icon as IconNode, {
stroke: 'white',
opacity: '0.2',
})
return element.outerHTML;
});
const highlightedSvgs = icons.map(icon => {
const element = createElement(icon as IconNode, {
stroke: 'white',
})
return element.outerHTML;
});
const images = svgs.map(svg => {
const img = new Image();
img.src = `data:image/svg+xml;base64,${btoa(svg)}`;
return img;
});
const highlightedImages = highlightedSvgs.map(svg => {
const img = new Image();
img.src = `data:image/svg+xml;base64,${btoa(svg)}`;
return img;
});
const canvas = ref<HTMLCanvasElement | null>(null);
// Setting up the columns
const fontSize = 16;
const gap = 40;
const gapY = 8;
const intervalTime = ref<number | null>(null);
// Store individual drops with their positions
let individualDrops: Array<{x: number, y: number, active: boolean}> = [];
// Random integer between min and max
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
onMounted(() => {
if (!canvas.value) return;
const ctx = canvas.value.getContext('2d');
if (!ctx) return;
const width = window.innerWidth;
const height = window.innerHeight * 0.6;
canvas.value.width = width;
canvas.value.height = height;
let columns = Math.floor(width / 120);
var rows = Math.floor(canvas.value.height / fontSize);
var midStart = Math.floor(rows * 0.25);
var midEnd = Math.floor(rows * 0.85);
let drops = Array.from({ length: columns }, () => randInt(midStart, midEnd));
let fps, fpsInterval, startTime, now, then, elapsed;
// Add click event listener
function handleCanvasClick(event: MouseEvent) {
const rect = canvas.value?.getBoundingClientRect();
if (!rect) return;
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
individualDrops.push({
x: x,
y: y,
active: true
});
}
canvas.value.addEventListener('click', handleCanvasClick);
function draw() {
if (!ctx) return;
ctx.fillStyle = 'rgba(27, 27, 31, 0.50)';
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
// Draw regular drops
for (var i = drops.length; i > 0; i--) {
var img = images[Math.floor(Math.random() * images.length)];
ctx.drawImage(img, i * fontSize * 2 + gap, drops[i] * fontSize, (fontSize / 2) + gapY, (fontSize / 2) + gapY);
drops[i]++;
if (Math.random() > .98) {
drops[i] = randInt(midStart, midEnd);
}
}
// Draw and update individual drops
individualDrops = individualDrops.filter(drop => {
if (!drop.active) return false;
var img = highlightedImages[Math.floor(Math.random() * images.length)];
ctx.drawImage(img, drop.x - fontSize/2, drop.y, fontSize, fontSize);
drop.y += fontSize
// Remove if off screen
if (drop.y > height) {
drop.active = false;
return false;
}
return true;
});
}
function startAnimating(fps) {
fpsInterval = 1000 / fps;
then = Date.now();
startTime = then;
animate();
}
function animate() {
// request another frame
requestAnimationFrame(animate);
// calc elapsed time since last loop
now = Date.now();
elapsed = now - then;
// if enough time has elapsed, draw the next frame
if (elapsed > fpsInterval) {
// Get ready for next frame by setting then=now, but also adjust for your
// specified fpsInterval not being a multiple of RAF's interval (16.7ms)
then = now - (elapsed % fpsInterval);
// Put your drawing code here
draw();
}
}
startAnimating(12);
window.addEventListener('resize', function() {
canvas.value.width = window.innerWidth;
canvas.value.height = window.innerHeight;
rows = Math.floor(canvas.value.height / fontSize);
columns = Math.floor(canvas.value.width / fontSize);
var oldDrops = drops.slice();
drops = [];
for (var i = 0; i < columns; i++) {
drops[i] = oldDrops[i % oldDrops.length] ?? randInt(midStart, midEnd);
}
});
// Cleanup event listener
onBeforeUnmount(() => {
canvas.value?.removeEventListener('click', handleCanvasClick);
});
});
</script>
<template>
<div class="hero">
<canvas ref="canvas" class="hero-canvas" />
</div>
</template>
<style scoped>
.hero {
overflow: hidden;
height: 60vh;
}
.hero-canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 60vh;
filter: blur(0px);
}
</style>