test_migratedmain.tsx1 match
97const svg = render(badge);
9899return new Response(svg, { headers: { "Content-Type": "image/svg+xml;charset=utf-8" } });
100}
memeGeneratormain.tsx27 matches
1/**
2* This meme creation tool app will allow users to create memes by selecting an image and adding top and bottom text.
3* We'll use HTML5 Canvas to render the meme directly in the browser, with custom positioning for different meme templates.
4*/
35}, []);
3637const getTextPositions = (imageWidth: number, imageHeight: number, templateId: string): [TextPosition, TextPosition] => {
38const defaultColor = "white";
39switch (templateId) {
40case "1": // Drake
41return [
42{ x: imageWidth * 0.7, y: imageHeight * 0.25, maxWidth: imageWidth * 0.5, color: "black" },
43{ x: imageWidth * 0.7, y: imageHeight * 0.75, maxWidth: imageWidth * 0.5, color: "black" }
44];
45case "2": // Distracted Boyfriend
46return [
47{ x: imageWidth * 0.6, y: imageHeight * 0.1, maxWidth: imageWidth * 0.3, color: defaultColor },
48{ x: imageWidth * 0.8, y: imageHeight * 0.1, maxWidth: imageWidth * 0.3, color: defaultColor }
49];
50case "3": // Two Buttons
51return [
52{ x: imageWidth * 0.5, y: imageHeight * 0.1, maxWidth: imageWidth * 0.8, color: defaultColor },
53{ x: imageWidth * 0.5, y: imageHeight * 0.9, maxWidth: imageWidth * 0.8, color: defaultColor }
54];
55case "4": // Expanding Brain
56return [
57{ x: imageWidth * 0.5, y: imageHeight * 0.15, maxWidth: imageWidth * 0.8, color: defaultColor },
58{ x: imageWidth * 0.5, y: imageHeight * 0.95, maxWidth: imageWidth * 0.8, color: defaultColor }
59];
60case "5": // Change My Mind
61return [
62{ x: imageWidth * 0.5, y: imageHeight * 0.7, maxWidth: imageWidth * 0.8, color: defaultColor },
63{ x: imageWidth * 0.5, y: imageHeight * 0.9, maxWidth: imageWidth * 0.8, color: defaultColor }
64];
65default:
66return [
67{ x: imageWidth * 0.5, y: imageHeight * 0.1, maxWidth: imageWidth * 0.9, color: defaultColor },
68{ x: imageWidth * 0.5, y: imageHeight * 0.9, maxWidth: imageWidth * 0.9, color: defaultColor }
69];
70}
78if (!ctx) return;
7980const selectedImage = templates.find(t => t.id === selectedTemplate);
81if (!selectedImage) return;
8283const image = new Image();
84image.crossOrigin = "anonymous";
85image.onload = () => {
86canvas.width = image.width;
87canvas.height = image.height;
88ctx.drawImage(image, 0, 0);
8990const fontSize = Math.floor(image.height / 15);
91ctx.font = `bold ${fontSize}px Impact, sans-serif`;
92ctx.textAlign = "center";
9394const [topPosition, bottomPosition] = getTextPositions(image.width, image.height, selectedTemplate);
9596// Function to draw text with word wrap
131setMemeUrl(canvas.toDataURL());
132};
133image.src = selectedImage.url;
134};
135164</form>
165<canvas ref={canvasRef} style={{ display: 'none' }}></canvas>
166{memeUrl && <img src={memeUrl} alt="Generated Meme" className="meme-image" />}
167<p>
168<a href={import.meta.url.replace("esm.town", "val.town")} target="_blank">View Source</a>
247background-color: #45a049;
248}
249.meme-image {
250max-width: 100%;
251display: block;
egoBoostermain.tsx15 matches
2* This ego booster app takes a selfie, sends it to GPT-4o-mini for analysis,
3* and streams funny, specific compliments about the user's appearance.
4* We use the WebRTC API for camera access, the OpenAI API for image analysis,
5* and server-sent events for real-time streaming of compliments.
6*/
73const context = canvasRef.current.getContext('2d');
74if (context) {
75context.drawImage(videoRef.current, 0, 0, canvasRef.current.width, canvasRef.current.height);
76console.log("Selfie captured on canvas");
77try {
78const blob = await new Promise<Blob | null>((resolve) => canvasRef.current!.toBlob(resolve, 'image/jpeg'));
79if (blob) {
80console.log("Blob created, size:", blob.size);
81const formData = new FormData();
82formData.append('image', blob, 'selfie.jpg');
83
84console.log("Sending request to /analyze");
112} else {
113console.log("Failed to create blob");
114throw new Error("Failed to create image blob");
115}
116} catch (error) {
177console.log("Handling POST request to /analyze");
178const formData = await request.formData();
179const image = formData.get('image') as File;
180181if (!image) {
182console.log("No image provided in request");
183return new Response('No image provided', { status: 400 });
184} else {
185console.log("Image received, size:", image.size);
186}
187192async start(controller) {
193try {
194console.log("Starting to process image");
195const arrayBuffer = await image.arrayBuffer();
196const base64Image = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
197198console.log("Sending request to OpenAI");
202{
203role: "system",
204content: "You are a hilarious and overly enthusiastic ego booster. Your job is to provide 5 funny, specific, and over-the-top compliments about the person's appearance in the image. Be creative, exaggerate, and make it entertaining! Keep each compliment short and punchy, around 10-15 words max. Use lots of emojis and fun language. Respond in markdown format, with each compliment as a separate bullet point."
205},
206{
208content: [
209{ type: "text", text: "Analyze this selfie and give me 5 short, funny, specific compliments about my appearance:" },
210{ type: "image_url", image_url: { url: `data:image/jpeg;base64,${base64Image}` } }
211]
212}
5/**
6* Provides functions for interacting with your account's blob storage.
7* Blobs can store any data type (text, JSON, images, etc.) and allow
8* retrieval across different vals using the same key.
9* ([Docs ↗](https://docs.val.town/std/blob))
1415<img
16src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/d2a422fe-8dc3-4f04-aaa3-3c35a2e99100/public"
17width="500px"
18/>
50where they can pick which way to login: email, Google, Github, etc.
5152
5354[Live Demo](https://www.val.town/v/stevekrouse/lastlogin_demo)
lastlogin_demoREADME.md1 match
12
34
switchbot_partyREADME.md1 match
3We hosted a party in the Val Town office and I texted a link to this site to all guests:
45
67You can see a demo here: https://x.com/stevekrouse/status/1819018859099132128
whenfilmedmain.tsx3 matches
78const TMDB_API_BASE = "https://api.themoviedb.org/3"
9const TMDB_IMAGE_BASE = "https://image.tmdb.org/t/p/w200"
1011const headers = {
65movies.map((movie, index) => `
66<div class="movie-container">
67<img src="${TMDB_IMAGE_BASE}${movie.poster_path}" alt="${movie.title}" style="width: 100px;">
68<div class="movie-info">
69<h3>${movie.title}</h3>
130return `
131<div class="movie-result ${resultClass}">
132<img src="${TMDB_IMAGE_BASE}${movie.poster_path}" alt="${movie.title}" style="width: 100px;">
133<div class="movie-info">
134<h3>${movie.title}</h3>
hardwarebingoREADME.md1 match
45<img width="300px"
6src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/3618d5f1-fe2c-4b44-bdef-3c679f390700/public"/>
78
azureCheetahmain.tsx1 match
42functions where possible. Unless specified, don't add error handling,
43make sure that errors bubble up to the caller.
44Avoid external images or base64 images, use emojis, unicode symtols, or icon fonts/libraries instead, unless that's
45not practical for the user's request (e.g. if they ask for a particular animated gif).
46If the user asks for something that requires persistence, use the Val Town Blob storage API, unless