[ FIX ] : ASCIIText Naming & Registry

This commit is contained in:
Utkarsh-Singhal-26
2026-01-21 16:08:55 +05:30
parent c484742f02
commit 18d561ea6f
27 changed files with 101 additions and 35 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"name":"CountUp","title":"CountUp","description":"Animated number counter supporting formatting and decimals.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <span ref=\"elementRef\" :class=\"className\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch, computed, useTemplateRef } from 'vue';\n\ninterface Props {\n to: number;\n from?: number;\n direction?: 'up' | 'down';\n delay?: number;\n duration?: number;\n className?: string;\n startWhen?: boolean;\n separator?: string;\n onStart?: () => void;\n onEnd?: () => void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n from: 0,\n direction: 'up',\n delay: 0,\n duration: 2,\n className: '',\n startWhen: true,\n separator: ''\n});\n\nconst elementRef = useTemplateRef<HTMLSpanElement>('elementRef');\nconst currentValue = ref(props.direction === 'down' ? props.to : props.from);\nconst isInView = ref(false);\nconst animationId = ref<number | null>(null);\nconst hasStarted = ref(false);\n\nlet intersectionObserver: IntersectionObserver | null = null;\n\nconst damping = computed(() => 20 + 40 * (1 / props.duration));\nconst stiffness = computed(() => 100 * (1 / props.duration));\n\nlet velocity = 0;\nlet startTime = 0;\n\nconst formatNumber = (value: number) => {\n const options = {\n useGrouping: !!props.separator,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0\n };\n\n const formattedNumber = Intl.NumberFormat('en-US', options).format(Number(value.toFixed(0)));\n\n return props.separator ? formattedNumber.replace(/,/g, props.separator) : formattedNumber;\n};\n\nconst updateDisplay = () => {\n if (elementRef.value) {\n elementRef.value.textContent = formatNumber(currentValue.value);\n }\n};\n\nconst springAnimation = (timestamp: number) => {\n if (!startTime) startTime = timestamp;\n\n const target = props.direction === 'down' ? props.from : props.to;\n const current = currentValue.value;\n\n const displacement = target - current;\n const springForce = displacement * stiffness.value;\n const dampingForce = velocity * damping.value;\n const acceleration = springForce - dampingForce;\n\n velocity += acceleration * 0.016; // Assuming 60fps\n currentValue.value += velocity * 0.016;\n\n updateDisplay();\n\n if (Math.abs(displacement) > 0.01 || Math.abs(velocity) > 0.01) {\n animationId.value = requestAnimationFrame(springAnimation);\n } else {\n currentValue.value = target;\n updateDisplay();\n animationId.value = null;\n\n if (props.onEnd) {\n props.onEnd();\n }\n }\n};\n\nconst startAnimation = () => {\n if (hasStarted.value || !isInView.value || !props.startWhen) return;\n\n hasStarted.value = true;\n\n if (props.onStart) {\n props.onStart();\n }\n\n setTimeout(() => {\n startTime = 0;\n velocity = 0;\n animationId.value = requestAnimationFrame(springAnimation);\n }, props.delay * 1000);\n};\n\nconst setupIntersectionObserver = () => {\n if (!elementRef.value) return;\n\n intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !isInView.value) {\n isInView.value = true;\n startAnimation();\n }\n },\n {\n threshold: 0,\n rootMargin: '0px'\n }\n );\n\n intersectionObserver.observe(elementRef.value);\n};\n\nconst cleanup = () => {\n if (animationId.value) {\n cancelAnimationFrame(animationId.value);\n animationId.value = null;\n }\n\n if (intersectionObserver) {\n intersectionObserver.disconnect();\n intersectionObserver = null;\n }\n};\n\nwatch(\n [() => props.from, () => props.to, () => props.direction],\n () => {\n currentValue.value = props.direction === 'down' ? props.to : props.from;\n updateDisplay();\n hasStarted.value = false;\n },\n { immediate: true }\n);\n\nwatch(\n () => props.startWhen,\n () => {\n if (props.startWhen && isInView.value && !hasStarted.value) {\n startAnimation();\n }\n }\n);\n\nonMounted(() => {\n updateDisplay();\n setupIntersectionObserver();\n});\n\nonUnmounted(() => {\n cleanup();\n});\n</script>\n","path":"CountUp/CountUp.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[],"devDependencies":[],"categories":["Animations"]}
{"name":"CountUp","title":"CountUp","description":"Animated number counter supporting formatting and decimals.","type":"registry:component","add":"when-added","files":[{"type":"registry:component","role":"file","content":"<template>\n <span ref=\"elementRef\" :class=\"className\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, watch, computed, useTemplateRef } from 'vue';\n\ninterface Props {\n to: number;\n from?: number;\n direction?: 'up' | 'down';\n delay?: number;\n duration?: number;\n className?: string;\n startWhen?: boolean;\n separator?: string;\n onStart?: () => void;\n onEnd?: () => void;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n from: 0,\n direction: 'up',\n delay: 0,\n duration: 2,\n className: '',\n startWhen: true,\n separator: ''\n});\n\nconst elementRef = useTemplateRef<HTMLSpanElement>('elementRef');\nconst currentValue = ref(props.direction === 'down' ? props.to : props.from);\nconst isInView = ref(false);\nconst animationId = ref<number | null>(null);\nconst hasStarted = ref(false);\n\nlet intersectionObserver: IntersectionObserver | null = null;\n\nconst damping = computed(() => 20 + 40 * (1 / props.duration));\nconst stiffness = computed(() => 100 * (1 / props.duration));\n\nlet velocity = 0;\nlet startTime = 0;\n\nconst formatNumber = (value: number) => {\n const options = {\n useGrouping: !!props.separator,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0\n };\n\n const formattedNumber = Intl.NumberFormat('en-US', options).format(Number(value.toFixed(0)));\n\n return props.separator ? formattedNumber.replace(/,/g, props.separator) : formattedNumber;\n};\n\nconst updateDisplay = () => {\n if (elementRef.value) {\n elementRef.value.textContent = formatNumber(currentValue.value);\n }\n};\n\nconst springAnimation = (timestamp: number) => {\n if (!startTime) startTime = timestamp;\n\n const target = props.direction === 'down' ? props.from : props.to;\n const current = currentValue.value;\n\n const displacement = target - current;\n const springForce = displacement * stiffness.value;\n const dampingForce = velocity * damping.value;\n const acceleration = springForce - dampingForce;\n\n velocity += acceleration * 0.016; // Assuming 60fps\n currentValue.value += velocity * 0.016;\n\n updateDisplay();\n\n if (Math.abs(displacement) > 0.01 || Math.abs(velocity) > 0.01) {\n animationId.value = requestAnimationFrame(springAnimation);\n } else {\n currentValue.value = target;\n updateDisplay();\n animationId.value = null;\n\n if (props.onEnd) {\n props.onEnd();\n }\n }\n};\n\nconst startAnimation = () => {\n if (hasStarted.value || !isInView.value || !props.startWhen) return;\n\n hasStarted.value = true;\n\n if (props.onStart) {\n props.onStart();\n }\n\n setTimeout(() => {\n startTime = 0;\n velocity = 0;\n animationId.value = requestAnimationFrame(springAnimation);\n }, props.delay * 1000);\n};\n\nconst setupIntersectionObserver = () => {\n if (!elementRef.value) return;\n\n intersectionObserver = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting && !isInView.value) {\n isInView.value = true;\n startAnimation();\n }\n },\n {\n threshold: 0,\n rootMargin: '0px'\n }\n );\n\n intersectionObserver.observe(elementRef.value);\n};\n\nconst cleanup = () => {\n if (animationId.value) {\n cancelAnimationFrame(animationId.value);\n animationId.value = null;\n }\n\n if (intersectionObserver) {\n intersectionObserver.disconnect();\n intersectionObserver = null;\n }\n};\n\nwatch(\n [() => props.from, () => props.to, () => props.direction],\n () => {\n currentValue.value = props.direction === 'down' ? props.to : props.from;\n updateDisplay();\n hasStarted.value = false;\n },\n { immediate: true }\n);\n\nwatch(\n () => props.startWhen,\n () => {\n if (props.startWhen && isInView.value && !hasStarted.value) {\n startAnimation();\n }\n }\n);\n\nonMounted(() => {\n updateDisplay();\n setupIntersectionObserver();\n});\n\nonUnmounted(() => {\n cleanup();\n});\n</script>\n","path":"CountUp/CountUp.vue","_imports_":[],"registryDependencies":[],"dependencies":[],"devDependencies":[]}],"registryDependencies":[],"dependencies":[],"devDependencies":[],"categories":["TextAnimations"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/r/PixelSnow.json Normal file

File diff suppressed because one or more lines are too long

1
public/r/PixelTrail.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
public/r/Shuffle.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -549,19 +549,19 @@
"categories": ["Animations"]
},
{
"name": "CountUp",
"title": "CountUp",
"description": "Animated number counter supporting formatting and decimals.",
"name": "PixelTrail",
"title": "PixelTrail",
"description": "Pixel grid trail effect that follows cursor movement with customizable gooey filter.",
"type": "registry:component",
"add": "when-added",
"registryDependencies": [],
"dependencies": [],
"dependencies": [{ "ecosystem": "js", "name": "three", "version": "^0.178.0" }],
"devDependencies": [],
"files": [
{
"type": "registry:component",
"role": "file",
"path": "CountUp/CountUp.vue",
"path": "PixelTrail/PixelTrail.vue",
"registryDependencies": [],
"dependencies": [],
"devDependencies": []
@@ -582,7 +582,28 @@
{
"type": "registry:component",
"role": "file",
"path": "ASCIIText/AsciiText.vue",
"path": "ASCIIText/ASCIIText.vue",
"registryDependencies": [],
"dependencies": [],
"devDependencies": []
}
],
"categories": ["TextAnimations"]
},
{
"name": "CountUp",
"title": "CountUp",
"description": "Animated number counter supporting formatting and decimals.",
"type": "registry:component",
"add": "when-added",
"registryDependencies": [],
"dependencies": [],
"devDependencies": [],
"files": [
{
"type": "registry:component",
"role": "file",
"path": "CountUp/CountUp.vue",
"registryDependencies": [],
"dependencies": [],
"devDependencies": []
@@ -1010,6 +1031,27 @@
],
"categories": ["TextAnimations"]
},
{
"name": "Shuffle",
"title": "Shuffle",
"description": "GSAP-powered slot machine style text shuffle animation with scroll trigger.",
"type": "registry:component",
"add": "when-added",
"registryDependencies": [],
"dependencies": [{ "ecosystem": "js", "name": "gsap", "version": "^3.13.0" }],
"devDependencies": [],
"files": [
{
"type": "registry:component",
"role": "file",
"path": "Shuffle/Shuffle.vue",
"registryDependencies": [],
"dependencies": [],
"devDependencies": []
}
],
"categories": ["TextAnimations"]
},
{
"name": "AnimatedList",
"title": "AnimatedList",
@@ -2391,6 +2433,27 @@
}
],
"categories": ["Backgrounds"]
},
{
"name": "PixelSnow",
"title": "PixelSnow",
"description": "Falling pixelated snow effect with customizable density and speed.",
"type": "registry:component",
"add": "when-added",
"registryDependencies": [],
"dependencies": [{ "ecosystem": "js", "name": "three", "version": "^0.178.0" }],
"devDependencies": [],
"files": [
{
"type": "registry:component",
"role": "file",
"path": "PixelSnow/PixelSnow.vue",
"registryDependencies": [],
"dependencies": [],
"devDependencies": []
}
],
"categories": ["Backgrounds"]
}
]
}