Added wiggle animation to images + badges

This commit is contained in:
2023-11-19 22:41:00 -06:00
parent ec45811387
commit f75e178ffc
7 changed files with 45 additions and 102 deletions

View File

@@ -52,15 +52,11 @@ export default function Filters({ originalPosts, posts, setPosts }: Props) {
),
);
console.log("CLICK", filterResults);
console.log("CLICK-Original", originalPosts);
setPosts(filterResults.length > 0 ? filterResults : originalPosts);
};
const handleReset = () => {
handleResetFilters();
console.log("RESET", originalPosts);
setPosts(originalPosts);
};

View File

@@ -1,3 +1,4 @@
import { WiggleWrapper } from "~/app/components/wiggle-wrapper";
import { Badge } from "~/app/components/ui/badge";
const BadgeList: React.FC<{ badges: string[] }> = ({ badges }) => {
@@ -5,7 +6,9 @@ const BadgeList: React.FC<{ badges: string[] }> = ({ badges }) => {
<ul className="not-prose flex flex-row flex-wrap gap-x-2 gap-y-1">
{badges.map((badge) => (
<li key={badge} className="inline">
<Badge>{badge}</Badge>
<WiggleWrapper>
<Badge>{badge}</Badge>
</WiggleWrapper>
</li>
))}
</ul>

View File

@@ -1,5 +1,6 @@
import Image from "next/image";
import { Card } from "~/app/components/card";
import { WiggleWrapper } from "~/app/components/wiggle-wrapper";
import { cn } from "~/app/utils/styles";
const BannerImage: React.FC<{
@@ -8,15 +9,17 @@ const BannerImage: React.FC<{
className?: string;
}> = ({ src, alt = "", className }) => {
return (
<Card
className={cn(
"not-prose relative aspect-video h-auto max-w-full",
className,
)}
overlayShadow
>
<Image src={src} alt={alt} className="object-cover" fill />
</Card>
<WiggleWrapper>
<Card
className={cn(
"not-prose relative aspect-video h-auto max-w-full",
className,
)}
overlayShadow
>
<Image src={src} alt={alt} className="object-cover" fill />
</Card>
</WiggleWrapper>
);
};

View File

@@ -1,87 +0,0 @@
"use client";
import React from "react";
import { clamp01 } from "~/app/utils/math";
import { random, randomInt0 } from "~/app/utils/random";
const RingBackground = () => {
const numRings = 10; // Adjust the number of rings as needed
const getRandomPosition = () => {
const randomValueX = randomInt0(100);
const randomWeightY = random();
// Choose a random percentage for the second value with a bias towards 100%
// 80% of the time, generate a number close to 100%
// 20% of the time, generate a completely random number
const randomValueY =
randomWeightY < 0.5 ? 50 + randomInt0(50) : randomInt0(100);
return { x: randomValueX, y: randomValueY };
};
function getColorByDepth(percentage: number) {
const color1 = "#92beb8";
const color2 = "#272828";
// Ensure the percentage is within the range [0, 1]
percentage = clamp01(percentage);
// Parse the input colors as hex values
const hexColor1 = parseInt(color1.slice(1), 16);
const hexColor2 = parseInt(color2.slice(1), 16);
// Interpolate between the two colors
const r1 = (hexColor1 >> 16) & 255;
const g1 = (hexColor1 >> 8) & 255;
const b1 = hexColor1 & 255;
const r2 = (hexColor2 >> 16) & 255;
const g2 = (hexColor2 >> 8) & 255;
const b2 = hexColor2 & 255;
const r = Math.round(r1 + (r2 - r1) * percentage);
const g = Math.round(g1 + (g2 - g1) * percentage);
const b = Math.round(b1 + (b2 - b1) * percentage);
// Convert the interpolated RGB values back to a hex color
const interpolatedColor = `#${((1 << 24) | (r << 16) | (g << 8) | b)
.toString(16)
.slice(1)}`;
return interpolatedColor;
}
const renderRings = () => {
const rings = [];
for (let i = 0; i < numRings; i++) {
const position = getRandomPosition();
const color = getColorByDepth((randomInt0(50) + position.y) / 100);
rings.push(
<circle
key={i}
cx={position.x + "%"}
cy={Math.max(5, position.y) + "%"}
r={24}
stroke={color}
strokeWidth={16}
fillOpacity={0}
/>,
);
}
return rings;
};
return (
<div className="absolute inset-0 top-[100vh] -z-40">
<svg className="h-full w-full" xmlns="http://www.w3.org/2000/svg">
{renderRings()}
</svg>
</div>
);
};
export { RingBackground };

View File

@@ -0,0 +1,28 @@
"use client";
import { motion } from "framer-motion";
import { type PropsWithChildren } from "react";
const height = -5;
const WiggleWrapper = ({ children }: PropsWithChildren) => {
return (
<motion.div
initial={{ y: 0, rotate: 0 }}
whileHover={{
y: [0, height, height, height, height, height, height],
rotate: [0, 0, -3, 2, -2, 1, 0],
transition: {
delay: 0.025,
duration: 0.75,
times: [0, 0.2, 0.475, 0.625, 0.775, 0.925, 1],
},
}}
style={{ originX: "50%", originY: "80%" }}
>
{children}
</motion.div>
);
};
export { WiggleWrapper };

View File

@@ -6,7 +6,7 @@ import { TRPCReactProvider } from "~/trpc/react";
import { ThemeProvider } from "~/app/components/theme/theme-provider";
import { Navigation } from "~/app/components/navigation/navigation";
import { type PropsWithChildren } from "react";
import { Footer } from "~/app/components/footer";
import { Footer } from "~/app/components/navigation/footer";
import { Toaster } from "~/app/components/ui/toaster";
const inter = Inter({