← Asian3D assetfogon/abanico-gigante
Abanico gigante
Drag to turn it// «Abanico gigante» · gpt-6-sol (medium)
// A big open Japanese folding fan standing upright on a small stand: a half-circle of red paper with a white Mount Fuji and a gold sun painted on it, dark wooden ribs fanning out from the bottom pivot.
const cx = 24;
const pivotZ = 14;
const minAngle = 9 * Math.PI / 180;
const maxAngle = 171 * Math.PI / 180;
function onFan(x, z) {
const dx = x - cx;
const dz = z - pivotZ;
const radius = Math.hypot(dx, dz);
const angle = Math.atan2(dz, dx);
return radius >= 2.5 && radius <= 22 &&
angle >= minAngle && angle <= maxAngle;
}
// Low lacquered display stand.
box(15, 17, 0, 33, 30, 1, "#541f22");
box(16, 16, 1, 32, 29, 2, "#8c2c2c");
box(17, 16, 2, 31, 17, 2, "#e5ae51");
box(18, 18, 3, 30, 28, 3, "#402427");
box(19, 19, 3, 20, 23, 12, "#412728");
box(28, 19, 3, 29, 23, 12, "#412728");
box(19, 18, 5, 29, 20, 6, "#752b2b");
box(20, 17, 6, 28, 17, 6, "#e5ae51");
box(20, 20, 10, 28, 23, 11, "#591e24");
box(21, 19, 11, 27, 22, 12, "#dca449");
// Solid paper, shaded in alternating folds.
for (let x = 2; x <= 46; x++) {
for (let z = 14; z <= 36; z++) {
if (!onFan(x, z)) continue;
const radius = Math.hypot(x - cx, z - pivotZ);
const angle = Math.atan2(z - pivotZ, x - cx);
const fold = Math.floor((angle - minAngle) / (Math.PI / 12));
let color = fold % 2 ? "#b82732" : "#a71928";
if (rand() < 0.07) color = fold % 2 ? "#c7373e" : "#951b29";
if (radius > 20.8) color = "#dfaa50";
else if (radius > 19.9) color = "#76212a";
set(x, 19, z, color);
set(x, 20, z, "#8d202a");
set(x, 21, z, "#642129");
}
}
// Dark wooden ribs radiating from the pivot.
for (let degrees = 12; degrees <= 168; degrees += 13) {
const angle = degrees * Math.PI / 180;
for (let radius = 3; radius <= 21; radius += 0.4) {
const x = Math.round(cx + Math.cos(angle) * radius);
const z = Math.round(pivotZ + Math.sin(angle) * radius);
if (onFan(x, z)) {
set(x, 18, z, radius > 18 ? "#9b5838" : "#382729");
}
}
}
// Raised gold edging along the curved rim.
for (let x = 2; x <= 46; x++) {
for (let z = 14; z <= 36; z++) {
if (!onFan(x, z)) continue;
const radius = Math.hypot(x - cx, z - pivotZ);
const angle = Math.atan2(z - pivotZ, x - cx);
if (radius > 21.25 ||
angle < minAngle + 0.035 ||
angle > maxAngle - 0.035) {
set(x, 17, z, "#ecc063");
}
}
}
// Golden sun, painted on the right side.
for (let x = 29; x <= 39; x++) {
for (let z = 24; z <= 34; z++) {
const distance = Math.hypot(x - 34, z - 29);
if (!onFan(x, z) || distance > 4.25) continue;
const color = distance > 3.35 ? "#f3c363" :
distance < 2.1 ? "#ffdf83" : "#e8a644";
set(x, 17, z, color);
}
}
// Mount Fuji, with a broad blue-grey base and snowy summit.
for (let z = 17; z <= 32; z++) {
for (let x = 8; x <= 38; x++) {
const halfWidth = (32 - z) * 1.35 + 0.6;
const dx = x - 22;
if (!onFan(x, z) || Math.abs(dx) > halfWidth) continue;
let color = dx > 1 ? "#687e87" : "#91a1a2";
if (z >= 23 || (z >= 21 && Math.abs(dx) < (z - 19) * 1.3)) {
color = "#f6f0e3";
}
if (z >= 27 && dx >= -5 && dx < -1) color = "#d5dfe2";
if (z === 32) color = "#ffffff";
set(x, 17, z, color);
}
}
line(21, 17, 29, 17, 17, 23, 0, "#fff8ed");
line(24, 17, 29, 28, 17, 24, 0, "#fff8ed");
line(19, 17, 27, 15, 17, 22, 0, "#e7edef");
// Small gold cloud strokes.
for (const cloud of [[8, 27], [37, 22]]) {
for (let i = 0; i < 8; i++) {
const x = cloud[0] + i;
const z = cloud[1] + Math.round(Math.sin(i * 0.8));
if (onFan(x, z) && get(x, 17, z) === undefined) {
set(x, 17, z, i % 3 === 0 ? "#ffebb0" : "#e8b758");
}
}
}
// Layered lacquer-and-gold pivot clasp.
cylinder(24, 16, 14, 2.7, 2, "#552126");
cylinder(24, 15, 14, 1.5, 1, "#e9b753");
set(24, 14, 15, "#fff0bc");import { draw } from "./assets/voxel";
import { abanicoGigante } from "./assets/abanico-gigante";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, abanicoGigante, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add abanico-gigante
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["abanico-gigante"] })
# It lands in client/assets/abanico-gigante.ts
# https://fogon.page/object/abanico-gigante