Files
healthy_oil/docs/CYCLING_IMAGE_COMPONENT.md
2025-10-25 16:13:58 +08:00

7.8 KiB

CyclingImage Component Documentation

Overview

CyclingImage is a dynamic React component that implements continuous light-to-dark color cycling animations on images while maintaining full responsive positioning across all viewport sizes. The component features smooth transition effects that oscillate between light and dark themes with customizable settings.

Features

Smooth Animations: Hardware-accelerated CSS animations for optimal performance
Fully Responsive: Works with all Chakra UI responsive props (base, sm, md, lg, xl)
Flexible Positioning: Maintains absolute/relative positioning
Customizable Duration: Adjust cycle speed from 0.5s to 10s+
Adjustable Intensity: Control brightness range from 0% to 100%
Multiple Timing Functions: Support for ease, linear, cubic-bezier, and more
Interactive Controls: Optional play/pause and real-time adjustments
Auto-start or Paused: Choose initial animation state
Minimal Performance Impact: Efficient CSS-based implementation

Installation

The component is located at:

src/components/new_ui/CyclingImage.tsx

Basic Usage

import CyclingImage from './components/new_ui/CyclingImage'

function MyComponent() {
  return (
    <CyclingImage 
      src="/images/my-image.png"
      position="absolute"
      w="200px"
      left="50px"
      top="100px"
    />
  )
}

Props API

Prop Type Default Description
src string required Image source URL
position CSSProperties['position'] 'relative' CSS position value
w any - Width (supports responsive objects)
left any - Left position (supports responsive objects)
top any - Top position (supports responsive objects)
right any - Right position (supports responsive objects)
bottom any - Bottom position (supports responsive objects)
cycleDuration number 3 Duration of one cycle in seconds
intensity number 0.5 Brightness variation (0-1)
timingFunction string 'ease-in-out' CSS timing function
showControls boolean false Display interactive controls
autoStart boolean true Auto-start animation
style CSSProperties {} Additional CSS styles

Usage Examples

1. Default Configuration

Simple usage with default settings (3s cycle, 50% intensity):

<CyclingImage 
  src="/images/logo.png"
  position="absolute"
  w="150px"
  left="20px"
  top="30px"
/>

2. Responsive Positioning

Using Chakra UI responsive objects:

<CyclingImage 
  src="/images/warning.png"
  position="absolute"
  w={{ base: "100px", sm: "120px", md: "150px", lg: "11vw", xl: "10vw" }}
  left={{ base: "20px", sm: "30px", md: "40px", lg: "30vw", xl: "37vw" }}
  top={{ base: "3vw", sm: "3vw", md: "3vw", lg: "7vw", xl: "3vw" }}
  cycleDuration={4}
  intensity={0.6}
/>

3. With Interactive Controls

Enable user controls for play/pause and adjustments:

<CyclingImage 
  src="/images/hero.png"
  position="absolute"
  w="300px"
  left="100px"
  top="50px"
  showControls={true}
  cycleDuration={5}
  intensity={0.7}
/>

4. Fast Pulse Effect

Quick pulsing animation:

<CyclingImage 
  src="/images/alert.png"
  position="absolute"
  w="100px"
  left="50px"
  top="50px"
  cycleDuration={1}
  intensity={0.8}
/>

5. Slow Breathing Effect

Gentle, subtle animation:

<CyclingImage 
  src="/images/background.png"
  position="absolute"
  w="100%"
  left="0"
  top="0"
  cycleDuration={8}
  intensity={0.3}
  timingFunction="linear"
/>

6. Custom Timing Function

Using cubic-bezier for unique effects:

<CyclingImage 
  src="/images/element.png"
  position="absolute"
  w="200px"
  left="50%"
  top="50%"
  style={{ transform: 'translate(-50%, -50%)' }}
  cycleDuration={5}
  intensity={0.7}
  timingFunction="cubic-bezier(0.68, -0.55, 0.265, 1.55)"
/>

7. Paused by Default

Start with animation paused:

<CyclingImage 
  src="/images/static.png"
  position="absolute"
  w="200px"
  left="50px"
  top="50px"
  autoStart={false}
  showControls={true}
/>

Integration Example

Here's how it's integrated in the hero1.tsx component:

import { Box, Image, Stack } from '@chakra-ui/react'
import CyclingImage from './CyclingImage'

function Hero1() {
  return (
    <Box position="relative" w="100%">
      <Stack gap={0}>
        <Box
          position="relative"
          w="100%"
          minH={{ base: "100vh", lg: "70vw", xl: "45vw" }}
          bgImage={"url('/images/new/confuse.webp')"}
          bgSize="cover"
        >
          {/* Warning Text with Animation */}
          <CyclingImage 
            src="/images/new/threehightext.webp"
            position={'absolute'}
            w={{ base: "100px", sm: "120px", md: "150px", lg: "11vw", xl: "10vw" }}
            left={{ base: "20px", sm: "30px", md: "40px", lg: "30vw", xl: "37vw" }}
            top={{ base: "3vw", sm: "3vw", md: "3vw", lg: "7vw", xl: "3vw" }}
            cycleDuration={4}
            intensity={0.6}
          />
          
          {/* Static images remain unchanged */}
          <Image src="/images/new/fattext.webp"
            position={'absolute'}
            w={{ base: "100px", sm: "120px", md: "150px", lg: "10vw", xl: "9vw" }}
            left={{ base: "25vw", sm: "25vw", md: "25vw", lg: "18vw", xl: "25vw" }}
            top={{ base: "14vw", sm: "14vw", md: "14vw", lg: "20vw", xl: "14vw" }}
          />
        </Box>
      </Stack>
    </Box>
  )
}

Control Panel

When showControls={true}, the component displays an interactive control panel with:

  • Play/Pause Button: Toggle animation on/off
  • Speed Slider: Adjust cycle duration (0.5s - 10s)
  • Intensity Slider: Adjust brightness variation (0% - 100%)

Animation Details

The component uses CSS filter: brightness() with keyframe animations:

@keyframes lightToDarkCycle {
  0% {
    filter: brightness(1 + intensity); /* Light */
  }
  50% {
    filter: brightness(1 - intensity); /* Dark */
  }
  100% {
    filter: brightness(1 + intensity); /* Back to light */
  }
}

Intensity Examples:

  • 0.3 → brightness range: 0.7 to 1.3 (subtle)
  • 0.5 → brightness range: 0.5 to 1.5 (moderate)
  • 0.8 → brightness range: 0.2 to 1.8 (dramatic)

Timing Functions

Common timing functions you can use:

  • 'ease' - Default smooth transition
  • 'linear' - Constant speed
  • 'ease-in' - Slow start, fast end
  • 'ease-out' - Fast start, slow end
  • 'ease-in-out' - Smooth acceleration and deceleration
  • 'cubic-bezier(0.68, -0.55, 0.265, 1.55)' - Custom bounce effect

Performance Considerations

  • Uses hardware-accelerated CSS animations
  • will-change: filter optimizes rendering
  • Minimal JavaScript - only for controls
  • No impact on image loading or layout

Demo Component

A comprehensive demo is available at:

src/components/new_ui/CyclingImageDemo.tsx

To view the demo, import it in your router or main component:

import CyclingImageDemo from './components/new_ui/CyclingImageDemo'

// In your router or component
<CyclingImageDemo />

Browser Compatibility

Works in all modern browsers that support:

  • CSS animations
  • CSS filters
  • CSS keyframes

Troubleshooting

Animation not visible:

  • Check that autoStart is true (default)
  • Verify intensity is not 0
  • Ensure image is loaded and visible

Controls not showing:

  • Set showControls={true}
  • Check that there's enough space for the control panel

Responsive sizing issues:

  • Use Chakra UI responsive objects for all positioning props
  • Test on different viewport sizes

License

Part of the Healthy Oil project.

Author

Created with Chakra UI and React.