newOS for Developers
Back to Overview
useFlyawayAnimation
hook47 linesProvides a flyaway animation effect for votes/powerups, showing "+1 CWATT" floating upward with random angle on click.
Source Path
apps/web/hooks/useFlyawayAnimation.tsxPackage
@newos/web
Signature
useFlyawayAnimation(): {
containerRef: React.RefObject<any>; // Ref for positioning container
animatedFlyAway: { // Current animation state
id: number;
value: string | number | ReactNode;
x: number;
y: number;
angle: number;
} | undefined;
handleClick: (e: MouseEvent | TouchEvent) => void; // Trigger animation
setFlyAwayComponent: (component: ReactNode) => void; // Customize display
}Animation State Properties
| Property | Type | Description |
|---|---|---|
| id | number | Unique ID (Date.now()) for React key |
| value | ReactNode | Content to display (default: +1CWATT) |
| x | number | X position relative to container |
| y | number | Y position relative to container |
| angle | number | Random rotation (-45° to +45°) |
Key Features
Click Position Tracking
Animation starts at exact click/touch position within the container. Handles both touchend and click events.
Random Angle
Each animation gets a random angle between -45° and +45° for visual variety.
Auto-Cleanup
Animation state is automatically cleared via setTimeoutafter 2000ms.
Customizable Content
Use setFlyAwayComponent to change the displayed content. Default shows +1CWATT in #E3FF93 color.
Responsive Sizing
Default component uses fontSize: 24px on mobile,auto on wide screens.
Usage Example
import { useFlyawayAnimation } from "@/hooks/useFlyawayAnimation";
function VoteButton({ onVote }) {
const {
containerRef,
animatedFlyAway,
handleClick,
setFlyAwayComponent
} = useFlyawayAnimation();
// Optional: customize display
useEffect(() => {
setFlyAwayComponent(
<span style={{ color: "#E3FF93", fontSize: "48px" }}>+⚡</span>
);
}, []);
const onClick = (e) => {
handleClick(e); // Trigger animation
onVote(); // Perform vote action
};
return (
<div ref={containerRef} style={{ position: "relative" }}>
<button onClick={onClick}>Vote</button>
{animatedFlyAway && (
<div
key={animatedFlyAway.id}
className="flyaway-animation"
style={{
position: "absolute",
left: animatedFlyAway.x,
top: animatedFlyAway.y,
transform: `rotate(${animatedFlyAway.angle}deg)`,
}}
>
{animatedFlyAway.value}
</div>
)}
</div>
);
}Edge Cases & Gotchas
containerRef Required — Must attach
containerRef to a positioned parent element for correct positioning.Left-Click Only — Mouse events only trigger on
e.button === 0(left click). Right-clicks are ignored.Touch Event Coordinates — For touch events, uses
e.pageX/pageYinstead of e.clientX/clientY.CSS Animation — You must provide CSS for the actual flyaway animation (e.g., translateY, opacity fade). This hook only provides positioning.