Skip to content

Commit e4ade31

Browse files
committed
Add scalable styles, refine layout, and improve text rendering.
1 parent 7439d9d commit e4ade31

File tree

5 files changed

+108
-33
lines changed

5 files changed

+108
-33
lines changed

components/notification-generator/preview/MinecraftPreview.tsx

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client";
22

33
import { AnimatePresence } from "framer-motion";
4-
import React, { useMemo } from "react";
4+
import React, { useMemo, useRef, useLayoutEffect, useState } from "react";
55

66
import ActionBar from "@/components/notification-generator/tabs/actionbar/ActionBar";
77
import ChatMessage from "@/components/notification-generator/tabs/chat/ChatMessage";
@@ -17,10 +17,48 @@ export function MinecraftPreview({ notification }: MinecraftPreviewProps) {
1717
const { showTitle, titleOpacity } = useTitleAnimation(notification);
1818
const { playSound } = useSoundEffect(notification.sound);
1919

20+
const rootRef = useRef<HTMLDivElement | null>(null);
21+
const [scaleVars, setScaleVars] = useState<React.CSSProperties>({});
22+
23+
useLayoutEffect(() => {
24+
const el = rootRef.current;
25+
if (!el) return;
26+
27+
const rect = el.getBoundingClientRect();
28+
const baseHeight = 540;
29+
const scale = Math.max(0.5, rect.height / baseHeight);
30+
31+
const cssVars: React.CSSProperties = {
32+
["--mc-scale" as any]: scale.toString(),
33+
["--mc-font-size" as any]: `calc(8px * var(--mc-scale))`,
34+
["--mc-line-height" as any]: `calc(9px * var(--mc-scale))`,
35+
["--mc-shadow" as any]: `calc(1px * var(--mc-scale))`,
36+
37+
["--mc-chat-left" as any]: `calc(4px * var(--mc-scale))`,
38+
["--mc-chat-bottom" as any]: `calc(48px * var(--mc-scale))`,
39+
["--mc-chat-width" as any]: `calc(320px * var(--mc-scale))`,
40+
41+
["--mc-actionbar-bottom" as any]: `calc(67px * var(--mc-scale))`,
42+
43+
["--mc-title-font-size" as any]: `calc(32px * var(--mc-scale))`,
44+
["--mc-subtitle-font-size" as any]: `calc(16px * var(--mc-scale))`,
45+
};
46+
47+
setScaleVars(cssVars);
48+
}, []);
49+
2050
const chatComponent = useMemo(() => {
2151
if (!notification.chat) return null;
2252
return (
23-
<div className="absolute bottom-4 left-0">
53+
<div
54+
className="absolute"
55+
style={{
56+
left: "var(--mc-chat-left)",
57+
bottom: "var(--mc-chat-bottom)",
58+
width: "var(--mc-chat-width)",
59+
zIndex: 5,
60+
}}
61+
>
2462
<ChatMessage message={notification.chat} />
2563
</div>
2664
);
@@ -29,7 +67,16 @@ export function MinecraftPreview({ notification }: MinecraftPreviewProps) {
2967
const actionBarComponent = useMemo(() => {
3068
if (!notification.actionbar) return null;
3169
return (
32-
<div>
70+
<div
71+
className="absolute left-1/2"
72+
style={{
73+
bottom: "var(--mc-actionbar-bottom)",
74+
transform: "translateX(-50%)",
75+
width: "100%",
76+
maxWidth: "100%",
77+
zIndex: 10,
78+
}}
79+
>
3380
<ActionBar message={notification.actionbar} />
3481
</div>
3582
);
@@ -60,12 +107,14 @@ export function MinecraftPreview({ notification }: MinecraftPreviewProps) {
60107

61108
return (
62109
<div
110+
ref={rootRef}
63111
className="font-minecraft relative overflow-hidden rounded-lg bg-gray-900 shadow-lg"
64112
style={{
65113
width: "100%",
66114
aspectRatio: "16/9",
67115
maxWidth: "1280px",
68116
margin: "0 auto",
117+
...scaleVars,
69118
}}
70119
role="img"
71120
aria-label="Minecraft notification preview"

components/notification-generator/preview/minecraftTextParser.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,18 @@ export const MinecraftText: FC<MinecraftTextProps> = ({ text }) => {
2323
}
2424
}, [cleanedText]);
2525

26-
return <span className="font-minecraft" dangerouslySetInnerHTML={{ __html: htmlOutput }} />;
26+
return (
27+
<span
28+
className="font-minecraft"
29+
style={{
30+
imageRendering: "pixelated",
31+
textRendering: "optimizeSpeed",
32+
WebkitFontSmoothing: "none",
33+
MozOsxFontSmoothing: "grayscale",
34+
}}
35+
dangerouslySetInnerHTML={{ __html: htmlOutput }}
36+
/>
37+
);
2738
};
2839

2940
function sanitizeInput(input: string): string {
@@ -56,6 +67,7 @@ function convertLegacyToMini(text: string): string {
5667
k: "obfuscated",
5768
r: "reset",
5869
};
70+
5971
return text.replace(/[§&]([0-9A-FK-OR])/gi, (_, code) => {
6072
const key = code.toLowerCase();
6173
const tag = codeToTag[key];

components/notification-generator/tabs/actionbar/ActionBar.tsx

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,24 @@ const ActionBar = React.memo(({ message }: ActionBarProps) => {
1111

1212
return (
1313
<div
14-
className="absolute left-1/2"
1514
style={{
16-
bottom: "12%",
17-
transform: "translateX(-50%)",
18-
width: "100%",
19-
textAlign: "center",
2015
pointerEvents: "none",
2116
zIndex: 10,
22-
background: "none",
23-
border: "none",
24-
boxShadow: "none",
25-
padding: 0,
17+
width: "100%",
18+
textAlign: "center",
2619
}}
2720
>
2821
<span
2922
className="font-minecraft"
3023
style={{
31-
fontSize: "1.5rem",
32-
textShadow:
33-
"2px 0 0 #000, -2px 0 0 #000, 0 2px 0 #000, 0 -2px 0 #000, 1px 1px #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000",
24+
fontSize: "calc(14px * var(--mc-scale))",
25+
lineHeight: "calc(16px * var(--mc-scale))",
3426
fontWeight: "normal",
35-
lineHeight: 1.2,
36-
padding: 0,
37-
margin: 0,
3827
letterSpacing: 0,
3928
userSelect: "none",
40-
background: "none",
41-
border: "none",
42-
boxShadow: "none",
4329
whiteSpace: "pre-wrap !important",
30+
textShadow:
31+
"var(--mc-shadow) 0 0 #000, calc(-1 * var(--mc-shadow)) 0 0 #000, 0 var(--mc-shadow) 0 #000, 0 calc(-1 * var(--mc-shadow)) 0 #000",
4432
}}
4533
>
4634
<MinecraftText text={message} />

components/notification-generator/tabs/chat/ChatMessage.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ const ChatMessage = React.memo(({ message }: ChatMessageProps) => {
1616
className={`relative flex items-center ${styles.chatContainer}`}
1717
style={{
1818
width: "100%",
19-
maxWidth: "50vw",
20-
minWidth: 200,
21-
overflowX: "unset",
19+
maxWidth: "100%",
20+
overflowX: "hidden",
2221
overflowY: "auto",
2322
whiteSpace: "pre-line",
2423
height: "auto",
@@ -38,13 +37,18 @@ const ChatMessage = React.memo(({ message }: ChatMessageProps) => {
3837
{message.split("\n").map((line, index) => (
3938
<div
4039
key={`${line}-${index}`}
41-
className="font-minecraft px-4 drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]"
40+
className="font-minecraft"
4241
style={{
4342
display: "block",
44-
minHeight: 32,
45-
lineHeight: "32px",
43+
minHeight: "var(--mc-line-height)",
44+
lineHeight: "var(--mc-line-height)",
45+
fontSize: "var(--mc-font-size)",
4646
whiteSpace: "pre-wrap !important",
4747
wordBreak: "break-word",
48+
paddingLeft: "calc(4px * var(--mc-scale))",
49+
paddingRight: "calc(4px * var(--mc-scale))",
50+
textShadow:
51+
"var(--mc-shadow) 0 0 #000, calc(-1 * var(--mc-shadow)) 0 0 #000, 0 var(--mc-shadow) 0 #000, 0 calc(-1 * var(--mc-shadow)) 0 #000",
4852
}}
4953
>
5054
<MinecraftText text={line} />
@@ -53,14 +57,19 @@ const ChatMessage = React.memo(({ message }: ChatMessageProps) => {
5357
</div>
5458
) : (
5559
<div
56-
className="font-minecraft px-4 drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]"
60+
className="font-minecraft"
5761
style={{
5862
position: "relative",
5963
zIndex: 1,
60-
minHeight: 32,
61-
lineHeight: "32px",
64+
minHeight: "var(--mc-line-height)",
65+
lineHeight: "var(--mc-line-height)",
66+
fontSize: "var(--mc-font-size)",
6267
whiteSpace: "pre-wrap !important",
6368
wordBreak: "break-word",
69+
paddingLeft: "calc(4px * var(--mc-scale))",
70+
paddingRight: "calc(4px * var(--mc-scale))",
71+
textShadow:
72+
"var(--mc-shadow) 0 0 #000, calc(-1 * var(--mc-shadow)) 0 0 #000, 0 var(--mc-shadow) 0 #000, 0 calc(-1 * var(--mc-shadow)) 0 #000",
6473
}}
6574
>
6675
<MinecraftText text={message} />

components/notification-generator/tabs/title/Title.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,29 @@ const Title = React.memo(({ title, subtitle, showTitle, titleOpacity }: TitlePro
1818
style={{ opacity: titleOpacity }}
1919
>
2020
{title && (
21-
<div className="font-minecraft mb-2 text-3xl font-bold text-white drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]">
21+
<div
22+
className="font-minecraft mb-2 text-white"
23+
style={{
24+
fontSize: "var(--mc-title-font-size)",
25+
lineHeight: "calc(var(--mc-title-font-size) + var(--mc-shadow))",
26+
fontWeight: "bold",
27+
textShadow:
28+
"var(--mc-shadow) 0 0 #000, calc(-1 * var(--mc-shadow)) 0 0 #000, 0 var(--mc-shadow) 0 #000, 0 calc(-1 * var(--mc-shadow)) 0 #000",
29+
}}
30+
>
2231
<MinecraftText text={title} />
2332
</div>
2433
)}
2534
{subtitle && (
26-
<div className="font-minecraft text-xl text-gray-300 drop-shadow-[2px_2px_0px_rgba(0,0,0,0.5)]">
35+
<div
36+
className="font-minecraft text-gray-300"
37+
style={{
38+
fontSize: "var(--mc-subtitle-font-size)",
39+
lineHeight: "calc(var(--mc-subtitle-font-size) + var(--mc-shadow))",
40+
textShadow:
41+
"var(--mc-shadow) 0 0 #000, calc(-1 * var(--mc-shadow)) 0 0 #000, 0 var(--mc-shadow) 0 #000, 0 calc(-1 * var(--mc-shadow)) 0 #000",
42+
}}
43+
>
2744
<MinecraftText text={subtitle} />
2845
</div>
2946
)}

0 commit comments

Comments
 (0)