Skip to content

Commit 700c29f

Browse files
committed
feat: moar fishies (o3-mini-high testing)
1 parent 0e2ff29 commit 700c29f

File tree

11 files changed

+506
-224
lines changed

11 files changed

+506
-224
lines changed

showcase/fishies/src/App.css

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,75 @@
22
width: 100vw;
33
height: 100vh;
44
overflow: hidden;
5-
background: linear-gradient(180deg,
6-
#87CEEB 0%,
7-
rgba(135, 206, 235, 0.8) 20%,
8-
rgba(30, 144, 255, 0.9) 60%,
9-
#1E90FF 100%
10-
);
5+
background: linear-gradient(180deg, #0f4c81 0%, #1e90ff 50%, #0d3b66 100%);
116
perspective: 2000px;
127
transform-style: preserve-3d;
138
}
149

10+
/* The fish-tank container holds all moving parts */
1511
.fish-tank {
1612
width: 100%;
1713
height: 100%;
1814
position: relative;
1915
animation: tank-depth 20s infinite ease-in-out;
2016
}
2117

18+
/* Subtle light-ray overlay for extra depth */
19+
.fish-tank::before {
20+
content: "";
21+
position: absolute;
22+
top: 0;
23+
left: 0;
24+
width: 100%;
25+
height: 100%;
26+
background: radial-gradient(
27+
ellipse at center,
28+
rgba(255, 255, 255, 0.1),
29+
transparent
30+
);
31+
pointer-events: none;
32+
z-index: -1;
33+
}
34+
2235
@keyframes tank-depth {
23-
0%, 100% { transform: translate3d(0, 0, 0); }
24-
50% { transform: translate3d(50px, 30px, -200px); }
36+
0%,
37+
100% {
38+
transform: translate3d(0, 0, 0);
39+
}
40+
50% {
41+
transform: translate3d(50px, 30px, -200px);
42+
}
43+
}
44+
45+
@keyframes jellyfish-float {
46+
0% {
47+
transform: translate(0, 0) rotate(0deg);
48+
}
49+
50% {
50+
transform: translate(10px, -20px) rotate(5deg);
51+
}
52+
100% {
53+
transform: translate(0, 0) rotate(0deg);
54+
}
55+
}
56+
57+
@keyframes bubble-rise {
58+
0% {
59+
transform: translateY(0) scale(1);
60+
opacity: 1;
61+
}
62+
100% {
63+
transform: translateY(-100px) scale(0.5);
64+
opacity: 0;
65+
}
66+
}
67+
68+
@keyframes sway {
69+
0%,
70+
100% {
71+
transform: rotate(0deg);
72+
}
73+
50% {
74+
transform: rotate(5deg);
75+
}
2576
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// src/components/Bubble.tsx
2+
import { CSSProperties } from "react";
3+
4+
interface BubbleProps {
5+
x: number;
6+
y: number;
7+
size?: number;
8+
duration?: number;
9+
}
10+
11+
export const Bubble: React.FC<BubbleProps> = ({
12+
x,
13+
y,
14+
size = 10,
15+
duration = 4,
16+
}) => {
17+
const style: CSSProperties = {
18+
position: "absolute",
19+
left: `${x}px`,
20+
top: `${y}px`,
21+
width: `${size}px`,
22+
height: `${size}px`,
23+
backgroundColor: "rgba(255, 255, 255, 0.7)",
24+
borderRadius: "50%",
25+
zIndex: 0,
26+
animation: `bubble-rise ${duration}s linear infinite`,
27+
};
28+
29+
return <div style={style}></div>;
30+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// src/components/Coral.tsx
2+
import { CSSProperties } from "react";
3+
4+
interface CoralProps {
5+
x: number;
6+
y: number;
7+
size?: number;
8+
}
9+
10+
export const Coral: React.FC<CoralProps> = ({ x, y, size = 40 }) => {
11+
const style: CSSProperties = {
12+
position: "absolute",
13+
left: `${x}px`,
14+
top: `${y}px`,
15+
fontSize: `${size}px`,
16+
zIndex: 0,
17+
};
18+
19+
return <div style={style}>🪸</div>;
20+
};
Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,52 @@
1-
import { CSSProperties } from 'react'
1+
// src/components/Fish.tsx
2+
import { CSSProperties } from "react";
23

34
interface FishProps {
4-
x: number
5-
y: number
6-
direction: number
7-
color: string
8-
isDying?: boolean
9-
dyingStartTime?: number
10-
isBeingEaten?: boolean
5+
x: number;
6+
y: number;
7+
direction: number;
8+
color: string;
9+
isDying?: boolean;
10+
dyingStartTime?: number;
11+
isBeingEaten?: boolean;
1112
}
1213

13-
export const Fish: React.FC<FishProps> = ({ x, y, direction, color, isDying, dyingStartTime, isBeingEaten }) => {
14+
export const Fish: React.FC<FishProps> = ({
15+
x,
16+
y,
17+
direction,
18+
color,
19+
isDying,
20+
dyingStartTime,
21+
isBeingEaten,
22+
}) => {
1423
const style: CSSProperties = {
15-
position: 'absolute',
24+
position: "absolute",
1625
left: `${x}px`,
1726
top: `${y}px`,
27+
// Ensure fish (and later, predators) are rendered above decorations
28+
zIndex: 1,
1829
transform: `
1930
translate3d(0, 0, ${Math.sin(Date.now() / 1000) * 200}px)
2031
rotateY(${direction > 0 ? 0 : 180}deg)
21-
${isDying ? 'rotateZ(180deg)' : isBeingEaten ? 'rotateZ(0deg)' : 'rotateZ(-15deg)'}
32+
${
33+
isDying
34+
? "rotateZ(180deg)"
35+
: isBeingEaten
36+
? "rotateZ(0deg)"
37+
: "rotateZ(-15deg)"
38+
}
2239
scale(${1 + Math.sin(Date.now() / 1000) * 0.1})
2340
`,
24-
transition: isDying ? 'opacity 1s ease-out' : 'none',
25-
fontSize: '24px',
41+
transition: isDying ? "opacity 1s ease-out" : "none",
42+
fontSize: "24px",
2643
color,
2744
opacity: isDying ? (Date.now() - dyingStartTime! > 500 ? 0 : 1) : 1,
28-
}
45+
};
2946

30-
return <div style={style}>{isDying && Date.now() - dyingStartTime! > 500 ? '☠️' : '🐠'}</div>
31-
}
47+
return (
48+
<div style={style}>
49+
{isDying && Date.now() - dyingStartTime! > 500 ? "☠️" : "🐠"}
50+
</div>
51+
);
52+
};

0 commit comments

Comments
 (0)