390390 }
391391 /* --------------------------------- */
392392
393+ /* --- Logo Carousel Styling --- */
394+ .logo-carousel-container {
395+ width : 100% ;
396+ overflow : hidden;
397+ margin-top : 1.5rem ; /* Space below the h2 of this section */
398+ }
399+
400+ .logo-carousel-track {
401+ display : flex;
402+ /* CSS animation removed, JS will handle it */
403+ }
404+
405+ .logo-carousel-track img {
406+ height : 80px ; /* Adjust default logo height as needed */
407+ width : auto; /* Maintain aspect ratio */
408+ margin : 0 ; /* Ensures 0px gap between image elements */
409+ padding : 0 ; /* Ensures 0px padding around image content */
410+ flex-shrink : 0 ; /* Prevent logos from shrinking */
411+ }
412+
413+ /* CSS animation keyframes removed */
414+ /* --- End Logo Carousel Styling --- */
415+
416+ .logo-carousel-title {
417+ font-size : 1rem ; /* Smaller than default h2, e.g., 18px */
418+ color : # 666 ; /* Grey color */
419+ text-align : center;
420+ border-bottom : none; /* Remove underline from default h2 style */
421+ margin-top : 2rem ; /* Adjust top margin as needed */
422+ margin-bottom : 1rem ; /* Space before the carousel */
423+ font-weight : 500 ; /* Lighter than default h2 */
424+ padding-bottom : 0 ; /* Remove padding from default h2 style */
425+ }
426+
393427 /* --- Footer Disclaimer Styling --- */
394428 .disclaimer {
395429 font-size : 0.75rem ; /* Smaller text */
@@ -464,6 +498,27 @@ <h1>Open-Simples</h1>
464498 </ header >
465499
466500 < main >
501+ < div class ="logo-carousel-container ">
502+ < h2 class ="logo-carousel-title "> Made & Used by people at</ h2 >
503+
504+ < div class ="logo-carousel-track ">
505+ <!-- First set of logos - Replace with your actual SVG paths -->
506+ < img src ="logos/logo1.svg " alt ="Company 1 Logo ">
507+ < img src ="logos/logo2.svg " alt ="Company 2 Logo ">
508+ < img src ="logos/logo3.svg " alt ="Company 3 Logo ">
509+ < img src ="logos/logo4.svg " alt ="Company 4 Logo ">
510+ < img src ="logos/logo5.svg " alt ="Company 5 Logo ">
511+ < img src ="logos/logo6.svg " alt ="Company 6 Logo ">
512+ <!-- Second set of logos (for seamless loop) - Replace with your actual SVG paths -->
513+ < img src ="logos/logo1.svg " alt ="Company 1 Logo ">
514+ < img src ="logos/logo2.svg " alt ="Company 2 Logo ">
515+ < img src ="logos/logo3.svg " alt ="Company 3 Logo ">
516+ < img src ="logos/logo4.svg " alt ="Company 4 Logo ">
517+ < img src ="logos/logo5.svg " alt ="Company 5 Logo ">
518+ < img src ="logos/logo6.svg " alt ="Company 6 Logo ">
519+ </ div >
520+ </ div >
521+
467522 < h2 > Repos</ h2 >
468523 < div id ="tag-filters ">
469524 <!-- Tag filters will be generated here -->
@@ -822,6 +877,99 @@ <h3><a href="${repo.html_url}" target="_blank" rel="noopener noreferrer">${repo.
822877 }
823878 } ) ;
824879 }
880+
881+ // --- Logo Carousel JS Animation ---
882+ document . addEventListener ( 'DOMContentLoaded' , ( ) => {
883+ const track = document . querySelector ( '.logo-carousel-track' ) ;
884+ if ( ! track ) {
885+ console . warn ( "Logo carousel track not found." ) ;
886+ return ;
887+ }
888+
889+ const logos = Array . from ( track . children ) ;
890+ if ( logos . length === 0 ) {
891+ console . warn ( "No logos found in carousel track." ) ;
892+ return ;
893+ }
894+ // Ensure we have an even number for duplication, otherwise this logic won't work well.
895+ // The HTML should already have duplicates.
896+ const originalLogosCount = logos . length / 2 ;
897+
898+ let scrollAmount = 0 ;
899+ const scrollSpeed = 0.5 ; // Pixels per frame. Adjust for speed.
900+ let animationFrameId = null ;
901+ let scrollWidth = 0 ;
902+
903+ function calculateScrollWidth ( ) {
904+ let width = 0 ;
905+ for ( let i = 0 ; i < originalLogosCount ; i ++ ) {
906+ if ( logos [ i ] ) width += logos [ i ] . offsetWidth ;
907+ }
908+ return width ;
909+ }
910+
911+ function startAnimationSequence ( ) {
912+ scrollWidth = calculateScrollWidth ( ) ;
913+ if ( scrollWidth > 0 && ! animationFrameId ) {
914+ animateLogos ( ) ;
915+ } else if ( scrollWidth === 0 ) {
916+ console . warn ( "Logo carousel scroll width is 0. Animation will not start until images load or have width." ) ;
917+ }
918+ }
919+
920+ // Initial calculation and animation start attempt
921+ // We need to make sure images (especially SVGs) are loaded to get correct offsetWidth
922+ let imagesToLoad = logos . filter ( logo => logo . tagName === 'IMG' && ! logo . complete ) . length ;
923+ if ( imagesToLoad === 0 ) { // All images already loaded (e.g. cached or not IMG tags)
924+ startAnimationSequence ( ) ;
925+ } else {
926+ logos . forEach ( logo => {
927+ if ( logo . tagName === 'IMG' && ! logo . complete ) {
928+ logo . onload = logo . onerror = ( ) => {
929+ imagesToLoad -- ;
930+ if ( imagesToLoad === 0 ) {
931+ startAnimationSequence ( ) ;
932+ }
933+ } ;
934+ }
935+ } ) ;
936+ }
937+
938+ function animateLogos ( ) {
939+ if ( scrollWidth <= 0 ) { // Safety check
940+ animationFrameId = null ; // Stop animation if width is invalid
941+ return ;
942+ }
943+ scrollAmount -= scrollSpeed ;
944+ // When the first set of logos has scrolled completely out of view
945+ if ( Math . abs ( scrollAmount ) >= scrollWidth ) {
946+ scrollAmount += scrollWidth ; // Reset position
947+ }
948+ track . style . transform = `translateX(${ scrollAmount } px)`
949+ animationFrameId = requestAnimationFrame ( animateLogos ) ;
950+ }
951+
952+ /* // Optional: Pause on hover - REMOVED
953+ track.addEventListener(\'mouseenter\', () => {\n if (animationFrameId) {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = null;\n }\n });\n
954+ track.addEventListener(\'mouseleave\', () => {\n if (!animationFrameId && scrollWidth > 0) { // Only restart if not already running and width is valid\n animateLogos();\n }\n });
955+ */
956+
957+ let resizeTimeout ;
958+ window . addEventListener ( 'resize' , ( ) => {
959+ if ( animationFrameId ) {
960+ cancelAnimationFrame ( animationFrameId ) ;
961+ animationFrameId = null ;
962+ }
963+ track . style . transform = `translateX(0px)` ; // Reset visually before recalc
964+ scrollAmount = 0 ;
965+
966+ clearTimeout ( resizeTimeout ) ;
967+ resizeTimeout = setTimeout ( ( ) => {
968+ startAnimationSequence ( ) ; // Recalculate and restart animation
969+ } , 250 ) ; // Debounce resize handling
970+ } ) ;
971+ } ) ;
972+ // --- End Logo Carousel JS Animation ---
825973 </ script >
826974</ body >
827975</ html >
0 commit comments