bsc

Comprehensive codebase and cou...
Log | Files | Refs | README | LICENSE

commit 370d1a5c28d44b0997b8e5f73208e89efbaedefd
parent ebd15a137f3f9fdcaac6e93f45b0275540d39e76
Author: Amit Dutta <amitdutta4255@gmail.com>
Date:   Mon, 22 Jun 2026 19:22:23 +0530

added sponser button

Diffstat:
Ddocs/.vitepress/theme/components/ArticleAd.vue | 40----------------------------------------
Ddocs/.vitepress/theme/components/FloatingAd.vue | 108-------------------------------------------------------------------------------
Adocs/.vitepress/theme/components/Footer.vue | 33+++++++++++++++++++++++++++++++++
Adocs/.vitepress/theme/components/SponsorButton.vue | 190+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdocs/.vitepress/theme/index.ts | 8++++----
5 files changed, 227 insertions(+), 152 deletions(-)

diff --git a/docs/.vitepress/theme/components/ArticleAd.vue b/docs/.vitepress/theme/components/ArticleAd.vue @@ -1,39 +0,0 @@ -<template> - <div class="article-ad-container"> - <span class="ad-label">ADVERTISEMENT</span> - - <!-- EXACT A-ADS ADAPTIVE UNIT --> - <div id="frame" style="width: 100%; margin: auto; position: relative; z-index: 99998;"> - <iframe - data-aa='2445210' - src='//acceptable.a-ads.com/2445210/?size=Adaptive' - style='border:0; padding:0; width:70%; height:90px; overflow:hidden; display: block; margin: auto' - allowtransparency='true'> - </iframe> - </div> - - </div> -</template> - -<style scoped> -.article-ad-container { - margin-top: 2rem; - padding: 1rem; - background: var(--vp-c-bg-elv); - border: 1px solid var(--vp-c-divider); - border-radius: 12px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; -} - -.ad-label { - font-size: 10px; - font-weight: 700; - color: var(--vp-c-text-3); - letter-spacing: 0.5px; - margin-bottom: 12px; -} -</style>- \ No newline at end of file diff --git a/docs/.vitepress/theme/components/FloatingAd.vue b/docs/.vitepress/theme/components/FloatingAd.vue @@ -1,107 +0,0 @@ -<script setup lang="ts"> -import { ref } from 'vue' - -const isVisible = ref(true) - -const closeAd = () => { - isVisible.value = false -} -</script> - -<template> - <Transition name="slide-up" appear> - <div v-if="isVisible" class="floating-ad-container"> - <!-- Header zone for the button and label so they never touch the iframe --> - <div class="ad-header"> - <span class="ad-label">ADVERTISEMENT</span> - <button class="close-btn" @click="closeAd" aria-label="Close Ad">×</button> - </div> - - <!-- Isolated content zone purely for the 125x125 ad --> - <div class="ad-content"> - <iframe - data-aa='2445210' - src='//ad.a-ads.com/2445210/?size=125x125' - style='border:0; padding:0; width:125px; height:125px; overflow:hidden; display:block; margin:0;' - allowtransparency='true'> - </iframe> - </div> - </div> - </Transition> -</template> - -<style scoped> -.floating-ad-container { - position: fixed; - bottom: 24px; - right: 24px; - /* Expanded size to ensure zero overlap with the 125x125 ad */ - width: 145px; - height: 165px; - - background: var(--vp-c-bg-elv); - border: 1px solid var(--vp-c-divider); - border-radius: 12px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); - /* Maximum z-index to ensure it sits on top of all VitePress UI elements */ - z-index: 99999; - - display: flex; - flex-direction: column; - align-items: center; - overflow: hidden; - padding: 6px; - box-sizing: border-box; -} - -.ad-header { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - height: 20px; - margin-bottom: 4px; - padding: 0 4px; - box-sizing: border-box; -} - -.ad-label { - font-size: 9px; - font-weight: 700; - color: var(--vp-c-text-3); - letter-spacing: 0.5px; -} - -.close-btn { - font-size: 20px; - color: var(--vp-c-text-2); - background: none; - border: none; - cursor: pointer; - line-height: 1; - padding: 0; -} - -.close-btn:hover { - color: var(--vp-c-text-1); -} - -.ad-content { - width: 125px; - height: 125px; - display: block; - clear: both; -} - -/* Slide-In Animation */ -.slide-up-enter-active, -.slide-up-leave-active { - transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.25, 1, 0.5, 1); -} - -.slide-up-enter-from, -.slide-up-leave-to { - opacity: 0; - transform: translateY(40px) scale(0.95); -} -</style>- \ No newline at end of file diff --git a/docs/.vitepress/theme/components/Footer.vue b/docs/.vitepress/theme/components/Footer.vue @@ -0,0 +1,33 @@ +<template> + <footer class="simple-footer"> + <p> + Released under the + <a href="https://github.com" target="_blank" rel="noopener noreferrer" class="footer-link">MIT License</a>. + </p> + <p>Copyright (c) 2025-present <a href="https://amit.is-a.dev" target="_blank" rel="noopener noreferrer" class="footer-link">Amit Dutta</a></p> + </footer> +</template> + +<style scoped> +.simple-footer { + margin-top: 3rem; + padding-top: 1.5rem; + border-top: 1px solid var(--vp-c-divider); + text-align: center; + font-size: 13px; + color: var(--vp-c-text-2); + line-height: 1.5; +} + +.footer-link { + color: var(--vp-c-brand-1); + text-decoration: none; + font-weight: 500; + transition: color 0.2s ease; +} + +.footer-link:hover { + color: var(--vp-c-brand-2); + text-decoration: underline; +} +</style> diff --git a/docs/.vitepress/theme/components/SponsorButton.vue b/docs/.vitepress/theme/components/SponsorButton.vue @@ -0,0 +1,189 @@ +<script setup lang="ts"> +import { ref, onMounted } from 'vue' + +const particles = ref<SVGElement[]>([]) +const isBeating = ref(false) +const isTouchDevice = ref(false) + +onMounted(() => { + isTouchDevice.value = window.matchMedia('(hover: none) and (pointer: coarse)').matches +}) + +// Varied colors like anime.js — different pinks, reds, corals +const particleColors = [ + '#ff4772', '#ff6b9d', '#ff3355', '#ff8fab', + '#e91e63', '#f06292', '#ff1744', '#ff80ab' +] + +const triggerBurst = () => { + if (isTouchDevice.value || !particles.value?.length) return + + // Cancel any running animations first so re-hover always works + particles.value.forEach((particle, i) => { + particle.getAnimations().forEach(a => a.cancel()) + + const angle = (i / particles.value.length) * Math.PI * 2 + (Math.random() - 0.5) * 0.6 + const distance = 28 + Math.random() * 32 + const tx = Math.cos(angle) * distance + const ty = Math.sin(angle) * distance + const size = 0.6 + Math.random() * 0.8 // vary particle size + + // Random color from palette + const color = particleColors[Math.floor(Math.random() * particleColors.length)]; + (particle as SVGElement & { style: CSSStyleDeclaration }).style.color = color + + particle.animate([ + { + transform: `translate(0px, 0px) scale(${size})`, + opacity: 1, + visibility: 'visible' + }, + { + transform: `translate(${tx * 0.4}px, ${ty * 0.4}px) scale(${size * 1.1})`, + opacity: 1, + offset: 0.2 + }, + { + transform: `translate(${tx}px, ${ty}px) scale(0)`, + opacity: 0, + visibility: 'hidden' + } + ], { + duration: 500 + Math.random() * 250, + easing: 'cubic-bezier(0.25, 1, 0.5, 1)', + fill: 'forwards' + }) + }) + + // Heart beat + isBeating.value = true + setTimeout(() => { isBeating.value = false }, 400) +} +</script> + +<template> + <div class="sponsor-wrapper"> + <a + href="https://github.com/sponsors/notamitgamer" + class="sponsor-button" + target="_blank" + title="Sponsor Amit Dutta on GitHub" + @mouseenter="triggerBurst" + @click="triggerBurst" + :class="{ 'mobile-pill': isTouchDevice }" + > + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="4 7 16 12" + class="icon heart-icon" + :class="{ beating: isBeating }" + > + <path + fill="currentColor" + d="M12 18.445a.778.778 0 0 1-.34-.078C11.39 18.235 5 15.077 5 9.889a3.889 3.889 0 0 1 6.638-2.75L12 7.5l.362-.361A3.889 3.889 0 0 1 19 9.889c0 5.17-6.387 8.344-6.66 8.478a.778.778 0 0 1-.34.078z" + /> + </svg> + <span>Sponsor</span> + </a> + + <!-- Burst particles — desktop only --> + <svg + v-if="!isTouchDevice" + v-for="i in 12" + :key="i" + ref="particles" + xmlns="http://www.w3.org/2000/svg" + viewBox="4 7 16 12" + class="particle" + > + <path + fill="currentColor" + d="M12 18.445a.778.778 0 0 1-.34-.078C11.39 18.235 5 15.077 5 9.889a3.889 3.889 0 0 1 6.638-2.75L12 7.5l.362-.361A3.889 3.889 0 0 1 19 9.889c0 5.17-6.387 8.344-6.66 8.478a.778.778 0 0 1-.34.078z" + /> + </svg> + </div> +</template> + +<style scoped> +.sponsor-wrapper { + position: relative; + display: inline-flex; + align-items: center; + margin-left: 8px; +} + +.sponsor-button { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 5px 12px 5px 10px; + background-color: transparent; + color: var(--vp-c-text-1, #3c3c43); + font-size: 13px; + font-weight: 500; + border-radius: 20px; + transition: + background-color 0.2s ease, + color 0.2s ease; + text-decoration: none; + position: relative; + z-index: 2; + white-space: nowrap; + cursor: pointer; +} + +.sponsor-button:hover { + background-color: rgba(255, 71, 114, 0.1); + color: #ff4772; +} + +/* Heart icon */ +.heart-icon { + width: 15px; + height: 15px; + color: #ff4772; + flex-shrink: 0; + transition: transform 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.sponsor-button:hover .heart-icon { + transform: scale(1.2); +} + +/* Beat animation triggered on click */ +.heart-icon.beating { + animation: heartbeat 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +@keyframes heartbeat { + 0% { transform: scale(1); } + 40% { transform: scale(1.4); } + 70% { transform: scale(0.9); } + 100% { transform: scale(1.2); } +} + +/* Mobile: static pink pill, no hover/animation */ +.mobile-pill { + background-color: rgba(255, 71, 114, 0.12); + color: #ff4772; +} + +.mobile-pill .heart-icon { + color: #ff4772; +} + +.particle { + position: absolute; + top: 50%; + left: 18px; /* roughly where the heart icon center sits */ + width: 10px; + height: 10px; + margin-top: -5px; + margin-left: -5px; + color: #ff4772; + visibility: hidden; + opacity: 0; + pointer-events: none; + z-index: 1; +} +</style>+ \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts @@ -1,9 +1,9 @@ import { h } from 'vue' import DefaultTheme from 'vitepress/theme' import type { Theme } from 'vitepress' -import CodePage from './CodePage.vue' import TermsBanner from './components/TermsBanner.vue' -import FloatingAd from './components/ArticleAd.vue' +import Footer from './components/Footer.vue' +import SponsorButton from './components/SponsorButton.vue' import './style.css' export default { @@ -12,8 +12,8 @@ export default { Layout() { return h(DefaultTheme.Layout, null, { 'layout-bottom': () => h(TermsBanner), - - 'doc-after': () => h(FloatingAd) + 'doc-after': () => h(Footer), + 'nav-bar-content-after': () => h(SponsorButton) }) } } satisfies Theme \ No newline at end of file
© notamitgamer • Site Built: 2026-07-21 13:58:23 UTC • git-mirror commit: 1037f62 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror