-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 🎨 style: 背景グラデーションの実装 #185 * 🎨 style: 絵文字アニメーションの実装 * 🎨 style: ヘッダーの重ね合わせを修正 * 🎨 style: 絵文字の色を半透明に変更 * ♻️ refactor: 細かい表記の修正
- Loading branch information
Showing
9 changed files
with
341 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { | ||
emojiToUnicodeHex, | ||
getAnimationStyles, | ||
getEmojiSize, | ||
} from "@/utils/animated-emoji"; | ||
import contributors from "../../Contributors.json"; | ||
import { latestContributorsColor } from "@/utils/contributors-grouping"; | ||
import { hexToRgb } from "@/utils/background-color"; | ||
|
||
type AnimatedEmojiProps = { | ||
index: number; | ||
contributor: (typeof contributors)[number]; | ||
size?: "small" | "medium" | "large"; | ||
isTopSection?: boolean; | ||
}; | ||
|
||
const AnimatedEmoji: React.FC<AnimatedEmojiProps> = ({ | ||
index, | ||
contributor, | ||
isTopSection = false, | ||
}) => { | ||
const emojiSize = getEmojiSize( | ||
isTopSection && index === 0 ? "large" : "medium", | ||
); | ||
const speed = Math.floor(Math.random() * 65 + 35) / 10; | ||
const styles = getAnimationStyles(index, speed); | ||
const notoEmoji = emojiToUnicodeHex(contributor.favoriteEmoji); | ||
const emojiColor = hexToRgb(latestContributorsColor, 0.5); | ||
|
||
return ( | ||
<> | ||
<div | ||
className="group absolute flex h-20 w-20 cursor-pointer items-center justify-center rounded-full bg-transparent [perspective:1000px]" | ||
style={styles as React.CSSProperties} | ||
> | ||
<div className="relative h-full w-full rounded-full duration-1000 [transform-style:preserve-3d] group-hover:[transform:rotateY(180deg)]"> | ||
<div className="absolute h-full w-full rounded-full [backface-visibility:hidden]"> | ||
<div | ||
className={`flex h-full w-full flex-col items-center justify-center gap-0.5 ${emojiSize}`} | ||
style={{ color: emojiColor }} | ||
dangerouslySetInnerHTML={{ __html: notoEmoji }} | ||
></div> | ||
</div> | ||
<div | ||
style={{ borderColor: contributor.favoriteColor }} | ||
className="absolute h-full w-full rounded-full border-4 shadow-xl [backface-visibility:hidden] [transform:rotateY(180deg)]" | ||
> | ||
<img | ||
src={`${contributor.github}.png`} | ||
loading="lazy" | ||
alt="contributor's icon" | ||
className="h-full w-full rounded-full object-cover object-top" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default AnimatedEmoji; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { getGradientStyles } from "@/utils/background-color"; | ||
import { ReactNode } from "react"; | ||
|
||
type GradientBackgroundProps = { | ||
mainColor: string; | ||
children: ReactNode; | ||
}; | ||
|
||
const GradientBackground: React.FC<GradientBackgroundProps> = ({ | ||
mainColor, | ||
children, | ||
}) => { | ||
const gradientStyles = getGradientStyles(mainColor); | ||
|
||
return ( | ||
<main | ||
className="bg-gradient-to-b from-[var(--background-start-rgb)] via-[var(--background-middle-rgb)] to-[var(--background-end-rgb)]" | ||
style={gradientStyles as React.CSSProperties} | ||
> | ||
<div className=" inset-0 top-0"> | ||
<svg | ||
preserveAspectRatio="none" | ||
viewBox="0 0 1200 120" | ||
xmlns="http://www.w3.org/2000/svg" | ||
style={{ | ||
fill: "#ffffff", | ||
width: "100%", | ||
height: 137, | ||
transform: "scaleX(-1)", | ||
}} | ||
> | ||
<path | ||
d="M0 0v46.29c47.79 22.2 103.59 32.17 158 28 70.36-5.37 136.33-33.31 206.8-37.5 73.84-4.36 147.54 16.88 218.2 35.26 69.27 18 138.3 24.88 209.4 13.08 36.15-6 69.85-17.84 104.45-29.34C989.49 25 1113-14.29 1200 52.47V0z" | ||
opacity=".25" | ||
/> | ||
<path | ||
d="M0 0v15.81c13 21.11 27.64 41.05 47.69 56.24C99.41 111.27 165 111 224.58 91.58c31.15-10.15 60.09-26.07 89.67-39.8 40.92-19 84.73-46 130.83-49.67 36.26-2.85 70.9 9.42 98.6 31.56 31.77 25.39 62.32 62 103.63 73 40.44 10.79 81.35-6.69 119.13-24.28s75.16-39 116.92-43.05c59.73-5.85 113.28 22.88 168.9 38.84 30.2 8.66 59 6.17 87.09-7.5 22.43-10.89 48-26.93 60.65-49.24V0z" | ||
opacity=".5" | ||
/> | ||
<path d="M0 0v5.63C149.93 59 314.09 71.32 475.83 42.57c43-7.64 84.23-20.12 127.61-26.46 59-8.63 112.48 12.24 165.56 35.4C827.93 77.22 886 95.24 951.2 90c86.53-7 172.46-45.71 248.8-84.81V0z" /> | ||
</svg> | ||
</div> | ||
{children} | ||
</main> | ||
); | ||
}; | ||
|
||
export default GradientBackground; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import AnimatedEmoji from "./animated-emoji"; | ||
import contributors from "../../Contributors.json"; | ||
import { Noto_Emoji } from "next/font/google"; | ||
|
||
const emoji = Noto_Emoji({ | ||
subsets: ["emoji"], | ||
weight: "300", | ||
display: "swap", | ||
}); | ||
|
||
type ScreenEmojisProps = { | ||
contributors: typeof contributors; | ||
isTopSection?: boolean; | ||
}; | ||
|
||
const ScreenEmojis: React.FC<ScreenEmojisProps> = ({ | ||
contributors, | ||
isTopSection, | ||
}) => { | ||
return ( | ||
<> | ||
<div className={`${emoji.className} relative`}> | ||
{contributors.map((contributor, index) => ( | ||
<AnimatedEmoji | ||
key={index} | ||
index={index} | ||
contributor={contributor} | ||
isTopSection={isTopSection} | ||
/> | ||
))} | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default ScreenEmojis; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const getEmojiSize = (type: "small" | "medium" | "large") => { | ||
switch (type) { | ||
case "small": | ||
return "text-xl"; | ||
case "medium": | ||
return "text-7xl"; | ||
case "large": | ||
return "text-9xl"; | ||
} | ||
}; | ||
|
||
const getAnimationDirection = (index: number) => | ||
(index + 1) % 2 === 0 ? "vertical" : "horizontal"; | ||
const getAnimationAlternate = (index: number) => | ||
index < 5 ? "alternate-reverse" : "alternate"; | ||
|
||
const getAnimationStyles = (index: number, speed: number) => { | ||
const animationDirection = getAnimationDirection(index); | ||
const isHorizontal = animationDirection === "horizontal"; | ||
const alternate = getAnimationAlternate(index); | ||
const left = isHorizontal ? 0 : `calc(100vw / 10 * ${index})`; | ||
const top = isHorizontal ? `calc(80vh / 10 * ${index})` : 0; | ||
|
||
return { | ||
animation: `${animationDirection} ${speed}s ease-in-out infinite ${alternate} both`, | ||
left, | ||
top, | ||
}; | ||
}; | ||
|
||
const emojiToUnicodeHex = (emoji: string) => { | ||
const codePoint = emoji.codePointAt(0); | ||
if (codePoint === undefined) { | ||
throw new Error("Invalid emoji input"); | ||
} | ||
return `&#x${codePoint.toString(16).toUpperCase()};️`; | ||
}; | ||
|
||
export { getEmojiSize, getAnimationStyles, emojiToUnicodeHex }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export const hexToRgb = (color: string, transparency = 1) => { | ||
const rgbValues = Object.fromEntries( | ||
( | ||
(color.match(/^#?[0-9A-Fa-f]{3}([0-9A-Fa-f]{3})?$/) ? color : "000") | ||
.replace(/^#?(.*)$/, (_, hex) => | ||
hex.length == 3 ? hex.replace(/./g, "$&$&") : hex, | ||
) | ||
.match(/../g) ?? [] | ||
).map((c, i) => ["rgb".charAt(i), parseInt("0x" + c)]), | ||
); | ||
|
||
return `rgb(${rgbValues.r} ${rgbValues.g} ${rgbValues.b} / ${transparency})`; | ||
}; | ||
|
||
export const getGradientStyles = (color: string) => { | ||
return { | ||
"--background-start-rgb": hexToRgb(color, 0.05), | ||
"--background-middle-rgb": hexToRgb(color, 0.4), | ||
"--background-end-rgb": hexToRgb(color), | ||
}; | ||
}; |
Oops, something went wrong.