Showcase

Animations from past Functn projects, adapted for TaylorUI. Copy the components into your project and wire them up to your own data.


This Product carousel is copied from the functndev/wsk-bank-relaunch project and adapted to TaylorUI. See it live in the Unsere Produkte section on wsk-bank.at.

The carousel combines TaylorUI carousel primitives with embla-carousel-fade so slides crossfade in place. A fixed text region above animates title and description on slide change (fadeUp from @/animations). The thumbnail rail below expands the active item and accepts clicks to jump between slides.

To reuse in your project:

  1. Copy src/ui/components/carousel/product-carousel.tsx into your app.
  2. Ensure TaylorUI carousel primitives are available (see file list below).
  3. Install embla-carousel-fade alongside embla-carousel-react.
  4. Replace placeholderProductList in @/assets with your own slide data — each slide needs a title, description, optional links, and an image.

Files to copy (skip any your project already has):

  • src/ui/components/carousel/product-carousel.tsx
  • src/ui/components/carousel/carousel.tsx
  • src/lib/cn.ts
  • src/animations/framer/variants.ts (for fadeUp)

Dependencies: embla-carousel-react, embla-carousel-fade, framer-motion, next, react

import { ProductCarouselShowcase } from '@/ui/components/carousel/product-carousel';
 
// Renders with placeholder slides from @/assets.
export function ProductsSection() {
  return (
    <section>
      <ProductCarouselShowcase />
    </section>
  );
}

To customise slide content, map your data to the ProductSlide type from @/assets:

import type { ProductSlide } from '@/assets';
 
const products: ProductSlide[] = items.map((item) => ({
  productTitle: item.title,
  productText: item.description,
  productLinks: item.links,
  image: item.image,
}));

Animated Buttons

Uses Framer Motion's layoutId inside a LayoutGroup to smoothly morph between two buttons with different positions and sizes as you scroll. The button starts small at the top-left and grows into a large variant at the bottom-right once the container reaches the viewport center — scrolling back reverses the animation.

Wrap both button positions in LayoutGroup, give each motion.div the same layoutId, and use useScroll to toggle between them. AnimatePresence keeps the exiting button alive so the morph is seamless.

import {
  AnimatePresence,
  LayoutGroup,
  motion,
  useMotionValueEvent,
  useScroll,
} from 'framer-motion';
 
function AnimatedButton() {
  const ref = useRef(null);
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ['start end', 'center center'],
  });
  const [showFirst, setShowFirst] = useState(true);
  useMotionValueEvent(scrollYProgress, 'change', (v) => setShowFirst(v < 0.8));
 
  return (
    <LayoutGroup>
      <div ref={ref} className="relative h-[50vh]">
        <AnimatePresence initial={false}>
          {showFirst ? (
            <motion.div
              key="first"
              layoutId="my-button"
              className="absolute top-8 left-8"
            >
              <Button size="small">Small</Button>
            </motion.div>
          ) : (
            <motion.div
              key="second"
              layoutId="my-button"
              className="absolute right-8 bottom-8"
            >
              <Button size="large">Large</Button>
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    </LayoutGroup>
  );
}

Hero entrance

This Hero entrance animation is adapted from the functndev/arian project and simplified for TaylorUI. See it live on the Arian homepage. It demonstrates a phased full-screen hero reveal on page load.

A full-viewport hero fades in a background image, then reveals content in stages using heroPhase state and timed transitions. Framer Motion handles opacity and slide-up on the color info, cycling facts, headline, and CTA. Facts rotate automatically via a simplified SlidingFacts helper.

To reuse in your project:

  1. Copy src/animations/components/hero-home-showcase.tsx into your app.
  2. Ensure ButtonLink and cn are available (see file list below).
  3. Edit the placeholder constants at the top of the copied file.
  4. Adjust timer values (900ms / 1600ms) to change pacing.

Files to copy (skip any your project already has):

  • src/animations/components/hero-home-showcase.tsx
  • src/ui/components/button/button-link.tsx
  • src/lib/cn.ts
  • src/assets/index.ts (or provide your own hero image)

Dependencies: framer-motion, next, react

import { HeroHomeShowcase } from '@/animations/components/hero-home-showcase';
 
// Renders with placeholder image and copy baked into the component.
export function HomeHero() {
  return <HeroHomeShowcase />;
}

To customise content, edit the constants at the top of hero-home-showcase.tsx:

import { placeholderImages } from '@/assets';
 
const PLACEHOLDER_HERO_IMAGE = placeholderImages.underwater;
const PLACEHOLDER_FACTS = ['Fact one', 'Fact two', 'Fact three'];
const PLACEHOLDER_COLOR = { name: 'Ocean Blue', code: '#155dfc' };
const PLACEHOLDER_CONTENT = {
  brandName: 'Brand Name',
  heading: 'Your headline',
  ctaLabel: 'Call to action',
  ctaHref: '/your-link',
};

The showcase uses an image background only (no video). Scroll-based CTA morphing from the original Arian hero is omitted — it requires a global scroll context.

Underwater
Color of the day
Ocean Blue#155dfc

Print this color on your next project

Founded in 1985

Brand Name

Crafted with precision

Learn more