Skip to content

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

清明上河

可交互的宋代沿河街市画卷,包含行走、乘船、街市故事和「虹桥过船」。

项目缘起、参考与原创再创作说明见 从长卷到街市

画卷片段

夜景下的沿河街市与虹桥 夜景下灯火亮起的城门货市
夜景 · 沿河灯火 夜景 · 城门货市
白天的水磨与作坊 清明时雨中的沿河茶市与虹桥
水磨作坊 清明时雨

公开源码:qingming-riverside

在线体验:打开画卷

备用入口:Vercel

GitHub Pages 从 master 分支自动发布;推送代码后可在仓库 Actions 中查看发布状态。Vercel 为独立部署,更新时运行 vercel deploy --prod

无需安装或登录,支持电脑与手机浏览器。画面为原创生成插画,不是《清明上河图》原画扫描。

本地运行

在项目目录运行 python3 -m http.server 8794 --bind 127.0.0.1,然后访问 http://127.0.0.1:8794/。无需构建步骤,Three.js 已包含在 vendor 中。请通过 HTTP 服务打开,不要直接双击 HTML。

测试:安装 Node.js 后运行 node --test *.test.cjs

本版

  • 新增“招船”:无论主角在画卷何处,都可走向最近的码头,在岸边举手候船;船靠岸后自动登船,横渡后在对岸下船。不包含专注计时、时长选择或悬浮面板。
  • 渡船改为更慢的起步、巡航和减速,完整横渡约 48 秒。船夫持续做前探、压篙、回收的循环动作,篙尖入水时带起轻微水纹。东西两侧街区底图现在全部载入后才显示画卷,避免只有人物而建筑消失。
  • 恢复“清明时雨”环境事件:底部“时雨”可触发风起、疏雨、骤雨、雨歇与天青,地面和水面随雨势变湿,沿街摊棚增加遮雨效果;声音开启时加入雨声。
  • 时雨不改动原有人物素材、尺寸、位置和动作;疏雨开始后所有人物会按不同节奏逐渐撑开雨伞,到骤雨前全部完成。伞面从合拢到展开,伞柄跟随动画后的真实手部位置。主角继续保持 66 世界单位,岸上人物仍为 141 位。
  • 新增“虹桥过船”可玩事件。底部“过船”进入,船靠近后点击桥边“接绳”;也可再次点底部“过船”前往接应。主角沿街道走到桥边,船工放倒桅杆后货船才驶入桥洞。船随远近缩小,事件结束后留在桥后水道。
  • 按住“向左拉”向左拖动控制牵引,松手放绳。接绳后按住左箭头或 E 牵引,右箭头放缓;聚焦绳索控件后,回车切换持续牵引,空格按住牵引。Escape 离开,纤夫会接替。正常步行时方向键行为保持原样。
  • 合适的力度加快降桅与过桥,用力过猛会减速;旁观也能看到完整过程。牵引力度影响绳索松紧、画师与纤夫的重心。桥上居民回应船工,过桥行人暂候,船通过后从原位置继续走。
  • 货船使用现有船体和船工素材,加上可转动的桅杆、卷帆和缆绳;船工保持竖直站立,船体逐步进入桥洞并被桥体遮挡。修正过桥时船身过度变窄的透视。窄屏聚焦主角、绳索和船,保留人物大小。
  • 结束后得到可打开、保存为 JPEG 的画稿,区分“助船”和“观船”。画稿保存在本机浏览器;曾经帮忙会被船工记住,再次进入时回应。更换浏览器或清除网站数据后不会保留。
  • 声音开启时加入降桅落木、水声与牵绳声;保持默认静音。没有增加任务面板、积分或倒计时。
  • 六组街区事件按先后顺序发生:茶客招呼、店家送茶、客人举杯;菜市挑选与交货;陶作取坯、搬运、入架;布铺展开布料、折好交给顾客;两个孩童推圈、追逐、停下展示;货栈搬货、交接、入库。每组周期和起始时间不同,人物完成后回到原处。
  • 货物交接使用两个人的实际手部位置,同一件物品在交接时只绘制一次。搬运和送茶人物沿街前路面移动,脚底与家具遮挡沿用原规则;人物尺寸与衣色保持一致。
  • 渡船会自行靠东岸,岸上的搬货人沿现有码头下行、放货、返回。你登船时搬货人从当前位置退回;自动靠岸不会抢占已发起的饮茶或乘船操作。
  • 街坊错开交谈和点头,忙碌的人被点击后也会回应。迎面路人会停步让主角通过,随后继续原路,步态按实际位移推进。孩童靠近时麻雀飞起;树叶和店幌随同一阵风活动。
  • 所有事件共用动画时间,暂停后人物、物件和装卸一起停止。声音开启时增加附近的杯声与轻微货物落放声,默认仍关闭,没有增加画面说明文字。
  • 主角使用独立画师素材:朱衣、幞头、蓝绿裤装、绑腿与竹编画卷包。高度统一为 66 世界单位,与多数成年居民的 62–68 接近;上船后保持同一身高,与船工比例一致。画卷、茶杯和手部动作同步按身形调整,脚底仍按街道和桥面逐脚定位。停下后会展开画卷查看,走动时收起。
  • 船工换为斗笠、短衣、卷裤的撑篙人物。船工高度从约 32 调整为 53 船内单位,船身与船篷重新配比,脚底落在甲板上;篙跟随两只手的位置,船舷遮住鞋底下缘。
  • 新人物由 featured-characters.js 载入,使用已有的脚底校准和网格动画。原居民素材保留。新素材与最终提示词见 FEATURED-PROMPTS.md
  • 街区宽度从 2172 扩展到 6516 世界单位,保留中央茶市与虹桥,新增西侧水磨、陶作、织坊、菜市,以及东侧货市、城门、仓场。
  • 清除中央底图内的固定人物,重新加入 95 位有独立动作的食客、店主、摊贩和街坊。另有 40 位按各自路径行走、停留、换向的路人,加上原有行人、挑担人、推车人与主角,共 141 位岸上人物。船上另有船工。
  • 全部人物使用线描素材,原有几何小人已替换。主角与船工使用独立设计,其他路人与居民使用人物图集。主角手动速度 102、自动速度 62;路人速度 23–33.8,挑担和推车稍慢。
  • 依据图片透明轮廓校准鞋底,支撑脚在落地期间保持原地,另一只脚抬起迈步;桥面根据每只脚的位置分别取高度。头、手和身体通过连续网格变形,脚下保持固定。
  • 食客举杯或用餐,店家递物、倒茶,桥上人物交谈和张望;陶作、织坊、水磨、园边与货场分别使用揉制、送梭、扳动、翻土和整理包裹的动作。周期与起始相位错开,点击店铺人物会触发回应。
  • 食客和店主先绘制,桌面与楼上栏杆随后绘制,街上路人与主角最后绘制,避免桌面穿过身体。桥栏与水磨前景保留各自的遮挡规则。加入街犬、水车转动、水流和织机梭子。
  • 亭前行走路线沿石台外侧的路面描绘,主角、路人和推车人共用;狭窄处取消路人的纵向错位。前景木桩按轮廓遮挡脚部,码头上下船路线衔接新的路面高度。
  • 男女服饰使用八组配色,外衣与裙摆、袍摆分别着色。脸、手、头发、鞋和手持物保留原色;每位人物的配色固定,缩放、移动和暂停时不变。服装纹理提前缓存,不在每帧重新染色。
  • 底部四个小圆点可直接浏览不同街区,没有增加说明文字。人物图层只绘制当前视野,并按屏幕像素密度渲染。

操作

  • 左右方向键、底部左右箭头:短按走一小段,按住持续行走,松开减速停下;连续输入保留速度,换向先减速。镜头跟随,到达所选位置前减速,过桥时根据坡度调整步速。
  • 点击街道:行人走到该处;中间播放键:自动行走。原街区边界不再限制行走。
  • 点击店铺人物:对方回应;底部四个圆点:浏览水磨、茶市、虹桥、城门。
  • 拖动、滚轮:浏览画卷;左下角图标:回到行人或船只。
  • 双击、放大图标、双指缩放:查看局部;放大后支持横向和纵向拖动。Ctrl + 滚轮也可缩放。
  • 点击茶铺或桥头:行人到达后饮茶或喂鸟;附近也可按 E。
  • 点击两岸码头:行人走到岸边唤船。船靠岸后点击船上图标或码头上船,经过登船、行船、下船三个阶段到达另一岸;可再次上船返回。
  • 乘船中间键切换暂停与继续,左右行走暂时关闭;仍可浏览画卷。Escape 暂停乘船,在岸上则停止行走。
  • 点击水面:产生波纹。
  • 声音图标:开启或关闭背景音乐、雨声、划桨声和饮茶杯声,默认关闭。切换夜景时,背景音乐会平滑切换为 夜晚背景音乐.mp3,回到白天后恢复原音乐。点击“时雨”后,背景音乐随雨势缓慢淡出,原有雨声保留;雨歇后音乐缓慢恢复。动画暂停或页面进入后台后静音。
  • 暂停图标或空格:暂停人物、船与蒸汽;点击产生的波纹仍会消退。
  • 底部细线:定位;Home / End:画卷起点 / 终点。
  • 支持键盘和减少动态效果设置。画面只显示必要图标,状态说明仅提供给屏幕阅读器。

实现

Canvas 2D 与 Three.js 混合渲染。街市底图、透明船素材与独立人物层保持 Canvas 2D;water-three.js 通过本地 Three.js r186 的 WebGLRendererShaderMaterial 生成透明 GPU 水层,合成回画卷世界坐标。河面使用连续法线扰动、反光与流向;水磨落水使用纵向加速、水幕厚薄和冲击泡沫。WebGL 不可用时自动回退到 Canvas 水效。Three.js 位于 vendor/,许可证一并保留。桥面路线和前栏遮罩分别依据底图描绘,让人物脚下位置与栏杆遮挡一致。人物在船上使用独立坐标和绘制层,避免水面人物受桥栏遮罩影响。

world.js 管理行人往返与渡船状态;乘船包含连续上下台阶、缓慢离岸、横渡、减速靠岸和返程。scene.js 负责画面、角色动作、镜头、命中区域与输入。sound.js 通过 Web Audio 混合本地 pubuniaosheng.mp3、合成雨声与交互音效;首次点击声音开关才创建音频上下文。

street-life.js 管理街区事件的阶段、人物路线、物件归属、行人让路与靠岸装卸。street-details.js 绘制茶壶、陶坯、布料、包裹、木圈、麻雀与落叶。全部复用现有人物,没有新增素材请求;被移动人物的点击范围随实际位置更新。

bridge-event.js 管理过船阶段、牵引输入、桅杆进度、船的位置与参与结果;bridge-art.js 绘制船体透视、桅杆、绳索和桥洞遮挡。故事时间与全场暂停、页面失焦共用。主角无需瞬移,原有 5 位行人也接入独立时钟,以便等候后继续原路。

wardrobe.js 保存服装配色、衣物轮廓与肤色保护区域。inhabitants.js 在保留线稿明暗的基础上生成独立衣色,人物底图文件不变。

movement.js 管理步速、支撑脚与摆动脚、鞋底透明边距校准、局部动作和网格变形。动作按实际行走距离推进;先在复用的透明画布上完成变形,再一次合成人物,避免网格接缝加深。只绘制视野附近的人物。

方向键和屏幕箭头共用输入状态,速度按经过时间连续变化;松手后保留双脚位置。店内人物轻微动作按错开的 12 Hz 时点缓存,每人只保留一帧;行走人物和主角继续逐帧定位脚底。网格绘制限制到当前格子的图片范围,近似仿射的格子合并;船图预缩放,视野外船只不绘制。控制层和诊断属性以 10 Hz 更新,画布持续刷新。

人物中间画布使用 willReadFrequently,减少多次合成的回读开销。移动修正后,880×919 视口连续行走采样约 55 FPS;设备负载和视野内人数会影响数值。

建筑底图保持静止,人物全部通过独立图层更新。水磨前方建筑遮挡后巷行人,过桥仍使用原有桥面路径。底图是原创生成插画,不是《清明上河图》原画扫描。放大查看使用现有位图分辨率。

素材使用内置 imagegen 生成。新增街区与人物素材的最终提示词见 ASSETS.md,初版街景和船的提示词见 PROMPT.mdBOAT-PROMPT.md。原有素材保留。人物图集保留白底,由 people-masks.js 的矢量轮廓在 Canvas 中裁剪后分层绘制。

验证

运行 node --test *.test.cjs:五十四项通过。覆盖渡船、人口、遮挡、路线、配色、人物比例与脚底,以及河流、落水、桨花、船体尾流和本地 Three.js 依赖。还包含短按跨帧、长按、连续与反向输入、多输入释放、取消操作、暂停、边界、停止时脚位连续和绘制缓存。

第九版新增六项:旁观完整流程、不同刷新率下协助的结果、过度牵引、放手与暂停后继续、重复开始及输入边界、桥上交通恢复。浏览器在 1280×720、390×844 视口验证入口、接绳、拖动、键盘持续牵引、暂停和画稿;实际参与累计产生“助船”记录,刷新后仍可打开。触屏交互以窄屏指针模拟验证,未在实体手机上测试。

第八版浏览器检查:1280×720 视口、1.65 倍放大查看送茶、孩童、货栈和布铺;货物跟随手部,站立和搬运人物保持原比例。逻辑测试覆盖完整事件周期,视觉检查采用不同阶段的画面抽查。

第七版浏览器检查:880×919 视口及 1.65 倍放大,主角展开画卷、步行、到达桥中央 x=1501.7 / y=402.4、码头上船。船工双手与篙关联,脚在甲板上,船舷遮住脚底下缘。主角沿原街道和桥面路线行走。

第六版浏览器检查:新主角自动过桥至东街 x=2150.2,饮茶与暂停,陶作及织坊。1280×720 视口下查看约 37 位居民和路人时,实测人物及场景每帧绘制约 7–8 毫秒;性能数值随设备与视野变化。

浏览器确认:两侧街区及接缝;主角从 x=585 过桥走到新增东街 x=2222.1;人群暂停后相位保持不变;东岸登船、行船、西岸下船;手机上点击居民回应和放大。检查了 880×919 与 390×844 视口,控制台无错误。双指缩放已实现,未在实体触屏设备上验证。

About

可交互的宋代沿河街市画卷:行走、乘船、时雨与虹桥过船。Canvas 2D + Three.js。

Resources

Stars

121 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages