) || innerContainer.current,
})
const scrollVelocity = useVelocity(scrollY)
const smoothVelocity = useSpring(scrollVelocity, scrollSpringConfig)
// Transform scroll velocity into a factor for marquee speed
const velocityFactor = useTransform(
useScrollVelocity ? smoothVelocity : defaultVelocity,
[0, 1000],
[0, 5],
{ clamp: false }
)
// In animation frame
// Adjust movement based on scroll velocity
moveBy += directionFactor.current * moveBy * velocityFactor.get()
// Change direction based on scroll if enabled
if (scrollAwareDirection && !isDragging.current) {
if (velocityFactor.get() < 0) {
directionFactor.current = -1
} else if (velocityFactor.get() > 0) {
directionFactor.current = 1
}
}
```
--------------------------------
### Cloning Fancy Components Git Repository (Bash)
Source: https://github.com/danielpetho/fancy/blob/main/CONTRIBUTING.md
This command clones the 'fancy' Git repository from GitHub to the user's local machine. It is the second step in setting up the development environment after forking the repository. The user should replace 'your-username' with their actual GitHub username.
```bash
git clone https://github.com/your-username/fancy.git
```
--------------------------------
### Creating and Switching to New Git Branch (Bash)
Source: https://github.com/danielpetho/fancy/blob/main/CONTRIBUTING.md
This command creates a new Git branch named 'my-new-branch' and immediately switches the user's working directory to this new branch. This is a standard practice for feature development or bug fixes to isolate changes from the main branch. The user should replace 'my-new-branch' with a descriptive name for their contribution.
```bash
git checkout -b my-new-branch
```
--------------------------------
### Basic Usage - Gravity & MatterBody - Typescript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/physics/cursor-attractor-and-gravity.mdx
Demonstrates how to wrap content with the `Gravity` component to enable physics and how to make individual HTML elements interactive physics bodies using `MatterBody`. It shows configuring attractor points and cursor forces, and setting initial positions for bodies using percentage values.
```typescript
Hello world!
fancy!
```
--------------------------------
### Basic Usage of Stacking Cards Component (TSX)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/stacking-cards.mdx
Wrap your content within the StackingCards component and individual card elements within StackingCardItem components to enable the stacking and scroll animation effect. Replace the comment with your actual card content.
```tsx
{/* Your card go here */}
```
--------------------------------
### Initializing Motion Values for Position JavaScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
Initializes `baseX` and `baseY` using Framer Motion's `useMotionValue` hook. These values are the core drivers of the animation, tracking the fundamental horizontal and vertical position that will be transformed to create the continuous scrolling effect.
```jsx
const baseX = useMotionValue(0)
const baseY = useMotionValue(0)
```
--------------------------------
### Positioning MatterBody component (TypeScript)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/physics/gravity.mdx
This snippet illustrates how to set the initial position of a MatterBody component using the `x` and `y` props. Positions can be specified using percentage values relative to the container or as absolute pixel values.
```typescript
I'm physics-enabled!
```
--------------------------------
### Transforming Marquee Position with Wrapping and Easing JavaScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
Uses Framer Motion's `useTransform` to map the continuously changing `baseX` value. It applies a `wrap` function to keep the value within a specific range (e.g., 0 to -100) and then optionally applies a custom `easing` function before converting it to a percentage string for CSS positioning.
```jsx
const x = useTransform(baseX, (v) => {
// wrap it between 0 and -100
const wrappedValue = wrap(0, -100, v)
// Apply easing if provided, otherwise use linear
return `${easing ? easing(wrappedValue / -100) * -100 : wrappedValue}%`
})
```
--------------------------------
### Applying Custom Easing to Marquee Position Transformation JavaScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
Demonstrates applying a custom easing function to the marquee's position transformation using Framer Motion's `useTransform`. After the `baseX` value is wrapped within the animation range, the provided `easing` function is applied to the normalized value before converting it back to a percentage string for CSS.
```jsx
const x = useTransform(baseX, (v) => {
// Apply easing if provided, otherwise use linear
const wrappedValue = wrap(0, -100, v)
return `${easing ? easing(wrappedValue / -100) * -100 : wrappedValue}%`
})
```
--------------------------------
### Rendering Repeated Marquee Content with Motion JSX
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
This JSX snippet maps over a range determined by the `repeat` prop to render the component's `children` multiple times. Each child set is wrapped in a `motion.div` which applies styles (like position via `x` or `y`) and dynamic class names based on orientation and drag state, enabling continuous scrolling.
```jsx
{
Array.from({ length: repeat }, (_, i) => i).map((i) => (
0}
>
{children}
))
}
```
--------------------------------
### Updating 3D Box Rotation from Drag Input (TypeScript)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/css-box.mdx
This TypeScript snippet illustrates how pointer movement deltas (`deltaX`, `deltaY`) are used to update the target rotation values (`baseRotateX`, `baseRotateY`) during a drag interaction. The deltas are scaled to control drag sensitivity.
```ts
baseRotateX.set(startRotation.current.x - deltaY / 2)
baseRotateY.set(startRotation.current.y + deltaX / 2)
```
--------------------------------
### Combining Motion Values into CSS Transform (TypeScript)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/css-box.mdx
This snippet shows how `useTransform` from framer-motion combines two spring-driven motion values (`springX`, `springY`) into a single CSS `transform` string. This transform is applied to the box element, handling rotation and positioning based on the animated values.
```ts
const transform = useTransform([springX, springY], ([x, y]) =>
`translateZ(-${depth / 2}px) rotateX(${x}deg) rotateY(${y}deg)`
)
```
--------------------------------
### Implementing Marquee Slowdown on Hover JavaScript/JSX
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
This code block demonstrates implementing a slowdown effect when the mouse hovers over the marquee. It uses `useRef` to track hover state, `useMotionValue` for the target speed factor, and `useSpring` for a smooth transition between speeds. The resulting `smoothHoverFactor` modifies the movement calculation in the animation loop.
```jsx
// Track hover state
const isHovered = useRef(false)
const hoverFactorValue = useMotionValue(1)
const smoothHoverFactor = useSpring(hoverFactorValue, slowDownSpringConfig)
// In component JSX
(isHovered.current = true)}
onHoverEnd={() => (isHovered.current = false)}
// ...other props
>
{/* ... */}
// In animation frame
if (isHovered.current) {
hoverFactorValue.set(slowdownOnHover ? slowDownFactor : 1)
} else {
hoverFactorValue.set(1)
}
// Apply the hover factor to movement calculation
let moveBy = directionFactor.current *
actualBaseVelocity *
(delta / 1000) *
smoothHoverFactor.get()
```
--------------------------------
### Calculating Angled Drag Projection (JSX)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
This snippet demonstrates the mathematical calculation used to project the raw horizontal (`deltaX`) and vertical (`deltaY`) pointer movement onto a specific `dragAngle`. It converts the `dragAngle` from degrees to radians and uses cosine and sine to find the components of the angle's direction, then projects the delta onto that direction.
```jsx
// Convert dragAngle from degrees to radians
const angleInRadians = (dragAngle * Math.PI) / 180
// Calculate the projection of the movement along the angle direction
const directionX = Math.cos(angleInRadians)
const directionY = Math.sin(angleInRadians)
// Project the movement onto the angle direction
const projectedDelta = deltaX * directionX + deltaY * directionY
```
--------------------------------
### Defining FontVariationMapping Interface (TypeScript)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/text/variable-font-and-cursor.mdx
This TypeScript interface defines the structure required for the `fontVariationMapping` prop. It specifies how the horizontal (`x`) and vertical (`y`) cursor positions are mapped to specific font variation axes, including their names and corresponding minimum and maximum values.
```typescript
interface FontVariationMapping {
x: { name: string; min: number; max: number };
y: { name: string; min: number; max: number };
}
```
--------------------------------
### Apply Pixelate SVG Filter to Element - React/TypeScript & CSS
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/filter/pixelate-svg-filter.mdx
Demonstrates how to include the `PixelateSvgFilter` component in a React application and apply the visual effect to an HTML element by referencing the filter's ID in the element's CSS `filter` property using the `url(#id)` syntax. Requires the component to be imported and rendered.
```typescript
filter will be applied here
```
--------------------------------
### Helper Function for Wrapping Value within Range TypeScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
A utility function written in TypeScript that takes a numerical `value` and constraints (`min`, `max`). It calculates the range and uses the modulo operator to cycle the value, ensuring it always falls within the inclusive `min` and exclusive `max` bounds.
```typescript
const wrap = (min: number, max: number, value: number): number => {
const range = max - min
return ((((value - min) % range) + range) % range) + min
}
```
--------------------------------
### Defining Background Gradient Animation Keyframes (CSS)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/background/animated-gradient-with-svg.mdx
Defines the `@keyframes` rule for the `background-gradient` animation within a theme object structure. It specifies the movement path of elements (SVG circles) using `transform: translate` based on custom CSS variables (`--tx`, `--ty`) at different percentages of the animation duration.
```css
@theme: {
--animate-background-gradient: background-gradient;
@keyframes: background-gradient {
0%, 100% {
transform: translate(0, 0);
animationDelay: var(--background-gradient-delay, 0s);
}
20% {
transform: translate(calc(100% * var(--tx-1, 1)), calc(100% * var(--ty-1, 1)));
}
40% {
transform: translate(calc(100% * var(--tx-2, -1)), calc(100% * var(--ty-2, 1)));
}
60% {
transform: translate(calc(100% * var(--tx-3, 1)), calc(100% * var(--ty-3, -1)));
}
80% {
transform: translate(calc(100% * var(--tx-4, -1)), calc(100% * var(--ty-4, -1)));
}
}
},
```
--------------------------------
### Apply Gooey SVG Filter - React/TypeScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/filter/gooey-svg-filter.mdx
Demonstrates how to use the `GooeySvgFilter` component in a React application. It shows adding the filter component with an optional ID and then applying it to a HTML element using the CSS `filter` property with `url(#filter-id)`.
```typescript
filter will be applied here
```
--------------------------------
### Applying CSS Offset Properties - JSX
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/marquee-along-svg-path.mdx
This JSX snippet shows how the core CSS properties `offsetPath` and `offsetDistance` are applied to an element's style within the component. `offsetPath` defines the SVG path to follow, while `offsetDistance` controls the element's position along that path.
```JSX
style={{
...
offsetPath: `path('${path}')`,
offsetDistance: itemOffset,
}}
```
--------------------------------
### Calculate Item Offset with useTransform - React/Framer Motion
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/marquee-along-svg-path.mdx
Uses Framer Motion's `useTransform` hook to calculate each item's `offsetDistance`. It distributes items evenly along the path (0-100%) by combining a base offset with the item's index, wrapping the value as needed and optionally applying an easing function.
```JSX
const itemOffset = useTransform(baseOffset, (v) => {
// evenly distribute items along the path (0-100%)
const position = (itemIndex * 100) / items.length
const wrappedValue = wrap(0, 100, v + position)
return `${easing ? easing(wrappedValue / 100) * 100 : wrappedValue}%`
})
```
--------------------------------
### Adjusting Marquee Velocity based on Direction JavaScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
Calculates the effective base velocity for the marquee animation based on the desired direction. It negates the provided `baseVelocity` if the `direction` prop specifies movement to the "left" or "up", ensuring the animation proceeds correctly.
```jsx
// Convert baseVelocity to the correct direction
const actualBaseVelocity =
direction === "left" || direction === "up" ? -baseVelocity : baseVelocity
```
--------------------------------
### Updating Marquee Position on Animation Frame JavaScript
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
This code snippet, typically executed within Framer Motion's `useAnimationFrame` hook, calculates the displacement (`moveBy`) for the current frame. It updates either the `baseX` (horizontal) or `baseY` (vertical) motion value by adding this displacement, driving the animation forward.
```jsx
// Inside useAnimationFrame
let moveBy = directionFactor.current * baseVelocity * (delta / 1000)
if (isHorizontal) {
baseX.set(baseX.get() + moveBy)
} else {
baseY.set(baseY.get() + moveBy)
}
```
--------------------------------
### Assigning Random CSS Variable Values (TypeScript/React)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/background/animated-gradient-with-svg.mdx
Demonstrates how to dynamically assign random values between -0.5 and 0.5 to CSS variables (`--tx-1` through `--ty-4`) within a React `style` object. These variables are used by the `background-gradient` keyframes to define the target positions for the animated SVG circles, contributing to the random movement effect.
```typescript
...\nstyle={
{
...
"--tx-1": (Math.random() - 0.5),
"--ty-1": (Math.random() - 0.5),
"--tx-2": (Math.random() - 0.5),
"--ty-2": (Math.random() - 0.5),
"--tx-3": (Math.random() - 0.5),
"--ty-3": (Math.random() - 0.5),
"--tx-4": (Math.random() - 0.5),
"--ty-4": (Math.random() - 0.5),
} as React.CSSProperties
}
...
```
--------------------------------
### Calculate Rolling Z-Index - React/Framer Motion
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/marquee-along-svg-path.mdx
Implements a function to calculate an element's z-index based on its position (offset distance) along the path, useful for self-crossing paths. The z-index is interpolated between `zIndexBase` and `zIndexRange` based on the normalized distance (0-1). The `useTransform` hook applies this calculation dynamically.
```JSX
// Function to calculate z-index based on offset distance
const calculateZIndex = useCallback(
(offsetDistance: number) => {
if (!enableRollingZIndex) {
return undefined;
}
// Simple progress-based z-index
const normalizedDistance = offsetDistance / 100;
return Math.floor(zIndexBase + normalizedDistance * zIndexRange);
},
[enableRollingZIndex, zIndexBase, zIndexRange]
);
// ...
// Inside an element:
const zIndex = useTransform(
currentOffsetDistance,
(value) => calculateZIndex(value)
);
```
--------------------------------
### Applying Drag Velocity in Animation Loop (JSX)
Source: https://github.com/danielpetho/fancy/blob/main/src/content/docs/components/blocks/simple-marquee.mdx
This code snippet is typically placed within an animation frame loop (like `useAnimationFrame`). When the marquee is being dragged (`isDragging.current` is true), it applies the current `dragVelocity` to update the horizontal (`baseX`) or vertical (`baseY`) position. It also includes logic to apply decay to the drag velocity while dragging and stop it if it becomes negligible, ensuring dragging movement takes precedence.
```jsx
// Inside useAnimationFrame
if (isDragging.current && draggable) {
if (isHorizontal) {
baseX.set(baseX.get() + dragVelocity.current)
} else {
baseY.set(baseY.get() + dragVelocity.current)
}
// Add decay to dragVelocity when not moving
dragVelocity.current *= 0.9
// Stop completely if velocity is very small
if (Math.abs(dragVelocity.current) < 0.01) {
dragVelocity.current = 0
}
return
}
```