@biunow/agent-biuart 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/server.mjs +575 -0
- package/data/styles.json +533 -0
- package/engine/audit_clip.py +46 -0
- package/engine/clip.html +24 -0
- package/engine/clip.js +104 -0
- package/engine/clip_schema.json +19 -0
- package/engine/clips/t1_3b1b.js +203 -0
- package/engine/clips/t2_keynote_ui.js +347 -0
- package/engine/clips/t3_finance_chart.js +206 -0
- package/engine/clips/y1_kurzgesagt.js +183 -0
- package/engine/clips/y2_vox.js +150 -0
- package/engine/clips/y3_whiteboard.js +209 -0
- package/engine/clips/y4_storytime.js +194 -0
- package/engine/clips/y5_kinetic_type.js +134 -0
- package/engine/compare.py +19 -0
- package/engine/demos/_shared/hero/c1_0.png +0 -0
- package/engine/demos/_shared/hero/c1_1.png +0 -0
- package/engine/demos/_shared/hero/c1_2.png +0 -0
- package/engine/demos/_shared/hero/c3_line.png +0 -0
- package/engine/demos/_shared/hero.js +96 -0
- package/engine/demos/long_scroll/eras.js +23 -0
- package/engine/demos/long_scroll/frames/8bit_act/01.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/02.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/03.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/04.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/05.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/06.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/07.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/08.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_act/meta.json +69 -0
- package/engine/demos/long_scroll/frames/8bit_walk/01.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/02.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/03.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/04.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/05.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/06.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/07.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/08.png +0 -0
- package/engine/demos/long_scroll/frames/8bit_walk/meta.json +69 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/01.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/02.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/03.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/04.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/05.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/06.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/07.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/08.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_dodge/meta.json +69 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/01.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/02.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/03.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/04.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/05.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/06.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/07.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/08.png +0 -0
- package/engine/demos/long_scroll/frames/egypt_walk8/meta.json +69 -0
- package/engine/demos/long_scroll/frames/monet_throw/01.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/02.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/03.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/04.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/05.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/06.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/07.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/08.png +0 -0
- package/engine/demos/long_scroll/frames/monet_throw/meta.json +71 -0
- package/engine/demos/long_scroll/frames/monet_walk/01.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/02.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/03.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/04.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/05.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/06.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/07.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/08.png +0 -0
- package/engine/demos/long_scroll/frames/monet_walk/meta.json +71 -0
- package/engine/demos/long_scroll/lib/acts.js +87 -0
- package/engine/demos/long_scroll/lib/crossing.js +463 -0
- package/engine/demos/long_scroll/lib/world.js +143 -0
- package/engine/demos/long_scroll/lib/xing2_ding.js +42 -0
- package/engine/demos/long_scroll/lib/xing2_jia.js +114 -0
- package/engine/demos/long_scroll/lib/xing2_yi.js +133 -0
- package/engine/demos/long_scroll/segments/02_egypt.js +234 -0
- package/engine/demos/long_scroll/segments/14_8bit.js +118 -0
- package/engine/demos/long_scroll/segments/28_monet.js +86 -0
- package/engine/demos/t1_3b1b/eras.js +11 -0
- package/engine/demos/t1_3b1b/t1_s1.js +101 -0
- package/engine/demos/t1_3b1b/t1_s2.js +74 -0
- package/engine/demos/t1_3b1b/t1_s3.js +65 -0
- package/engine/demos/t2_keynote_ui/eras.js +10 -0
- package/engine/demos/t2_keynote_ui/t2_s1.js +57 -0
- package/engine/demos/t2_keynote_ui/t2_s2.js +70 -0
- package/engine/demos/t2_keynote_ui/t2_s3.js +61 -0
- package/engine/demos/t3_finance_chart/eras.js +11 -0
- package/engine/demos/t3_finance_chart/t3_s1.js +48 -0
- package/engine/demos/t3_finance_chart/t3_s2.js +42 -0
- package/engine/demos/t3_finance_chart/t3_s3.js +51 -0
- package/engine/demos/y1_kurzgesagt/eras.js +10 -0
- package/engine/demos/y1_kurzgesagt/kurzgesagt.js +347 -0
- package/engine/demos/y2_vox/eras.js +10 -0
- package/engine/demos/y2_vox/vox.js +240 -0
- package/engine/demos/y3_whiteboard/eras.js +10 -0
- package/engine/demos/y3_whiteboard/whiteboard.js +162 -0
- package/engine/demos/y4_storytime/eras.js +14 -0
- package/engine/demos/y4_storytime/s1_desk.js +18 -0
- package/engine/demos/y4_storytime/s2_screen.js +82 -0
- package/engine/demos/y4_storytime/s3_react.js +39 -0
- package/engine/demos/y4_storytime/s4_wide.js +16 -0
- package/engine/demos/y4_storytime/s5_close.js +18 -0
- package/engine/demos/y4_storytime/story.js +25 -0
- package/engine/demos/y4_storytime/vo_env.js +2 -0
- package/engine/demos/y4_storytime/world.js +73 -0
- package/engine/demos/y5_kinetic_type/eras.js +16 -0
- package/engine/demos/y5_kinetic_type/k1_title.js +38 -0
- package/engine/demos/y5_kinetic_type/k2_complete.js +55 -0
- package/engine/demos/y5_kinetic_type/k3_chat.js +47 -0
- package/engine/demos/y5_kinetic_type/k4_agent.js +49 -0
- package/engine/demos/y5_kinetic_type/kinetic.js +52 -0
- package/engine/engine.js +277 -0
- package/engine/eras.js +60 -0
- package/engine/eras_gallery.js +115 -0
- package/engine/eras_style_studies.js +20 -0
- package/engine/examples/assets/K/347/272/277/345/233/276_/346/250/252/345/261/217.png +0 -0
- package/engine/examples/assets//347/273/210/347/253/257_for/345/276/252/347/216/257/346/261/202/345/222/214.png +0 -0
- package/engine/examples/assets//347/273/210/347/253/257_sum/346/261/202/345/222/214.png +0 -0
- package/engine/examples/assets//350/220/245/346/224/266/345/233/276_/347/253/226/345/261/217.png +0 -0
- package/engine/examples/assets//350/264/242/347/273/217/345/233/276/350/241/250_/346/250/252/345/261/217.png +0 -0
- package/engine/examples/t1_3b1b.json +19 -0
- package/engine/examples/t2_fullbleed_pulse.json +15 -0
- package/engine/examples/t2_keynote_ui.json +15 -0
- package/engine/examples/t3_finance_chart.json +29 -0
- package/engine/examples/y1_kurzgesagt.json +16 -0
- package/engine/examples/y2_vox.json +14 -0
- package/engine/examples/y3_whiteboard.json +17 -0
- package/engine/examples/y4_storytime.json +52 -0
- package/engine/examples/y5_kinetic_type.json +14 -0
- package/engine/index.html +42 -0
- package/engine/lib/THREE_LICENSE.txt +21 -0
- package/engine/lib/brush.js +149 -0
- package/engine/lib/camera.js +99 -0
- package/engine/lib/chart.js +152 -0
- package/engine/lib/collage.js +97 -0
- package/engine/lib/diagram.js +264 -0
- package/engine/lib/finish.js +70 -0
- package/engine/lib/fonts/AlfaSlabOne-400.woff +0 -0
- package/engine/lib/fonts/Anton-400.woff +0 -0
- package/engine/lib/fonts/ArchivoBlack-400.woff +0 -0
- package/engine/lib/fonts/Bangers-400.woff +0 -0
- package/engine/lib/fonts/Caveat-600.woff +0 -0
- package/engine/lib/fonts/Cinzel-400.woff +0 -0
- package/engine/lib/fonts/Cinzel-700.woff +0 -0
- package/engine/lib/fonts/CormorantGaramond-500.woff +0 -0
- package/engine/lib/fonts/CormorantGaramond-500i.woff +0 -0
- package/engine/lib/fonts/CormorantGaramond-700.woff +0 -0
- package/engine/lib/fonts/EBGaramond-400.woff +0 -0
- package/engine/lib/fonts/EBGaramond-400i.woff +0 -0
- package/engine/lib/fonts/EBGaramond-600.woff +0 -0
- package/engine/lib/fonts/Exo2-800i.woff +0 -0
- package/engine/lib/fonts/GochiHand-400.woff +0 -0
- package/engine/lib/fonts/IMFellEnglish-400.woff +0 -0
- package/engine/lib/fonts/IMFellEnglish-400i.woff +0 -0
- package/engine/lib/fonts/Inter-var.woff +0 -0
- package/engine/lib/fonts/JosefinSans-700.woff +0 -0
- package/engine/lib/fonts/Kalam-700.woff +0 -0
- package/engine/lib/fonts/LICENSES.md +40 -0
- package/engine/lib/fonts/LXGWWenKai-500.woff +0 -0
- package/engine/lib/fonts/LibreBaskerville-400.woff +0 -0
- package/engine/lib/fonts/LibreBaskerville-700.woff +0 -0
- package/engine/lib/fonts/LilitaOne-400.woff +0 -0
- package/engine/lib/fonts/Marcellus-400.woff +0 -0
- package/engine/lib/fonts/NotoSansSC-500.woff +0 -0
- package/engine/lib/fonts/NotoSansSC-700.woff +0 -0
- package/engine/lib/fonts/NotoSansSC-800.woff +0 -0
- package/engine/lib/fonts/NotoSansSC-900.woff +0 -0
- package/engine/lib/fonts/NotoSansSC-sub.woff +0 -0
- package/engine/lib/fonts/NotoSerifJP-600.woff +0 -0
- package/engine/lib/fonts/NotoSerifSC-sub.woff +0 -0
- package/engine/lib/fonts/OFL.txt +94 -0
- package/engine/lib/fonts/PlayfairDisplay-400i.woff +0 -0
- package/engine/lib/fonts/PlayfairDisplay-700.woff +0 -0
- package/engine/lib/fonts/PlayfairDisplay-700i.woff +0 -0
- package/engine/lib/fonts/Poppins-600.woff +0 -0
- package/engine/lib/fonts/Poppins-700.woff +0 -0
- package/engine/lib/fonts/Poppins-800.woff +0 -0
- package/engine/lib/fonts/PressStart2P-400.woff +0 -0
- package/engine/lib/fonts/Righteous-400.woff +0 -0
- package/engine/lib/fonts/RobotoCondensed-var.woff +0 -0
- package/engine/lib/fonts/Rye-400.woff +0 -0
- package/engine/lib/fonts/UnifrakturMaguntia-400.woff +0 -0
- package/engine/lib/fonts/cmunrm.woff +0 -0
- package/engine/lib/fonts/cmunti.woff +0 -0
- package/engine/lib/fonts/index.json +1 -0
- package/engine/lib/fonts.js +56 -0
- package/engine/lib/kit.js +91 -0
- package/engine/lib/media.js +118 -0
- package/engine/lib/medium.js +258 -0
- package/engine/lib/motion.js +111 -0
- package/engine/lib/paint.js +200 -0
- package/engine/lib/palettes.js +57 -0
- package/engine/lib/post.js +108 -0
- package/engine/lib/render.js +189 -0
- package/engine/lib/rig.js +390 -0
- package/engine/lib/rig_huashu.js +171 -0
- package/engine/lib/three.min.js +7 -0
- package/engine/lib/toon.js +186 -0
- package/engine/lib/typo.js +136 -0
- package/engine/lib/ui.js +141 -0
- package/engine/lib/util.js +92 -0
- package/engine/render.py +157 -0
- package/engine/scenes/01_cave.js +364 -0
- package/engine/scenes/02_egypt.js +524 -0
- package/engine/scenes/03_greek.js +448 -0
- package/engine/scenes/04_roman.js +555 -0
- package/engine/scenes/05_gothic.js +522 -0
- package/engine/scenes/06_renaissance.js +338 -0
- package/engine/scenes/08_impressionism.js +206 -0
- package/engine/scenes/09_postimp.js +183 -0
- package/engine/scenes/10_nouveau.js +334 -0
- package/engine/scenes/11_cubism.js +265 -0
- package/engine/scenes/12_bauhaus.js +214 -0
- package/engine/scenes/13_pop.js +269 -0
- package/engine/scenes/14_8bit.js +238 -0
- package/engine/scenes/15_raytrace.js +300 -0
- package/engine/scenes/16_2026.js +565 -0
- package/engine/scenes/17_ink.js +273 -0
- package/engine/scenes/18_klimt.js +227 -0
- package/engine/scenes/19_munch.js +153 -0
- package/engine/scenes/20_dunhuang.js +215 -0
- package/engine/scenes/21_kusama.js +124 -0
- package/engine/scenes/22_constructivism.js +205 -0
- package/engine/scenes/23_dali.js +221 -0
- package/engine/scenes/24_hopper.js +150 -0
- package/engine/scenes/25_ghibli.js +251 -0
- package/engine/scenes/26_vaporwave.js +191 -0
- package/engine/scenes/27_kirby.js +255 -0
- package/engine/scenes/28_monet.js +176 -0
- package/engine/scenes/29_seurat.js +104 -0
- package/engine/scenes/30_matisse.js +151 -0
- package/engine/scenes/31_haring.js +109 -0
- package/engine/scenes/32_rembrandt.js +217 -0
- package/engine/scenes/33_rubberhose.js +219 -0
- package/engine/scenes/34_shadowpuppet.js +195 -0
- package/engine/scenes/35_shinkai.js +197 -0
- package/engine/scenes/36_picasso_blue.js +123 -0
- package/engine/scenes/38_giotto.js +133 -0
- package/engine/scenes/39_piero.js +53 -0
- package/engine/scenes/40_raphael.js +96 -0
- package/engine/scenes/41_michelangelo.js +112 -0
- package/engine/scenes/42_guardi.js +70 -0
- package/engine/scenes/43_lorenzetti.js +145 -0
- package/engine/scenes/44_cortona.js +86 -0
- package/engine/scenes/45_renoir.js +86 -0
- package/engine/scenes/46_pissarro.js +82 -0
- package/engine/scenes/47_sisley.js +94 -0
- package/engine/scenes/48_gauguin.js +107 -0
- package/engine/scenes/49_chagall.js +60 -0
- package/engine/scenes/50_ma_yuan.js +131 -0
- package/engine/scenes/51_persian_miniature.js +149 -0
- package/engine/scenes/52_south_park.js +105 -0
- package/engine/scenes/53_pixar.js +60 -0
- package/engine/scenes/54_ghibli_lab.js +68 -0
- package/engine/scenes/55_dunhuang.js +161 -0
- package/engine/scenes/index.js +28 -0
- package/engine/spec_assets.py +76 -0
- package/engine/transitions.js +929 -0
- package/engine//346/227/266/344/273/243/344/275/234/350/200/205/350/247/204/350/214/203.md +49 -0
- package/lib/host.mjs +754 -0
- package/lib/render-bridge.mjs +543 -0
- package/lib/render-cli.mjs +98 -0
- package/lib/storyboard-lint.mjs +54 -0
- package/manifest.json +52 -0
- package/package.json +8 -4
- package/runtime/package.json +8 -0
- package/skills/biuart/SKILL.md +154 -0
- package/skills/biuart/references/01-/346/213/206/350/247/243.md +55 -0
- package/skills/biuart/references/02-/346/234/272/345/210/266.md +41 -0
- package/skills/biuart/references/03-/344/270/200/345/270/247/345/205/210/350/241/214/345/233/233/346/235/241/350/267/257/347/272/277.md +39 -0
- package/skills/biuart/references/04-/347/272/257/344/273/243/347/240/201/347/273/230/345/210/266.md +92 -0
- package/skills/biuart/references/05-/350/212/202/345/245/217/344/270/216/351/205/215/344/271/220.md +19 -0
- package/skills/biuart/references/06-/345/217/243/346/222/255/351/251/261/345/212/250/347/232/204/350/211/272/346/234/257/347/237/255/347/211/207.md +31 -0
- package/skills/biuart/references/07-/346/255/243/351/235/242/347/273/217/351/252/214.md +196 -0
- package/skills/biuart/references/08-/351/243/216/346/240/274/344/275/234/350/200/205/350/247/204/350/214/203.md +61 -0
- package/skills/biuart/references/09-/350/247/206/351/242/221/345/212/250/347/224/273/350/257/255/346/263/225.md +382 -0
- package/skills/biuart/references/10-/350/247/222/350/211/262.md +34 -0
- package/skills/biuart/references/11-/351/225/277/345/215/267/347/251/277/350/266/212/347/211/207.md +43 -0
- package/skills/biuart/references/12-/345/217/243/346/222/255/346/225/264/347/211/207/344/270/216/347/273/217/351/252/214/345/233/236/346/265/201.md +25 -0
- package/skills/biuart/references/13-/345/217/243/346/222/255/344/270/216/350/257/255/351/237/263/345/244/215/345/210/273.md +7 -0
- package/skills/biuart/references/15-/350/267/250/345/234/272/346/231/257/351/243/216/346/240/274/346/217/220/347/202/274.md +48 -0
- package/skills/biuart/references/16-/351/243/216/346/240/274/346/274/224/347/244/27295/345/210/206/345/215/217/350/256/256.md +103 -0
- package/skills/biuart/references/about-author.md +99 -0
- package/skills/biuart/references/capabilities.md +91 -0
- package/skills/biuart/references/compatibility.md +34 -0
- package/skills/biuart/references/images.md +97 -0
- package/skills/biuart/references/voice-model-review.md +18 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/t1_3b1b.md +122 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/t2_keynote_ui.md +117 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/t3_finance_chart.md +116 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y1_kurzgesagt.md +193 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y2_vox.md +195 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y3_whiteboard.md +190 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y4_storytime.md +166 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y5_kinetic_type.md +158 -0
- package/skills/biuart/references//345/212/250/347/224/273/350/257/255/346/263/225/y6_presenter_explainer.md +24 -0
- package/skills/biuart/references//345/217/243/346/222/255API.md +125 -0
- package/skills/biuart/references//350/211/262/346/235/277.md +38 -0
- package/skills/biuart/references//350/247/222/350/211/262/347/262/276/347/273/206/345/272/246.md +61 -0
- package/skills/biuart/references//351/225/234/345/244/264/350/241/250/346/250/241/346/235/277.md +80 -0
- package/skills/biuart/references//351/225/234/345/244/264/350/257/255/350/250/200.md +73 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/01_cave.md +46 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/02_egypt.md +64 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/03_greek.md +50 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/04_roman.md +99 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/05_gothic.md +32 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/06_renaissance.md +41 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/08_impressionism.md +34 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/09_postimp.md +17 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/10_nouveau.md +31 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/11_cubism.md +30 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/12_bauhaus.md +30 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/13_pop.md +29 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/14_8bit.md +27 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/15_raytrace.md +32 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/16_2026.md +55 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/17_ink.md +50 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/18_klimt.md +37 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/19_munch.md +42 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/20_dunhuang.md +49 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/21_kusama.md +32 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/22_constructivism.md +35 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/23_dali.md +29 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/24_hopper.md +30 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/25_ghibli.md +55 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/26_vaporwave.md +27 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/27_kirby.md +30 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/28_monet.md +39 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/29_seurat.md +31 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/30_matisse.md +26 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/31_haring.md +22 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/32_rembrandt.md +29 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/33_rubberhose.md +31 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/34_shadowpuppet.md +40 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/35_shinkai.md +34 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/36_picasso_blue.md +25 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/37_rick_morty.md +48 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/38_giotto.md +67 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/39_piero.md +59 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/40_raphael.md +65 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/41_michelangelo.md +65 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/42_guardi.md +65 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/43_lorenzetti.md +69 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/44_cortona.md +66 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/45_renoir.md +66 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/46_pissarro.md +66 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/47_sisley.md +67 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/48_gauguin.md +66 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/49_chagall.md +59 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/50_ma_yuan.md +68 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/51_persian_miniature.md +66 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/52_south_park.md +65 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/53_pixar.md +61 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/55_dunhuang.md +41 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/INDEX.md +89 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/_/350/275/254/345/234/272_/350/277/201/347/247/273/346/265/213/350/257/225.md +53 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/_/351/207/215/345/201/232/350/277/233/345/272/246.md +37 -0
- package/skills/biuart/references//351/243/216/346/240/274/351/205/215/346/226/271/_/351/237/263/350/275/250_/350/211/272/346/234/257/345/217/262/351/200/237/351/200/232.md +135 -0
- package/studio/app.js +380 -0
- package/studio/assert-panel-permit.mjs +67 -0
- package/studio/composer.css +465 -0
- package/studio/composer.js +480 -0
- package/studio/index.html +97 -0
- package/studio/optimize-prompt.mjs +84 -0
- package/studio/optimize-prompt.test.mjs +47 -0
- package/studio/recipes.mjs +87 -0
- package/studio/select-menu.js +450 -0
- package/studio/styles.css +71 -0
- package/studio/to-english-prompt.mjs +149 -0
- package/studio/to-english-prompt.test.mjs +72 -0
- package/README.md +0 -3
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// 1993 早期光线追踪 CGI——纯代码(不用 3D 引擎)。
|
|
2
|
+
// 管线:①静态底(青绿墙+窗外粉紫夕阳远山,缓存)→ ②逐像素透视棋盘地面(2×2 超采样,缓存)
|
|
3
|
+
// → ③物体层(椅/玻璃桌/少女/猫)先「倒着」画一遍当地面反射(按各自接地线镜像、半透明、往下渐隐)→ ④正着画物体
|
|
4
|
+
// → ⑤道具(绿锥、铬球逐像素环境映射、紫环 48 颗球按深度排序拼成圆环并自转)→ ⑥镜头光晕(lighter 叠加)。
|
|
5
|
+
// 「90 年代塑料感」= 每个部件:底色 → 径向渐变(高光点亮、边缘压暗)→ 左侧青色环境反光 → 一颗硬边白色镜面高光。
|
|
6
|
+
SCENES['15_raytrace'] = (() => {
|
|
7
|
+
const W = 1920, H = 1080, P = PAINT, { clamp, lerp } = U;
|
|
8
|
+
const FLOOR_Y = 790, VP = [960, 480];
|
|
9
|
+
const SUN = [695, 225];
|
|
10
|
+
const rgba = (h, a) => P.rgb(P.hex(h), a);
|
|
11
|
+
|
|
12
|
+
// ---------- 塑料着色 ----------
|
|
13
|
+
// 球面感:(hx,hy) 高光中心,R 影响半径;dark 边缘压暗量
|
|
14
|
+
function plastic(c, path, base, hx, hy, R, { dark = 0.42, spec = 0.85, specR = 0.16, rim = true, specAng = -0.5 } = {}) {
|
|
15
|
+
c.fillStyle = base; c.fill(path);
|
|
16
|
+
c.save(); c.clip(path);
|
|
17
|
+
const g = c.createRadialGradient(hx, hy, 0, hx + R * 0.25, hy + R * 0.3, R);
|
|
18
|
+
g.addColorStop(0, 'rgba(255,255,255,.55)'); g.addColorStop(0.28, 'rgba(255,255,255,.06)'); g.addColorStop(0.62, 'rgba(0,0,0,0)'); g.addColorStop(1, `rgba(10,0,30,${dark})`);
|
|
19
|
+
c.fillStyle = g; c.fillRect(hx - R * 3, hy - R * 3, R * 6, R * 6);
|
|
20
|
+
if (rim) { c.globalCompositeOperation = 'lighter'; c.lineWidth = R * 0.18; c.strokeStyle = 'rgba(70,150,150,.28)'; c.translate(-R * 0.04, 0); c.stroke(path); c.globalCompositeOperation = 'source-over'; }
|
|
21
|
+
c.restore();
|
|
22
|
+
if (spec) { c.save(); c.clip(path); c.fillStyle = `rgba(255,255,255,${spec})`; c.beginPath(); c.ellipse(hx, hy, R * specR, R * specR * 0.55, specAng, 0, 7); c.fill(); c.restore(); }
|
|
23
|
+
}
|
|
24
|
+
// 圆柱感:沿 A→B 的肢体,渐变横跨宽度方向
|
|
25
|
+
function cyl(c, path, base, A, B, w, { spec = 0.7 } = {}) {
|
|
26
|
+
c.fillStyle = base; c.fill(path);
|
|
27
|
+
const a = Math.atan2(B[1] - A[1], B[0] - A[0]), nx = Math.cos(a + Math.PI / 2), ny = Math.sin(a + Math.PI / 2);
|
|
28
|
+
const M = [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];
|
|
29
|
+
const s = ny < 0 ? -1 : 1; // 让渐变从「上方」到「下方」
|
|
30
|
+
const g = c.createLinearGradient(M[0] - nx * s * w / 2, M[1] - ny * s * w / 2, M[0] + nx * s * w / 2, M[1] + ny * s * w / 2);
|
|
31
|
+
g.addColorStop(0, 'rgba(10,0,30,.25)'); g.addColorStop(0.22, 'rgba(255,255,255,.5)'); g.addColorStop(0.34, 'rgba(255,255,255,.08)'); g.addColorStop(0.7, 'rgba(0,0,0,.05)'); g.addColorStop(1, 'rgba(10,0,30,.45)');
|
|
32
|
+
c.save(); c.clip(path); c.fillStyle = g; c.fillRect(Math.min(A[0], B[0]) - w * 2, Math.min(A[1], B[1]) - w * 2, Math.abs(B[0] - A[0]) + w * 4, Math.abs(B[1] - A[1]) + w * 4);
|
|
33
|
+
if (spec) { c.strokeStyle = `rgba(255,255,255,${spec})`; c.lineWidth = w * 0.09; c.lineCap = 'round'; const o = w * 0.22 * s; c.beginPath(); c.moveTo(lerp(A[0], B[0], .2) - nx * o, lerp(A[1], B[1], .2) - ny * o); c.lineTo(lerp(A[0], B[0], .75) - nx * o, lerp(A[1], B[1], .75) - ny * o); c.stroke(); }
|
|
34
|
+
c.restore();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------- 静态底:墙、踢脚线、窗 ----------
|
|
38
|
+
function background(g) {
|
|
39
|
+
const wg = g.createRadialGradient(560, 260, 50, 700, 400, 1500); wg.addColorStop(0, '#7dbcb9'); wg.addColorStop(0.45, '#64a6a6'); wg.addColorStop(1, '#3f8285');
|
|
40
|
+
g.fillStyle = wg; g.fillRect(0, 0, W, FLOOR_Y);
|
|
41
|
+
// 窗的投影(右下偏移、软边)
|
|
42
|
+
g.save(); g.filter = 'blur(10px)'; g.fillStyle = 'rgba(20,60,70,.45)'; g.fillRect(372, 140, 450, 452); g.restore();
|
|
43
|
+
// 窗外:粉紫夕阳
|
|
44
|
+
g.save(); g.beginPath(); g.rect(375, 135, 410, 410); g.clip();
|
|
45
|
+
const sg = g.createLinearGradient(0, 135, 0, 480); sg.addColorStop(0, '#a24cc4'); sg.addColorStop(0.45, '#df62ae'); sg.addColorStop(0.8, '#f5a08a'); sg.addColorStop(1, '#f8c070');
|
|
46
|
+
g.fillStyle = sg; g.fillRect(375, 135, 410, 410);
|
|
47
|
+
// 远山(两层)+雪顶+线框网格
|
|
48
|
+
const mtn = (pts, col, snow) => {
|
|
49
|
+
g.beginPath(); g.moveTo(375, 545); pts.forEach(p => g.lineTo(...p)); g.lineTo(785, 545); g.closePath();
|
|
50
|
+
const mg = g.createLinearGradient(0, 340, 0, 545); mg.addColorStop(0, col[0]); mg.addColorStop(1, col[1]); g.fillStyle = mg; g.fill();
|
|
51
|
+
g.save(); g.clip(); g.strokeStyle = 'rgba(255,170,230,.45)'; g.lineWidth = 1.5;
|
|
52
|
+
for (let x = 375; x < 785; x += 28) { g.beginPath(); g.moveTo(x, 330); g.lineTo(x, 545); g.stroke(); }
|
|
53
|
+
for (let y = 360; y < 545; y += 26) { g.beginPath(); g.moveTo(375, y); g.lineTo(785, y); g.stroke(); }
|
|
54
|
+
g.fillStyle = '#fbeef6'; snow.forEach(([x, y, w]) => { g.beginPath(); g.moveTo(x - w, y + w * 0.9); g.lineTo(x, y); g.lineTo(x + w, y + w * 0.9); g.lineTo(x + w * 0.4, y + w * 0.6); g.lineTo(x, y + w * 0.95); g.lineTo(x - w * 0.5, y + w * 0.6); g.closePath(); g.fill(); });
|
|
55
|
+
g.restore();
|
|
56
|
+
};
|
|
57
|
+
mtn([[375, 380], [430, 352], [462, 345], [520, 400], [585, 440], [640, 420], [700, 390], [760, 395], [785, 400]], ['#b06ab8', '#8a50a8'], [[462, 345, 30], [700, 390, 22], [430, 352, 18]]);
|
|
58
|
+
mtn([[375, 470], [470, 430], [560, 470], [610, 440], [690, 480], [785, 440]], ['#8f5aa8', '#6c3f94'], [[610, 440, 18], [470, 430, 16]]);
|
|
59
|
+
g.restore();
|
|
60
|
+
// 白窗框(立体:亮边+暗边)
|
|
61
|
+
const frame = (x, y, w, h) => { const fg = g.createLinearGradient(x, y, x + w, y + h); fg.addColorStop(0, '#ffffff'); fg.addColorStop(1, '#d6dde0'); g.fillStyle = fg; g.fillRect(x, y, w, h); };
|
|
62
|
+
frame(355, 118, 445, 18); frame(355, 118, 20, 437); frame(783, 118, 17, 437); frame(355, 538, 445, 17); frame(571, 135, 14, 405); frame(375, 330, 410, 14);
|
|
63
|
+
g.fillStyle = 'rgba(0,40,60,.25)'; g.fillRect(375, 136, 410, 4); g.fillRect(375, 136, 4, 402);
|
|
64
|
+
// 窗台
|
|
65
|
+
const sl = g.createLinearGradient(0, 555, 0, 572); sl.addColorStop(0, '#ffffff'); sl.addColorStop(1, '#c9d2d6'); g.fillStyle = sl; g.fillRect(330, 555, 490, 16);
|
|
66
|
+
g.fillStyle = 'rgba(20,60,70,.35)'; g.fillRect(340, 571, 490, 12);
|
|
67
|
+
// 踢脚线
|
|
68
|
+
const bb = g.createLinearGradient(0, 760, 0, FLOOR_Y); bb.addColorStop(0, '#ffffff'); bb.addColorStop(1, '#d9dde0'); g.fillStyle = bb; g.fillRect(0, 760, W, FLOOR_Y - 760);
|
|
69
|
+
g.fillStyle = 'rgba(0,40,50,.25)'; g.fillRect(0, 756, W, 4);
|
|
70
|
+
}
|
|
71
|
+
// ---------- 透视棋盘地面(逐像素、2×2 超采样) ----------
|
|
72
|
+
function floor(g) {
|
|
73
|
+
const im = g.createImageData(W, H), d = im.data, TX = 0.27, TZ = 0.00029;
|
|
74
|
+
const A = P.hex('#d9dadf'), B = P.hex('#3e5d62');
|
|
75
|
+
for (let y = FLOOR_Y; y < H; y++) for (let x = 0; x < W; x++) {
|
|
76
|
+
let s = 0;
|
|
77
|
+
for (let k = 0; k < 4; k++) {
|
|
78
|
+
const yy = y + (k >> 1) * 0.5 + 0.25, xx = x + (k & 1) * 0.5 + 0.25, dy = yy - VP[1];
|
|
79
|
+
const X = (xx - VP[0]) / dy, Z = 1 / dy;
|
|
80
|
+
s += ((Math.floor(X / TX + 0.5) + Math.floor(Z / TZ)) & 1);
|
|
81
|
+
}
|
|
82
|
+
const q = s / 4, i = (y * W + x) * 4, fog = clamp(1 - (y - FLOOR_Y) / 140) * 0.35;
|
|
83
|
+
for (let ch = 0; ch < 3; ch++) d[i + ch] = lerp(lerp(A[ch], B[ch], q), [150, 190, 192][ch], fog);
|
|
84
|
+
d[i + 3] = 255;
|
|
85
|
+
}
|
|
86
|
+
g.putImageData(im, 0, 0);
|
|
87
|
+
// 地面上的环境光:窗光在地上的亮斑
|
|
88
|
+
const lg = g.createRadialGradient(560, 900, 20, 560, 900, 520); lg.addColorStop(0, 'rgba(255,200,230,.22)'); lg.addColorStop(1, 'rgba(255,200,230,0)');
|
|
89
|
+
g.fillStyle = lg; g.fillRect(0, FLOOR_Y, W, H - FLOOR_Y);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------- 家具 ----------
|
|
93
|
+
function chair(c) {
|
|
94
|
+
const wood = '#b77a40', post = (x, y0, y1, w) => { const p = new Path2D(); p.rect(x, y0, w, y1 - y0); cyl(c, p, wood, [x + w / 2, y0], [x + w / 2, y1], w, { spec: 0.5 }); grain(c, x, y0, w, y1 - y0); };
|
|
95
|
+
post(1478, 455, 912, 22); post(1442, 470, 760, 18);
|
|
96
|
+
for (let k = 0; k < 4; k++) { const p = new Path2D(); p.rect(1444, 500 + k * 52, 52, 12); cyl(c, p, '#a86a34', [1444, 506 + k * 52], [1496, 506 + k * 52], 12, { spec: 0.4 }); }
|
|
97
|
+
const seat = new Path2D(); seat.rect(1290, 738, 214, 22); cyl(c, seat, wood, [1290, 749], [1504, 749], 22); grain(c, 1290, 738, 214, 22);
|
|
98
|
+
post(1312, 760, 900, 18);
|
|
99
|
+
}
|
|
100
|
+
function grain(c, x, y, w, h) { // 木纹:细噪声线
|
|
101
|
+
c.save(); c.beginPath(); c.rect(x, y, w, h); c.clip(); c.strokeStyle = 'rgba(90,45,15,.35)'; c.lineWidth = 1.2;
|
|
102
|
+
const r = U.rng((x * 7 + y) | 0), vert = h > w;
|
|
103
|
+
for (let k = 0; k < (vert ? w : h) / 3; k++) { const o = r() * (vert ? w : h); c.beginPath(); for (let s = 0; s <= 20; s++) { const q = s / 20, n = P.noise(o * 0.3 + k, q * 4) * 3; vert ? (s ? c.lineTo(x + o + n, y + q * h) : c.moveTo(x + o + n, y + q * h)) : (s ? c.lineTo(x + q * w, y + o + n) : c.moveTo(x + q * w, y + o + n)); } c.stroke(); }
|
|
104
|
+
c.restore();
|
|
105
|
+
}
|
|
106
|
+
function table(c) {
|
|
107
|
+
// 大理石柱:竖向凹槽 + 圆柱明暗
|
|
108
|
+
const col = new Path2D(); col.rect(984, 664, 52, 212); cyl(c, col, '#efe6ea', [984, 770], [1036, 770], 52, { spec: 0 });
|
|
109
|
+
c.save(); c.clip(col); c.strokeStyle = 'rgba(120,100,140,.35)'; c.lineWidth = 2; for (let x = 990; x < 1036; x += 9) { c.beginPath(); c.moveTo(x, 664); c.lineTo(x, 876); c.stroke(); }
|
|
110
|
+
c.strokeStyle = 'rgba(150,130,170,.25)'; c.lineWidth = 1.5; c.beginPath(); for (let s = 0; s < 30; s++) c.lineTo(990 + P.noise(s * 0.3, 2) * 30 + 20, 664 + s * 7.3); c.stroke(); c.restore();
|
|
111
|
+
const lg = c.createLinearGradient(984, 0, 1036, 0); lg.addColorStop(0, 'rgba(255,255,255,0)'); lg.addColorStop(0.3, 'rgba(255,255,255,.6)'); lg.addColorStop(0.45, 'rgba(255,255,255,0)'); c.fillStyle = lg; c.fillRect(984, 664, 52, 212);
|
|
112
|
+
// 底座
|
|
113
|
+
const base = new Path2D(); base.ellipse(1010, 884, 56, 14, 0, 0, 7); base.rect(954, 872, 112, 12); plastic(c, base, '#e9e1e6', 985, 876, 80, { spec: 0.6, rim: false });
|
|
114
|
+
const cap = new Path2D(); cap.ellipse(1010, 668, 40, 9, 0, 0, 7); plastic(c, cap, '#efe6ea', 995, 664, 50, { spec: 0, rim: false });
|
|
115
|
+
}
|
|
116
|
+
function glassTop(c, t) {
|
|
117
|
+
// 玻璃桌面:半透明绿 + 厚边 + 高光条 + 一道会滑动的反光
|
|
118
|
+
c.save();
|
|
119
|
+
const top = new Path2D(); top.ellipse(1010, 650, 192, 20, 0, 0, 7);
|
|
120
|
+
const edge = new Path2D(); edge.ellipse(1010, 660, 192, 20, 0, 0, Math.PI); edge.lineTo(818, 650); edge.ellipse(1010, 650, 192, 20, 0, Math.PI, 0, true); edge.closePath();
|
|
121
|
+
c.fillStyle = 'rgba(40,140,90,.75)'; c.fill(edge);
|
|
122
|
+
const tg = c.createLinearGradient(818, 630, 1202, 670); tg.addColorStop(0, 'rgba(140,230,190,.55)'); tg.addColorStop(0.5, 'rgba(70,170,120,.45)'); tg.addColorStop(1, 'rgba(30,110,80,.6)');
|
|
123
|
+
c.fillStyle = tg; c.fill(top);
|
|
124
|
+
c.strokeStyle = 'rgba(220,255,240,.8)'; c.lineWidth = 2; c.stroke(top);
|
|
125
|
+
c.clip(top); const sx = 860 + ((t * 260) % 420);
|
|
126
|
+
c.fillStyle = 'rgba(255,255,255,.35)'; c.beginPath(); c.moveTo(sx, 630); c.lineTo(sx + 40, 630); c.lineTo(sx + 10, 672); c.lineTo(sx - 30, 672); c.fill();
|
|
127
|
+
c.restore();
|
|
128
|
+
}
|
|
129
|
+
// ---------- 角色(塑料人偶) ----------
|
|
130
|
+
const SK = '#f2c39c', HAIR = '#f6c624', RED = '#e3283c', BLUE = '#2c55d8';
|
|
131
|
+
function girl(c, G) {
|
|
132
|
+
const A = G.A;
|
|
133
|
+
plastic(c, G.farSleeve, '#b81f30', 1300, 560, 140, { spec: 0.4 });
|
|
134
|
+
plastic(c, G.farHand, SK, 1170, 608, 50, { spec: 0.7 });
|
|
135
|
+
// 腿:牛仔蓝塑料圆柱
|
|
136
|
+
const hip = G.hipSeat, knee = [1222, 722], ank = [1212, 870];
|
|
137
|
+
const th2 = RIG.taper([hip[0] + 14, hip[1] - 4], [knee[0] + 30, knee[1] - 8], 84, 70); cyl(c, th2, '#1e3c9c', hip, knee, 84, { spec: 0.3 });
|
|
138
|
+
const sh2 = RIG.taper([knee[0] + 30, knee[1] - 8], [ank[0] + 30, ank[1]], 62, 52); cyl(c, sh2, '#1e3c9c', knee, ank, 62, { spec: 0.3 });
|
|
139
|
+
const th = RIG.taper(hip, knee, 92, 78), sh = RIG.taper(knee, ank, 72, 58);
|
|
140
|
+
cyl(c, sh, BLUE, knee, ank, 72); cyl(c, th, BLUE, hip, knee, 92);
|
|
141
|
+
const kneeBall = new Path2D(); kneeBall.arc(knee[0], knee[1], 40, 0, 7); plastic(c, kneeBall, BLUE, knee[0] - 14, knee[1] - 16, 60, { spec: 0.6 });
|
|
142
|
+
const shoe = RIG.smooth([[1150, 868], [1238, 860], [1252, 902], [1124, 906], [1116, 890]]); plastic(c, shoe, '#5a2c1c', 1160, 872, 80, { spec: 0.8 });
|
|
143
|
+
// 身体
|
|
144
|
+
plastic(c, G.torso, RED, 1318, 478, 200, { spec: 0.75, specR: 0.1 });
|
|
145
|
+
plastic(c, G.neck, SK, 1296, 420, 40, { spec: 0 });
|
|
146
|
+
// 头发(后)、脸、刘海——塑料头发要有几条亮带
|
|
147
|
+
if (G.hairDown) plastic(c, G.hairDown, HAIR, 1380, 470, 140, { spec: 0.5 });
|
|
148
|
+
plastic(c, G.hairBack, HAIR, 1330, 320, 130, { spec: 0.8 });
|
|
149
|
+
plastic(c, G.face, SK, 1268, 340, 95, { spec: 0.55, specR: 0.12 });
|
|
150
|
+
c.fillStyle = 'rgba(240,120,120,.22)'; c.beginPath(); c.arc(G.cheek[0], G.cheek[1], 10, 0, 7); c.fill();
|
|
151
|
+
const ear = new Path2D(); ear.ellipse(G.ear[0], G.ear[1], 9, 13, 0.2, 0, 7); plastic(c, ear, SK, G.ear[0] - 3, G.ear[1] - 4, 18, { spec: 0 });
|
|
152
|
+
plastic(c, G.bangs, HAIR, 1282, 306, 80, { spec: 0.9, specR: 0.2 });
|
|
153
|
+
c.save(); c.lineCap = 'round'; G.hairLines.forEach((h, k) => { c.strokeStyle = 'rgba(255,255,230,.55)'; c.lineWidth = 5 - k; c.stroke(h); c.strokeStyle = 'rgba(180,120,0,.35)'; c.lineWidth = 2; c.translate(0, 8); c.stroke(h); c.translate(0, -8); }); c.restore();
|
|
154
|
+
// 眼(蓝色玻璃珠)、眉、唇
|
|
155
|
+
const ey = G.eye; c.fillStyle = '#fff'; c.beginPath(); c.ellipse(ey.x, ey.y, 6.5, 7, 0, 0, 7); c.fill();
|
|
156
|
+
if (G.blink) { c.strokeStyle = '#4a2a1a'; c.lineWidth = 2.5; c.stroke(G.lid); }
|
|
157
|
+
else { const ig = c.createRadialGradient(ey.x - 2, ey.y - 1, 1, ey.x - 1, ey.y + 1, 6); ig.addColorStop(0, '#6fa0ff'); ig.addColorStop(1, '#1a2c8a'); c.fillStyle = ig; c.beginPath(); c.arc(ey.x - 1.5, ey.y + 1, 5, 0, 7); c.fill(); c.fillStyle = '#fff'; c.beginPath(); c.arc(ey.x - 3, ey.y - 1.5, 1.6, 0, 7); c.fill(); c.strokeStyle = '#4a2a1a'; c.lineWidth = 2.2; c.stroke(G.lid); }
|
|
158
|
+
c.strokeStyle = '#b8862a'; c.lineWidth = 2.6; c.stroke(G.brow);
|
|
159
|
+
c.fillStyle = '#d0505a'; c.beginPath(); c.moveTo(...G.lips[0]); c.lineTo(...G.lips[1]); c.lineTo(...G.lips[2]); c.closePath(); c.fill();
|
|
160
|
+
// 近侧手臂(圆柱+球关节)、杯子、手
|
|
161
|
+
const S = A.shoulder, E = A.elbow, Hd = A.hand;
|
|
162
|
+
cyl(c, G.upperArm, RED, S, E, 54); cyl(c, G.foreArm, RED, E, Hd, 40);
|
|
163
|
+
const sb = new Path2D(); sb.arc(S[0], S[1], 30, 0, 7); plastic(c, sb, RED, S[0] - 10, S[1] - 12, 44, { spec: 0.8 });
|
|
164
|
+
// 杯子:白瓷,椭圆口+高光
|
|
165
|
+
const u = G.cup; c.save(); c.translate(u.x, u.y); c.rotate(u.tilt);
|
|
166
|
+
const body = new Path2D(); body.moveTo(-u.w / 2, 0); body.lineTo(-u.w * 0.42, u.h); body.quadraticCurveTo(0, u.h * 1.12, u.w * 0.42, u.h); body.lineTo(u.w / 2, 0); body.closePath();
|
|
167
|
+
c.strokeStyle = '#e8e8f0'; c.lineWidth = 7; c.beginPath(); c.arc(u.w * 0.55, u.h * 0.4, u.h * 0.26, -1.2, 1.4); c.stroke();
|
|
168
|
+
plastic(c, body, '#f4f2f8', -u.w * 0.2, u.h * 0.3, 40, { spec: 0.9, rim: false });
|
|
169
|
+
c.fillStyle = '#6a3a1a'; c.beginPath(); c.ellipse(0, 0, u.w / 2, u.h * 0.14, 0, 0, 7); c.fill(); c.strokeStyle = '#fff'; c.lineWidth = 2; c.stroke();
|
|
170
|
+
c.restore();
|
|
171
|
+
plastic(c, G.hand, SK, Hd[0] - 5, Hd[1] - 6, 26, { spec: 0.8 });
|
|
172
|
+
}
|
|
173
|
+
function cat(c, K, t) {
|
|
174
|
+
const O = '#ee8f2e', Wt = '#f6f2ee';
|
|
175
|
+
// 尾巴:粗管+高光线
|
|
176
|
+
c.save(); c.lineCap = 'round'; c.strokeStyle = '#b35f14'; c.lineWidth = K.tailW + 4; c.stroke(K.tail); c.strokeStyle = O; c.lineWidth = K.tailW; c.stroke(K.tail);
|
|
177
|
+
c.strokeStyle = 'rgba(255,240,200,.75)'; c.lineWidth = 4; c.translate(-2, -7); c.stroke(K.tail); c.restore();
|
|
178
|
+
const tip = K.tailPts[K.tailPts.length - 1]; const tp = new Path2D(); tp.arc(tip[0], tip[1], K.tailW / 2 + 1, 0, 7); plastic(c, tp, Wt, tip[0] - 4, tip[1] - 5, 20);
|
|
179
|
+
const body = RIG.smooth(K.bodyPts); // RIG 的猫身是折线,塑料质感要先 Catmull-Rom 平滑
|
|
180
|
+
plastic(c, body, O, 500, 735, 230, { spec: 0.8, specR: 0.09 });
|
|
181
|
+
c.save(); c.clip(body); plastic(c, K.white, Wt, 585, 720, 120, { spec: 0.5, rim: false }); c.restore();
|
|
182
|
+
c.save(); c.clip(body); const wg = c.createLinearGradient(560, 700, 650, 860); wg.addColorStop(0, 'rgba(0,0,0,0)'); wg.addColorStop(1, 'rgba(40,0,60,.3)'); c.fillStyle = wg; c.fillRect(540, 680, 140, 220); c.restore();
|
|
183
|
+
c.save(); c.clip(body); c.filter = 'blur(2px)'; c.strokeStyle = 'rgba(170,70,10,.5)'; c.lineWidth = 12; c.lineCap = 'round'; K.stripes.slice(3).forEach(s => { c.beginPath(); c.moveTo(...s[0]); c.lineTo(...s[1]); c.stroke(); }); c.restore();
|
|
184
|
+
K.legs.forEach((l, k) => { plastic(c, l, Wt, 578 + k * 44, 770, 110, { spec: 0.7, specR: 0.08, dark: 0.5 }); const pw = new Path2D(); pw.ellipse(585 + k * 50, 892, 25, 14, 0, 0, 7); plastic(c, pw, Wt, 578 + k * 50, 884, 34, { spec: 0.8, dark: 0.5 }); c.strokeStyle = 'rgba(120,90,110,.5)'; c.lineWidth = 2; [-8, 8].forEach(o => { c.beginPath(); c.moveTo(585 + k * 50 + o, 888); c.lineTo(585 + k * 50 + o, 903); c.stroke(); }); });
|
|
185
|
+
plastic(c, K.head, O, 580, 598, 100, { spec: 0.9, specR: 0.13 });
|
|
186
|
+
c.save(); c.clip(K.head); const mz = new Path2D(); mz.ellipse(K.nose[0] - 14, K.nose[1] + 16, 27, 19, 0, 0, 7); plastic(c, mz, Wt, K.nose[0] - 20, K.nose[1] + 8, 34, { spec: 0.4, rim: false, dark: 0.3 });
|
|
187
|
+
c.filter = 'blur(1.5px)'; c.strokeStyle = 'rgba(170,70,10,.5)'; c.lineWidth = 8; c.lineCap = 'round'; K.stripes.slice(0, 3).forEach(s => { c.beginPath(); c.moveTo(...s[0]); c.lineTo(...s[1]); c.stroke(); }); c.restore();
|
|
188
|
+
c.fillStyle = '#f2a0a8'; K.earInner.forEach(e => { c.beginPath(); e.forEach((p, i) => i ? c.lineTo(...p) : c.moveTo(...p)); c.fill(); });
|
|
189
|
+
c.fillStyle = '#e66a7a'; c.beginPath(); c.arc(K.nose[0], K.nose[1], 6, 0, 7); c.fill();
|
|
190
|
+
c.strokeStyle = 'rgba(255,255,255,.85)'; c.lineWidth = 1.6; K.whiskers.forEach(w => { c.beginPath(); c.moveTo(...w[0]); c.lineTo(...w[1]); c.stroke(); });
|
|
191
|
+
// 猫眼:发绿光(lighter 叠加、随时间脉动)
|
|
192
|
+
const pulse = 0.75 + 0.25 * Math.sin(t * 18);
|
|
193
|
+
K.eyes.forEach(e => {
|
|
194
|
+
c.fillStyle = '#0a3a10'; c.beginPath(); c.arc(e.x, e.y, 10, 0, 7); c.fill();
|
|
195
|
+
c.save(); c.globalCompositeOperation = 'lighter';
|
|
196
|
+
const gg = c.createRadialGradient(e.x, e.y, 0, e.x, e.y, 46 * pulse); gg.addColorStop(0, 'rgba(200,255,200,1)'); gg.addColorStop(0.25, 'rgba(80,255,120,.8)'); gg.addColorStop(1, 'rgba(40,255,90,0)');
|
|
197
|
+
c.fillStyle = gg; c.beginPath(); c.arc(e.x, e.y, 46 * pulse, 0, 7); c.fill(); c.restore();
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ---------- 道具:绿锥、铬球(逐像素环境映射)、紫环(自转) ----------
|
|
202
|
+
function cone(c) {
|
|
203
|
+
const p = new Path2D(); p.moveTo(1592, 612); p.lineTo(1660, 780); p.ellipse(1592, 780, 68, 14, 0, 0, Math.PI); p.closePath();
|
|
204
|
+
c.fillStyle = '#25835a'; c.fill(p);
|
|
205
|
+
c.save(); c.clip(p); const g = c.createLinearGradient(1524, 0, 1660, 0); g.addColorStop(0, 'rgba(0,30,20,.35)'); g.addColorStop(0.3, 'rgba(160,255,200,.55)'); g.addColorStop(0.4, 'rgba(255,255,255,.15)'); g.addColorStop(1, 'rgba(0,20,10,.55)');
|
|
206
|
+
c.fillStyle = g; c.fillRect(1520, 600, 150, 200); c.restore();
|
|
207
|
+
}
|
|
208
|
+
function chromeSphere(c, t, cx, cy, r) {
|
|
209
|
+
const sc = P.scratch('rt_sph'), g = sc.getContext('2d'), D = r * 2 + 2;
|
|
210
|
+
const im = g.createImageData(D, D), d = im.data, rot = t * 4.5;
|
|
211
|
+
for (let y = 0; y < D; y++) for (let x = 0; x < D; x++) {
|
|
212
|
+
const nx = (x - r) / r, ny = (y - r) / r, q = nx * nx + ny * ny; if (q > 1) continue;
|
|
213
|
+
const nz = Math.sqrt(1 - q), i = (y * D + x) * 4;
|
|
214
|
+
// 反射方向 R = 2(N·V)N - V, V=(0,0,1)
|
|
215
|
+
const rx = 2 * nz * nx, ry = 2 * nz * ny, rz = 2 * nz * nz - 1;
|
|
216
|
+
let col;
|
|
217
|
+
if (ry > 0.05) { // 往下看到棋盘
|
|
218
|
+
const u = rx / ry * 1.6 + rot, v = rz / ry * 1.6; const ck = (Math.floor(u * 2) + Math.floor(v * 2)) & 1; col = ck ? [40, 60, 70] : [225, 225, 235];
|
|
219
|
+
} else { const k = clamp(-ry * 1.4); col = [lerp(245, 160, k), lerp(160, 80, k), lerp(170, 200, k)]; if (Math.abs(rx - 0.4) < 0.08 && ry < -0.2 && ry > -0.7) col = [255, 255, 255]; }
|
|
220
|
+
const f = 0.35 + 0.65 * Math.pow(1 - nz, 0.3) * 0.5 + 0.3; // 边缘更亮(菲涅尔)
|
|
221
|
+
d[i] = col[0] * f + 20; d[i + 1] = col[1] * f + 20; d[i + 2] = col[2] * f + 25; d[i + 3] = 255;
|
|
222
|
+
}
|
|
223
|
+
g.clearRect(0, 0, D + 4, D + 4); g.putImageData(im, 0, 0);
|
|
224
|
+
c.drawImage(sc, 0, 0, D, D, cx - r - 1, cy - r - 1, D, D);
|
|
225
|
+
c.save(); c.globalCompositeOperation = 'lighter'; const hg = c.createRadialGradient(cx - r * 0.38, cy - r * 0.45, 0, cx - r * 0.38, cy - r * 0.45, r * 0.3); hg.addColorStop(0, 'rgba(255,255,255,1)'); hg.addColorStop(1, 'rgba(255,255,255,0)'); c.fillStyle = hg; c.beginPath(); c.arc(cx - r * 0.38, cy - r * 0.45, r * 0.3, 0, 7); c.fill(); c.restore();
|
|
226
|
+
}
|
|
227
|
+
function torus(c, t, cx, cy, R, rr) {
|
|
228
|
+
const th = t * 7, tilt = 0.35, out = [], N = 140;
|
|
229
|
+
for (let k = 0; k < N; k++) {
|
|
230
|
+
const ph = k / N * Math.PI * 2, x0 = R * Math.cos(ph), y0 = R * Math.sin(ph);
|
|
231
|
+
const X = x0 * Math.cos(th), Z = x0 * Math.sin(th);
|
|
232
|
+
const Y = y0 * Math.cos(tilt) - Z * Math.sin(tilt), Z2 = y0 * Math.sin(tilt) + Z * Math.cos(tilt);
|
|
233
|
+
out.push([cx + X, cy + Y, Z2]);
|
|
234
|
+
}
|
|
235
|
+
out.sort((a, b) => a[2] - b[2]);
|
|
236
|
+
// 先画一层暗色底让球之间连成管,再逐颗加高光
|
|
237
|
+
out.forEach(([x, y]) => { c.fillStyle = '#7a1aa0'; c.beginPath(); c.arc(x, y, rr, 0, 7); c.fill(); });
|
|
238
|
+
out.forEach(([x, y, z]) => {
|
|
239
|
+
const g = c.createRadialGradient(x - rr * 0.35, y - rr * 0.4, 1, x, y, rr); const l = 0.5 + 0.5 * z / R;
|
|
240
|
+
g.addColorStop(0, `rgba(255,${190 + l * 50},255,1)`); g.addColorStop(0.3, '#d850f6'); g.addColorStop(0.75, '#9a28c4'); g.addColorStop(1, 'rgba(110,20,150,0)');
|
|
241
|
+
c.fillStyle = g; c.beginPath(); c.arc(x, y, rr * 0.92, 0, 7); c.fill();
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function props(c, t, mirror) {
|
|
245
|
+
// mirror: 画反射时各自按接地线镜像
|
|
246
|
+
const M = (yC, fn) => { c.save(); if (mirror) { c.translate(0, 2 * yC); c.scale(1, -1); } fn(); c.restore(); };
|
|
247
|
+
M(780, () => cone(c));
|
|
248
|
+
M(846, () => torus(c, t, 1818, 772, 52, 22));
|
|
249
|
+
M(800, () => chromeSphere(c, t, 1712, 748, 52));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ---------- 镜头光晕 ----------
|
|
253
|
+
function flare(c, t) {
|
|
254
|
+
c.save(); c.globalCompositeOperation = 'lighter';
|
|
255
|
+
const pul = 1 + 0.08 * Math.sin(t * 23);
|
|
256
|
+
const glow = c.createRadialGradient(...SUN, 0, ...SUN, 170 * pul); glow.addColorStop(0, 'rgba(255,255,255,1)'); glow.addColorStop(0.15, 'rgba(255,240,250,.9)'); glow.addColorStop(0.4, 'rgba(255,170,220,.25)'); glow.addColorStop(1, 'rgba(255,150,220,0)');
|
|
257
|
+
c.fillStyle = glow; c.beginPath(); c.arc(...SUN, 170 * pul, 0, 7); c.fill();
|
|
258
|
+
// 星芒(缓慢旋转)
|
|
259
|
+
const rot = t * 1.6;
|
|
260
|
+
for (let k = 0; k < 12; k++) { const a = rot + k / 12 * Math.PI * 2, L = (k % 2 ? 70 : 120) * pul; const g = c.createLinearGradient(SUN[0], SUN[1], SUN[0] + Math.cos(a) * L, SUN[1] + Math.sin(a) * L); g.addColorStop(0, 'rgba(255,255,255,.8)'); g.addColorStop(1, 'rgba(255,255,255,0)'); c.strokeStyle = g; c.lineWidth = 2.5; c.beginPath(); c.moveTo(...SUN); c.lineTo(SUN[0] + Math.cos(a) * L, SUN[1] + Math.sin(a) * L); c.stroke(); }
|
|
261
|
+
// 水平长条光
|
|
262
|
+
const hs = c.createLinearGradient(220, 0, 1180, 0); hs.addColorStop(0, 'rgba(255,255,255,0)'); hs.addColorStop(0.5, `rgba(255,255,255,${0.75 * pul})`); hs.addColorStop(1, 'rgba(255,255,255,0)');
|
|
263
|
+
c.fillStyle = hs; c.fillRect(220, SUN[1] - 2, 960, 4);
|
|
264
|
+
c.strokeStyle = 'rgba(255,255,255,.18)'; c.lineWidth = 3; c.beginPath(); c.arc(...SUN, 150, 0, 7); c.stroke();
|
|
265
|
+
// 鬼影:沿 太阳→画面中心 的直线排布,随时间轻微滑动
|
|
266
|
+
const C0 = [960, 540], dx = C0[0] - SUN[0], dy = C0[1] - SUN[1], sl = Math.sin(t * 5) * 0.03;
|
|
267
|
+
[[0.62, 58, 'rgba(180,255,240,.16)', 0], [0.95, 17, 'rgba(160,255,255,.4)', 6], [1.25, 40, 'rgba(255,200,255,.12)', 6], [1.55, 34, 'rgba(200,255,230,.18)', 0], [0.8, 12, 'rgba(255,255,200,.3)', 6]].forEach(([k, r, col, sides]) => {
|
|
268
|
+
const x = SUN[0] + dx * (k + sl), y = SUN[1] + dy * (k + sl); c.fillStyle = col; c.beginPath();
|
|
269
|
+
if (sides) for (let i = 0; i < sides; i++) { const a = i / sides * Math.PI * 2 + 0.3; c.lineTo(x + Math.cos(a) * r, y + Math.sin(a) * r); } else c.arc(x, y, r, 0, 7);
|
|
270
|
+
c.closePath(); c.fill();
|
|
271
|
+
});
|
|
272
|
+
c.restore();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
draw(c, lt, t) {
|
|
277
|
+
const ch = P.choreo(lt, t);
|
|
278
|
+
c.drawImage(P.cached('rt_bg', W, H, background), 0, 0);
|
|
279
|
+
c.drawImage(P.cached('rt_floor', W, H, floor), 0, FLOOR_Y, W, H - FLOOR_Y, 0, FLOOR_Y, W, H - FLOOR_Y);
|
|
280
|
+
const K = RIG.cat({ tail: ch.tail, blink: 0, breathe: ch.breathe });
|
|
281
|
+
const G = RIG.girl({ cup: ch.cup, sip: ch.sip, hair: 'long', breathe: ch.breathe }); G.blink = ch.blink;
|
|
282
|
+
// 物体层
|
|
283
|
+
const L = P.scratch('rt_obj'), lg = L.getContext('2d'); lg.clearRect(0, 0, W, H);
|
|
284
|
+
chair(lg); table(lg); glassTop(lg, t); girl(lg, G); cat(lg, K, t);
|
|
285
|
+
// 反射:物体层按接地线 y=905 镜像,往下渐隐
|
|
286
|
+
c.save(); c.beginPath(); c.rect(0, FLOOR_Y, W, H - FLOOR_Y); c.clip();
|
|
287
|
+
c.globalAlpha = 0.34; c.translate(0, 2 * 906); c.scale(1, -1); c.drawImage(L, 0, 0); c.restore();
|
|
288
|
+
const R2 = P.scratch('rt_ref2'), rg = R2.getContext('2d'); rg.clearRect(0, 0, W, H); props(rg, t, true); // 道具反射先画到独立层再整体半透明,避免小球叠加变实
|
|
289
|
+
c.save(); c.beginPath(); c.rect(0, FLOOR_Y, W, H - FLOOR_Y); c.clip(); c.globalAlpha = 0.34; c.drawImage(R2, 0, 0); c.restore();
|
|
290
|
+
const fg = c.createLinearGradient(0, 905, 0, H); fg.addColorStop(0, 'rgba(160,190,195,0)'); fg.addColorStop(1, 'rgba(160,190,195,.25)'); c.fillStyle = fg; c.fillRect(0, 905, W, H - 905);
|
|
291
|
+
// 接触阴影
|
|
292
|
+
c.fillStyle = 'rgba(10,30,35,.35)'; [[540, 906, 130, 10], [1010, 900, 70, 8], [1190, 905, 80, 8], [1400, 912, 110, 8], [1592, 782, 70, 8]].forEach(([x, y, rx, ry]) => { c.beginPath(); c.ellipse(x, y, rx, ry, 0, 0, 7); c.fill(); });
|
|
293
|
+
c.drawImage(L, 0, 0);
|
|
294
|
+
props(c, t, false);
|
|
295
|
+
// 热气:半透明白色管状
|
|
296
|
+
P.steam(c, t, G.cup.x, G.cup.y - 6, { h: 60, n: 2, color: 'rgba(255,255,255,.7)', width: 5, spread: 14, wobble: 8 });
|
|
297
|
+
flare(c, t);
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
})();
|