77 <div class =" absolute inset-0 z-0 pointer-events-none overflow-hidden" >
88 <div class =" falling-blocks-container" >
99 <div
10- v-for =" i in 20 "
10+ v-for =" i in blockCount "
1111 :key =" i"
1212 class =" falling-block"
13- :style =" generateBlockStyle()"
13+ :style =" generateBlockStyle(i )"
1414 ></div >
1515 <!-- JSON symbol blocks -->
1616 <div
17- v-for =" i in 10 "
17+ v-for =" i in jsonSymbolCount "
1818 :key =" `json-${i}`"
1919 class =" falling-json-symbol"
20- :style =" generateJsonSymbolStyle()"
20+ :style =" generateJsonSymbolStyle(i )"
2121 >
2222 {{ getRandomJsonSymbol() }}
2323 </div >
@@ -695,41 +695,107 @@ for await (const [value, path] of jsonPathReader(reader, [
695695</template >
696696
697697<script setup>
698- import { onMounted , ref } from " vue"
699698import Logo from " ../components/Logo.vue"
700699import CodeBlock from " ../components/CodeBlock.vue"
700+ import { ref , computed , onMounted , onBeforeUnmount } from " vue"
701+
702+ // Reactive state for screen width
703+ const windowWidth = ref (
704+ typeof window !== " undefined" ? window .innerWidth : 1024
705+ )
706+
707+ // Compute the number of elements based on screen width
708+ const blockCount = computed (() => {
709+ const maxBlocks = 60
710+ const minBlocks = 30
711+
712+ if (windowWidth .value >= 1024 ) {
713+ return maxBlocks
714+ } else if (windowWidth .value <= 320 ) {
715+ return minBlocks
716+ } else {
717+ // Linear interpolation between min and max based on screen width
718+ const ratio = (windowWidth .value - 320 ) / (1024 - 320 )
719+ return Math .round (minBlocks + ratio * (maxBlocks - minBlocks))
720+ }
721+ })
722+
723+ const jsonSymbolCount = computed (() => {
724+ const maxSymbols = 15
725+ const minSymbols = 8
726+
727+ if (windowWidth .value >= 1024 ) {
728+ return maxSymbols
729+ } else if (windowWidth .value <= 320 ) {
730+ return minSymbols
731+ } else {
732+ // Linear interpolation between min and max based on screen width
733+ const ratio = (windowWidth .value - 320 ) / (1024 - 320 )
734+ return Math .round (minSymbols + ratio * (maxSymbols - minSymbols))
735+ }
736+ })
737+
738+ // Window resize handler
739+ const handleResize = () => {
740+ windowWidth .value = window .innerWidth
741+ }
742+
743+ // Set up and clean up the resize listener
744+ onMounted (() => {
745+ window .addEventListener (" resize" , handleResize)
746+ })
747+
748+ onBeforeUnmount (() => {
749+ window .removeEventListener (" resize" , handleResize)
750+ })
701751
702752// Function to get a random JSON symbol
703753const getRandomJsonSymbol = () => {
704- const symbols = [" {" , " }" , " [" , " ]" , " :" , " , " , ' " ' , " . " ]
754+ const symbols = [" {" , " }" , " [" , " ]" , " :" ]
705755 return symbols[Math .floor (Math .random () * symbols .length )]
706756}
707757
708758// Function to generate styles for JSON symbol blocks
709- const generateJsonSymbolStyle = () => {
759+ const generateJsonSymbolStyle = (index ) => {
710760 const left = Math .floor (Math .random () * 100 ) // Position across the screen
711- const delay = Math .random () * 5 // Random delay
712- const duration = Math .random () * 15 + 15 // Animation duration between 15-30s
761+
762+ // Calculate evenly distributed delays based on index
763+ // This creates a consistent stream of elements
764+ const maxDelay = 30 // Maximum delay in seconds
765+ const totalItems = jsonSymbolCount .value
766+ const delay = ((index / totalItems) * maxDelay) % maxDelay // Distribute delays evenly
767+
768+ // Varied durations between 15-25s
769+ const duration = Math .random () * 10 + 15
770+
713771 const size = Math .floor (Math .random () * 20 ) + 20 // Size between 20px and 40px
714- const opacity = Math .random () * 0.1 + 0.05 // Low opacity between 0.05-0.15
772+ const originalOpacity = Math .random () * 0.1 + 0.05 // Low opacity between 0.05-0.15
715773
716774 return {
717775 left: ` ${ left} %` ,
718776 animationDelay: ` ${ delay} s` ,
719777 animationDuration: ` ${ duration} s` ,
720- opacity: opacity,
778+ " --original- opacity" : originalOpacity, // Set as CSS variable
721779 fontSize: ` ${ size} px` ,
722780 transform: ` rotate(${ Math .floor (Math .random () * 20 - 10 )} deg)` , // Slight rotation
723781 }
724782}
725783
726784// Function to generate random styles for falling blocks
727- const generateBlockStyle = () => {
785+ const generateBlockStyle = (index ) => {
728786 const size = Math .floor (Math .random () * 40 ) + 10 // Size between 10px and 50px
729787 const left = Math .floor (Math .random () * 100 ) // Position across the screen
730- const delay = Math .random () * 5 // Random delay
731- const duration = Math .random () * 10 + 10 // Animation duration between 10-20s
732- const opacity = Math .random () * 0.08 + 0.02 // Low opacity between 0.02-0.1
788+
789+ // Calculate evenly distributed delays based on index
790+ // This creates a consistent stream of elements
791+ const maxDelay = 40 // Maximum delay in seconds
792+ const totalItems = blockCount .value
793+ const delay = ((index / totalItems) * maxDelay) % maxDelay // Distribute delays evenly
794+
795+ // Varied durations between 10-20s
796+ const duration = Math .random () * 10 + 10
797+
798+ const originalOpacity = Math .random () * 0.08 + 0.02 // Low opacity between 0.02-0.1
733799
734800 // Choose random shape type
735801 const shapeTypes = [" square" , " rectangle" , " circle" , " diamond" ]
@@ -742,7 +808,7 @@ const generateBlockStyle = () => {
742808 left: ` ${ left} %` ,
743809 animationDelay: ` ${ delay} s` ,
744810 animationDuration: ` ${ duration} s` ,
745- opacity: opacity,
811+ " --original- opacity" : originalOpacity, // Set as CSS variable
746812 transform: ` rotate(${ Math .floor (Math .random () * 360 )} deg)` ,
747813 }
748814
@@ -761,42 +827,6 @@ const generateBlockStyle = () => {
761827
762828 return styles
763829}
764-
765- // Create a grid pattern background effect for code blocks
766- const createBackgroundGridPattern = () => {
767- if (process .client ) {
768- setTimeout (() => {
769- const codeWindows = document .querySelectorAll (" .code-window-content" )
770- codeWindows .forEach ((codeWindow ) => {
771- if (! codeWindow .querySelector (" .bg-grid-pattern" )) {
772- const gridPattern = document .createElement (" div" )
773- gridPattern .classList .add (" bg-grid-pattern" )
774- gridPattern .style .position = " absolute"
775- gridPattern .style .inset = " 0"
776- gridPattern .style .opacity = " 0.05"
777- gridPattern .style .pointerEvents = " none"
778- gridPattern .style .backgroundSize = " 20px 20px"
779- gridPattern .style .backgroundImage =
780- " linear-gradient(to right, rgba(255, 255, 255, 0.1) 1px, transparent 1px), linear-gradient(to bottom, rgba(255, 255, 255, 0.1) 1px, transparent 1px)"
781- codeWindow .appendChild (gridPattern)
782- }
783- })
784- }, 100 )
785- }
786- }
787-
788- // Create a scroll to top function
789- const scrollToTop = () => {
790- window .scrollTo ({
791- top: 0 ,
792- behavior: " smooth" ,
793- })
794- }
795-
796- // Initialize any client-side effects
797- onMounted (() => {
798- createBackgroundGridPattern ()
799- })
800830 </script >
801831
802832<style scoped>
@@ -974,6 +1004,7 @@ onMounted(() => {
9741004 border-radius : 4px ;
9751005 animation : fall linear infinite ;
9761006 z-index : 0 ;
1007+ will-change : transform;
9771008}
9781009
9791010.falling-json-symbol {
@@ -985,14 +1016,25 @@ onMounted(() => {
9851016 animation : fall linear infinite ;
9861017 z-index : 0 ;
9871018 text-shadow : 0 0 5px rgba (59 , 130 , 246 , 0.15 );
1019+ will-change : transform;
9881020}
9891021
9901022@keyframes fall {
9911023 0% {
992- transform : translateY (-100px ) rotate (0deg );
1024+ transform : translateY (-20px ) rotate (0deg );
1025+ opacity : 0 ;
1026+ }
1027+ 2% {
1028+ /* Quick fade in to the pre-set randomized opacity */
1029+ opacity : var (--original-opacity , 0.05 );
1030+ }
1031+ 98% {
1032+ /* Maintain the pre-set randomized opacity until near the end */
1033+ opacity : var (--original-opacity , 0.05 );
9931034 }
9941035 100% {
995- transform : translateY (100vh ) rotate (360deg );
1036+ transform : translateY (calc (100vh + 40px )) rotate (360deg );
1037+ opacity : 0 ;
9961038 }
9971039}
9981040 </style >
0 commit comments