Skip to content

Commit 4bc257a

Browse files
committed
feat: tweet creator bg option
1 parent b7377a4 commit 4bc257a

File tree

1 file changed

+118
-36
lines changed

1 file changed

+118
-36
lines changed

src/pages/apps/TweetCreatorPage.jsx

Lines changed: 118 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
HeartIcon,
99
GlobeIcon,
1010
TrashIcon,
11+
PaintBrushIcon,
1112
} from '@phosphor-icons/react';
1213
import useSeo from '../../hooks/useSeo';
1314
import { useToast } from '../../hooks/useToast';
@@ -34,67 +35,126 @@ const TweetCreatorPage = () => {
3435
const [likeCount, setLikeCount] = useState('1,337');
3536
const [commentCount, setCommentCount] = useState('42');
3637
const [dateText, setDateText] = useState('10:24 PM · Dec 25, 2025');
37-
const [locationText, setLocationText] = useState('Transmission_HQ');
38-
const [postLink, setPostLink] = useState('fezcode.com/nodes/049');
38+
const [locationText, setLocationText] = useState('Transmission_HQ');
39+
const [postLink, setPostLink] = useState('fezcode.com/nodes/049');
40+
const [showCardBg, setShowCardBg] = useState(true);
3941

40-
const drawTweet = useCallback((ctx, width, height) => {
41-
const scale = width / 800;
42+
const drawTweet = useCallback((ctx, width, height) => {
43+
const scale = width / 800;
4244

43-
// 1. Transparent/Clean Background
45+
// 1. Transparent/Clean Background
4446

45-
ctx.clearRect(0, 0, width, height);
47+
ctx.clearRect(0, 0, width, height);
4648

47-
// 2. Card Dimensions (Fill the canvas)
49+
// 2. Card Dimensions
4850

49-
const cardW = width;
51+
const cardW = width;
5052

51-
const cardH = height;
53+
const cardH = height;
5254

53-
const cardX = 0;
55+
const cardX = 0;
5456

55-
const cardY = 0;
57+
const cardY = 0;
5658

57-
const radius = 40 * scale;
59+
const radius = 40 * scale;
5860

59-
ctx.save();
61+
// Define Card Path for clipping and filling
6062

61-
// Glass Fill (Slightly more opaque since it's now the only layer)
63+
const defineCardPath = (c) => {
64+
c.beginPath();
6265

63-
ctx.beginPath();
66+
c.moveTo(cardX + radius, cardY);
6467

65-
ctx.moveTo(cardX + radius, cardY);
68+
c.lineTo(cardX + cardW - radius, cardY);
6669

67-
ctx.lineTo(cardX + cardW - radius, cardY);
70+
c.quadraticCurveTo(cardX + cardW, cardY, cardX + cardW, cardY + radius);
6871

69-
ctx.quadraticCurveTo(cardX + cardW, cardY, cardX + cardW, cardY + radius);
72+
c.lineTo(cardX + cardW, cardY + cardH - radius);
7073

71-
ctx.lineTo(cardX + cardW, cardY + cardH - radius);
74+
c.quadraticCurveTo(cardX + cardW, cardY + cardH, cardX + cardW - radius, cardY + cardH);
7275

73-
ctx.quadraticCurveTo(cardX + cardW, cardY + cardH, cardX + cardW - radius, cardY + cardH);
76+
c.lineTo(cardX + radius, cardY + cardH);
7477

75-
ctx.lineTo(cardX + radius, cardY + cardH);
78+
c.quadraticCurveTo(cardX, cardY + cardH, cardX, cardY + cardH - radius);
7679

77-
ctx.quadraticCurveTo(cardX, cardY + cardH, cardX, cardY + cardH - radius);
80+
c.lineTo(cardX, cardY + radius);
7881

79-
ctx.lineTo(cardX, cardY + radius);
82+
c.quadraticCurveTo(cardX, cardY, cardX + radius, cardY);
8083

81-
ctx.quadraticCurveTo(cardX, cardY, cardX + radius, cardY);
84+
c.closePath();
85+
};
8286

83-
ctx.closePath();
87+
ctx.save();
8488

85-
ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';
89+
// Draw Background if enabled
8690

87-
ctx.fill();
91+
if (showCardBg) {
92+
ctx.save();
8893

89-
// Glass Border
94+
defineCardPath(ctx);
9095

91-
ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
96+
ctx.clip();
9297

93-
ctx.lineWidth = 2 * scale;
98+
// Background Gradient (Echo Chamber Style)
9499

95-
ctx.stroke();
100+
const bgGradient = ctx.createLinearGradient(0, 0, width, height);
101+
102+
bgGradient.addColorStop(0, '#6366f1'); // indigo-500
103+
104+
bgGradient.addColorStop(0.5, '#a855f7'); // purple-500
105+
106+
bgGradient.addColorStop(1, '#ec4899'); // pink-500
107+
108+
ctx.fillStyle = bgGradient;
109+
110+
ctx.fillRect(0, 0, width, height);
111+
112+
// Blobs
113+
114+
const drawBlob = (x, y, r, color) => {
115+
ctx.save();
116+
117+
ctx.beginPath();
118+
119+
ctx.arc(x, y, r, 0, Math.PI * 2);
120+
121+
ctx.fillStyle = color;
122+
123+
ctx.filter = 'blur(80px)';
124+
125+
ctx.globalAlpha = 0.4;
126+
127+
ctx.fill();
128+
129+
ctx.restore();
130+
};
131+
132+
drawBlob(width * 0.2, height * 0.2, 300 * scale, '#c084fc');
133+
134+
drawBlob(width * 0.8, height * 0.1, 250 * scale, '#facc15');
135+
136+
drawBlob(width * 0.5, height * 0.9, 350 * scale, '#f472b6');
96137

97-
ctx.restore();
138+
ctx.restore();
139+
}
140+
141+
// Glass Fill
142+
143+
defineCardPath(ctx);
144+
145+
ctx.fillStyle = showCardBg ? 'rgba(255, 255, 255, 0.12)' : 'rgba(255, 255, 255, 0.05)';
146+
147+
ctx.fill();
148+
149+
// Glass Border
150+
151+
ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
152+
153+
ctx.lineWidth = 2 * scale;
154+
155+
ctx.stroke();
156+
157+
ctx.restore();
98158

99159
// 3. Content Rendering
100160

@@ -244,12 +304,12 @@ const TweetCreatorPage = () => {
244304

245305
ctx.textAlign = 'center';
246306

247-
ctx.font = `${12 * scale}px "JetBrains Mono"`;
307+
ctx.font = `${12 * scale}px "JetBrains Mono"`;
248308

249-
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
309+
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
250310

251-
ctx.fillText(postLink.toUpperCase(), cardX + cardW/2, cardY + cardH - 20 * scale);
252-
}, [userName, userHandle, tweetText, likeCount, commentCount, dateText, locationText, postLink]);
311+
ctx.fillText(postLink.toUpperCase(), cardX + cardW/2, cardY + cardH - 20 * scale);
312+
}, [userName, userHandle, tweetText, likeCount, commentCount, dateText, locationText, postLink, showCardBg]);
253313

254314
useEffect(() => {
255315
const canvas = canvasRef.current;
@@ -355,6 +415,28 @@ const TweetCreatorPage = () => {
355415
<input type="text" value={locationText} onChange={(e) => setLocationText(e.target.value)} className={glassInputClass} placeholder="Location Tag" />
356416
</div>
357417
</div>
418+
419+
<div className={`${glassCardClass} p-8 space-y-6`}>
420+
<h3 className="font-mono text-[10px] font-bold text-pink-200 uppercase tracking-widest flex items-center gap-2">
421+
<PaintBrushIcon weight="fill" />
422+
Visual_Aesthetics
423+
</h3>
424+
<div className="space-y-4">
425+
<button
426+
onClick={() => setShowCardBg(!showCardBg)}
427+
className={`w-full py-3 px-4 rounded-xl border transition-all font-mono text-[10px] uppercase tracking-widest flex items-center justify-between ${
428+
showCardBg
429+
? 'bg-pink-500/20 border-pink-500/50 text-pink-200'
430+
: 'bg-white/5 border-white/10 text-white/40'
431+
}`}
432+
>
433+
<span>Card Background</span>
434+
<span className={showCardBg ? 'text-pink-400' : ''}>
435+
{showCardBg ? '[ ENABLED ]' : '[ DISABLED ]'}
436+
</span>
437+
</button>
438+
</div>
439+
</div>
358440
</div>
359441

360442
{/* Preview Area */}

0 commit comments

Comments
 (0)