diff --git a/LOGO_CAROUSEL_IMPLEMENTATION.md b/LOGO_CAROUSEL_IMPLEMENTATION.md deleted file mode 100644 index 3ad011202..000000000 --- a/LOGO_CAROUSEL_IMPLEMENTATION.md +++ /dev/null @@ -1,98 +0,0 @@ -# Logo Carousel Component Implementation - -## Summary - -Successfully implemented the infinite logo carousel component as requested in issue #5660. - -## Files Created - -### 1. Component Files - -- `libs/ui/src/lib/logo-carousel/logo-carousel.component.ts` - Main component logic -- `libs/ui/src/lib/logo-carousel/logo-carousel.component.html` - Template -- `libs/ui/src/lib/logo-carousel/logo-carousel.component.scss` - Styles with CSS animation -- `libs/ui/src/lib/logo-carousel/index.ts` - Export file -- `libs/ui/src/lib/logo-carousel/logo-carousel.component.stories.ts` - Storybook story - -### 2. Modified Files - -- `apps/client/src/app/pages/landing/landing-page.component.ts` - Added import and component usage -- `apps/client/src/app/pages/landing/landing-page.html` - Replaced static logo grid with carousel - -## Implementation Details - -### Features Implemented - -✅ **Pure CSS Animation**: Uses `@keyframes` for infinite horizontal scrolling -✅ **Responsive Design**: Adapts to different screen sizes (mobile, tablet, desktop) -✅ **Accessibility**: - -- Proper ARIA labels -- Pause animation on hover -- Screen reader friendly - ✅ **Dark Theme Support**: Automatic theme switching - ✅ **Performance**: -- CSS-only animation (no JavaScript) -- Uses `transform: translateX()` for GPU acceleration - ✅ **Seamless Loop**: Duplicates logos for continuous scrolling - ✅ **Interactive**: Hover effects with scaling and opacity changes - -### Technical Approach - -- **Animation Technique**: Duplicates the logo set and uses CSS `translateX(-50%)` to create seamless infinite scroll -- **Browser Compatibility**: Added `-webkit-` prefixes for mask properties -- **Styling**: Copied and adapted existing logo styles from landing page -- **Theming**: Uses CSS custom properties for theme-aware gradients - -### Animation Details - -- **Duration**: 40 seconds for full cycle -- **Direction**: Left to right horizontal scroll -- **Easing**: Linear for consistent speed -- **Interaction**: Pauses on hover for accessibility - -### CSS Features - -- Gradient fade masks on left/right edges for smooth visual effect -- Responsive logo sizing (3rem height on desktop, scales down on mobile) -- Hover effects with 1.05x scale and opacity fade -- Proper mask image handling for SVG logos - -## Integration - -The component is integrated into the landing page replacing the previous static 4-column logo grid. The "As seen in" text remains above the carousel. - -## Browser Support - -- Modern browsers with CSS mask support -- Fallback styles for older browsers -- Responsive design for all device sizes - -## Usage - -```html - -``` - -The component is self-contained and requires no additional configuration. - -## Testing Recommendations - -1. Test on different screen sizes -2. Verify smooth animation performance -3. Check accessibility with screen readers -4. Test dark/light theme switching -5. Verify all logo links work correctly - -## Next Steps - -1. Install dependencies: `npm install` -2. Build application: `npm run build:production` -3. Test in browser: `npm run start:client` -4. View in Storybook: `npm run start:storybook` - -The implementation follows the exact requirements from issue #5660: - -- ✅ Standalone Angular component at `@ghostfolio/ui/logo-carousel` -- ✅ Pure CSS infinite scrolling animation -- ✅ Integrated into landing page replacing static logos diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index 0de16ab05..589353861 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -115,7 +115,7 @@ As seen in
- +
diff --git a/apps/client/src/app/pages/landing/landing-page.scss b/apps/client/src/app/pages/landing/landing-page.scss index 4c0c14efd..35f362b0f 100644 --- a/apps/client/src/app/pages/landing/landing-page.scss +++ b/apps/client/src/app/pages/landing/landing-page.scss @@ -34,69 +34,6 @@ &.logo-agplv3 { mask-image: url('/assets/images/logo-AGPLv3.svg'); } - - &.logo-alternative-to { - mask-image: url('/assets/images/logo-alternative-to.svg'); - } - - &.logo-awesome { - background-image: url('/assets/images/logo-awesome.png'); - background-position: center; - background-repeat: no-repeat; - background-size: contain; - filter: grayscale(1); - } - - &.logo-dev-community { - mask-image: url('/assets/images/logo-dev-community.svg'); - } - - &.logo-hacker-news { - mask-image: url('/assets/images/logo-hacker-news.svg'); - } - - &.logo-openalternative { - mask-image: url('/assets/images/logo-openalternative.svg'); - } - - &.logo-privacy-tools { - mask-image: url('/assets/images/logo-privacy-tools.svg'); - } - - &.logo-product-hunt { - background-image: url('/assets/images/logo-product-hunt.png'); - background-position: center; - background-repeat: no-repeat; - background-size: contain; - filter: grayscale(1); - } - - &.logo-reddit { - mask-image: url('/assets/images/logo-reddit.svg'); - max-height: 1rem; - } - - &.logo-sackgeld { - mask-image: url('/assets/images/logo-sackgeld.png'); - } - - &.logo-selfh-st { - mask-image: url('/assets/images/logo-selfh-st.svg'); - max-height: 1.25rem; - } - - &.logo-sourceforge { - mask-image: url('/assets/images/logo-sourceforge.svg'); - } - - &.logo-umbrel { - mask-image: url('/assets/images/logo-umbrel.svg'); - max-height: 1.5rem; - } - - &.logo-unraid { - mask-image: url('/assets/images/logo-unraid.svg'); - } } .outro-inner-container { @@ -128,18 +65,7 @@ } .logo { - &.logo-agplv3, - &.logo-alternative-to, - &.logo-dev-community, - &.logo-hacker-news, - &.logo-openalternative, - &.logo-privacy-tools, - &.logo-reddit, - &.logo-sackgeld, - &.logo-selfh-st, - &.logo-sourceforge, - &.logo-umbrel, - &.logo-unraid { + &.logo-agplv3 { background-color: rgba(var(--light-primary-text)); } } diff --git a/libs/ui/src/lib/logo-carousel/interfaces/interfaces.ts b/libs/ui/src/lib/logo-carousel/interfaces/interfaces.ts new file mode 100644 index 000000000..43dcfeefd --- /dev/null +++ b/libs/ui/src/lib/logo-carousel/interfaces/interfaces.ts @@ -0,0 +1,7 @@ +export interface LogoItem { + className: string; + isMask?: boolean; + name: string; + title: string; + url: string; +} diff --git a/libs/ui/src/lib/logo-carousel/logo-carousel.component.html b/libs/ui/src/lib/logo-carousel/logo-carousel.component.html index 06422f298..4f7dd3493 100644 --- a/libs/ui/src/lib/logo-carousel/logo-carousel.component.html +++ b/libs/ui/src/lib/logo-carousel/logo-carousel.component.html @@ -1,7 +1,9 @@