[{"data":1,"prerenderedAt":2106},["ShallowReactive",2],{"blog-taxonomies":3,"blog-stats":507,"post-2025\u002F2025-12-05-现代协同-2d-画布编辑器pixijs-v8":1083},[4,11,16,21,25,29,36,39,44,47,52,58,63,66,71,76,80,84,87,93,96,101,105,110,113,117,122,127,132,136,141,143,146,151,155,157,162,165,169,173,176,179,183,186,190,193,197,200,205,208,211,214,219,222,228,234,237,239,245,249,253,256,260,266,271,276,281,283,287,290,293,298,301,304,306,308,311,314,316,318,321,327,332,337,342,347,352,354,356,358,361,365,367,369,371,374,376,378,381,386,390,393,396,400,404,407,411,413,415,417,421,423,425,428,431,433,435,437,439,441,443,446,448,450,454,456,459,461,463,465,467,469,471,473,477,483,486,488,491,493,495,497,499,501,503,505],{"category":5,"tags":6},"笔记",[7,8,9,10],"QQ","插件","LiteLoader","美化",{"category":12,"tags":13},"其他",[14,15,10],"博客","IP签名",{"category":17,"tags":18},"杂谈",[19,20],"互联网","观点",{"category":5,"tags":22},[14,23,24],"GitHub","数据可视化",{"category":5,"tags":26},[14,27,28],"访问统计","不蒜子",{"category":30,"tags":31},"工具",[32,33,34,35],"Python","爬虫","选课脚本","广州大学",{"category":5,"tags":37},[38,5],"数学分析",{"category":40,"tags":41},"算法",[42,40,43],"数据结构","线性表",{"category":40,"tags":45},[42,46],"复习",{"category":5,"tags":48},[49,50,51],"高等代数","线性代数","知识点",{"category":5,"tags":53},[14,54,55,56,57],"Typora","PicGo","图床","Markdown",{"category":30,"tags":59},[60,61,62],"Jupyter","工具配置","中文",{"category":30,"tags":64},[65,61,10],"VSCode",{"category":30,"tags":67},[68,69,70,35],"路由器","OpenWrt","校园网",{"category":12,"tags":72},[73,74,75],"网络协议","Wireshark","DEVP2P",{"category":5,"tags":77},[73,74,78,79],"Lua","解码器",{"category":5,"tags":81},[82,5,83],"常微分方程","数学",{"category":5,"tags":85},[86,5,83],"概率论",{"category":30,"tags":88},[89,90,91,92],"Docker","WSL","Windows","磁盘清理",{"category":30,"tags":94},[32,33,95,35],"课程表",{"category":5,"tags":97},[14,98,99,100],"Hexo","Gitalk","评论系统",{"category":5,"tags":102},[14,103,98,104],"Obsidian","写作工具",{"category":12,"tags":106},[107,108,109],"课题研究","泊松分布","参数估计",{"category":12,"tags":111},[107,108,109,112],"组会",{"category":12,"tags":114},[109,115,108,116],"IM模型","统计学",{"category":17,"tags":118},[119,120,121],"软考","网络规划","信息系统项目管理",{"category":30,"tags":123},[124,125,126],"Arch Linux","AppImage","Linux",{"category":5,"tags":128},[129,130,131],"编程语言","计算机科学","内存管理",{"category":5,"tags":133},[134,135],"Canvas","前端",{"category":5,"tags":137},[14,138,139,140],"GitHub Actions","Vite","部署",{"category":5,"tags":142},[135],{"category":5,"tags":144},[135,145],"系统设计",{"category":5,"tags":147},[135,148,149,150],"安全","XSS","CSRF",{"category":152,"tags":153},"项目",[134,154],"PixiJS",{"category":152,"tags":156},null,{"category":40,"tags":158},[42,159,160,161],"栈","队列","JavaScript",{"category":40,"tags":163},[42,164,161],"哈希表",{"category":5,"tags":166},[167,161,168],"ES6","Set",{"category":40,"tags":170},[40,171,172],"动态规划","背包问题",{"category":40,"tags":174},[40,175],"滑动窗口",{"category":40,"tags":177},[42,178,161],"链表",{"category":40,"tags":180},[40,181,161,182],"ACM","面试",{"category":40,"tags":184},[40,161,185],"数据类型转换",{"category":40,"tags":187},[42,188,178,189],"顺序表","TypeScript",{"category":5,"tags":191},[135,154,134,192],"渲染",{"category":5,"tags":194},[135,195,134,196],"富文本编辑","wangEditor",{"category":40,"tags":198},[199,40,178],"力扣",{"category":5,"tags":201},[202,203,204,91],"DNS","加密","网络安全",{"category":5,"tags":206},[135,207],"Axios",{"category":5,"tags":209},[135,207,189,210],"接口封装",{"category":5,"tags":212},[135,213,145],"JWT",{"category":152,"tags":215},[134,216,217,154,218],"画布","React","项目开发",{"category":17,"tags":220},[221],"日志",{"category":5,"tags":223},[224,225,226,227],"Neo4j","图数据库","中心度分析","PageRank",{"category":12,"tags":229},[230,231,232,233],"论文","机器学习","随机森林","保险欺诈",{"category":5,"tags":235},[236],"人工智能",{"category":5,"tags":238},[231,40,32],{"category":12,"tags":240},[241,242,243,244],"共识算法","最长链","区块链","算法设计",{"category":5,"tags":246},[161,247,248,135],"闭包","作用域",{"category":5,"tags":250},[14,138,251,252],"RSS","自动化",{"category":30,"tags":254},[89,90,91,255],"安装",{"category":30,"tags":257},[258,91,259],"MSYS2","开发环境",{"category":5,"tags":261},[262,263,264,265],"团队协作","Git","Commit规范","代码审查",{"category":30,"tags":267},[268,269,270],"oh-my-posh","终端美化","CLI",{"category":5,"tags":272},[273,274,275],"上下文工程","Agent","RAG",{"category":5,"tags":277},[278,279,280],"前端工程化","技术选型","工程基建",{"category":5,"tags":282},[275],{"category":5,"tags":284},[285,286],"SDD","规格驱动开发",{"category":5,"tags":288},[289],"neovim",{"category":5,"tags":291},[292],"技术写作",{"category":5,"tags":294},[295,32,296,89,297],"FastAPI","后端","工程实践",{"category":152,"tags":299},[274,300],"Harness Engineering",{"category":5,"tags":302},[303],"RFC",{"category":152,"tags":305},[274,300,275],{"category":152,"tags":307},[274],{"category":40,"tags":309},[199,40,161,310],"两数之和",{"category":40,"tags":312},[199,40,161,313],"双指针",{"category":40,"tags":315},[199,40,161,178],{"category":40,"tags":317},[199,40,161,175],{"category":40,"tags":319},[199,40,161,320],"回溯",{"category":5,"tags":322},[323,324,325,326],"分布式处理与计算","Spark","Scala","RDD",{"category":5,"tags":328},[323,329,330,331],"线性回归","逻辑回归","监督学习",{"category":5,"tags":333},[323,334,335,336],"数值优化","牛顿法","收敛性",{"category":5,"tags":338},[323,339,340,341],"PCA","数据降维","正则化",{"category":5,"tags":343},[323,344,345,346],"聚类","层次聚类","K-Means",{"category":5,"tags":348},[323,349,350,351],"随机模拟","统计推断","EM算法",{"category":5,"tags":353},[24],{"category":5,"tags":355},[24],{"category":5,"tags":357},[24],{"category":40,"tags":359},[42,360],"图论",{"category":40,"tags":362},[42,363,364],"树","二叉树",{"category":40,"tags":366},[42,160],{"category":40,"tags":368},[42],{"category":40,"tags":370},[42,159],{"category":40,"tags":372},[42,40,373],"复杂度分析",{"category":40,"tags":375},[42,43,178],{"category":40,"tags":377},[42,43,188],{"category":40,"tags":379},[42,380],"基础概念",{"category":17,"tags":382},[383,384,385],"随记","照片","高中",{"category":17,"tags":387},[383,388,389],"团建","战地",{"category":17,"tags":391},[383,392],"生活",{"category":17,"tags":394},[383,395],"文学",{"category":17,"tags":397},[383,398,399],"SCP","模因",{"category":17,"tags":401},[383,402,403],"画集","艺术",{"category":17,"tags":405},[14,406,383],"写作",{"category":17,"tags":408},[383,409,410],"音乐","摇滚",{"category":17,"tags":412},[383,392],{"category":17,"tags":414},[383,409],{"category":17,"tags":416},[383,35,392],{"category":17,"tags":418},[383,419,420],"同人","手书",{"category":17,"tags":422},[383,392],{"category":17,"tags":424},[383,392],{"category":17,"tags":426},[383,427],"植物",{"category":17,"tags":429},[383,430],"读书",{"category":17,"tags":432},[383,392],{"category":17,"tags":434},[383,392],{"category":17,"tags":436},[383,392],{"category":17,"tags":438},[383,392],{"category":17,"tags":440},[383,392],{"category":17,"tags":442},[383,392],{"category":17,"tags":444},[14,445,383],"一周年",{"category":17,"tags":447},[383,392],{"category":17,"tags":449},[383,392],{"category":17,"tags":451},[35,452,453],"开源组织","SITE-193",{"category":17,"tags":455},[383,392],{"category":17,"tags":457},[383,458],"年末",{"category":17,"tags":460},[383,392],{"category":17,"tags":462},[383,392],{"category":17,"tags":464},[14,17],{"category":17,"tags":466},[383,392],{"category":17,"tags":468},[383,392],{"category":17,"tags":470},[383,392],{"category":17,"tags":472},[383,392],{"category":17,"tags":474},[383,475,476],"游戏","Control",{"category":30,"tags":478},[479,480,481,482],"Quadim","图像处理","四叉树","Rust",{"category":17,"tags":484},[14,485],"上线纪念",{"category":17,"tags":487},[383,395],{"category":30,"tags":489},[203,490],"测试",{"category":17,"tags":492},[383],{"category":17,"tags":494},[383,392],{"category":17,"tags":496},[383],{"category":5,"tags":498},[40],{"category":5,"tags":500},[40],{"category":5,"tags":502},[40],{"category":5,"tags":504},[40],{"category":5,"tags":506},[40],[508,512,516,520,524,528,532,536,540,544,548,552,556,560,564,568,572,576,579,583,587,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646,650,654,658,662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726,730,734,738,742,746,750,754,758,762,766,770,774,778,782,786,790,794,798,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889,893,897,901,904,907,911,915,919,923,927,930,934,938,942,946,950,954,957,961,965,969,973,977,981,984,988,992,996,1000,1004,1007,1011,1015,1019,1023,1027,1031,1035,1039,1043,1047,1051,1055,1059,1063,1067,1071,1075,1079],{"path":509,"words":510,"published":511,"date":156},"\u002Fposts\u002F2024\u002F2024-06-25-liteloaderqqnt",1296,"2024-06-25 11:03:08",{"path":513,"words":514,"published":515,"date":156},"\u002Fposts\u002F2024\u002F2024-06-26-ip签名",0,"2024-06-26 22:53:53",{"path":517,"words":518,"published":519,"date":156},"\u002Fposts\u002F2024\u002F2024-06-29-何加盐中文互联网正在加速崩塌",4853,"2024-06-29 00:47:13",{"path":521,"words":522,"published":523,"date":156},"\u002Fposts\u002F2024\u002F2024-07-12-github-chart",270,"2024-07-12 20:02:50",{"path":525,"words":526,"published":527,"date":156},"\u002Fposts\u002F2024\u002F2024-07-14-访客数统计",192,"2024-07-24 01:34:28",{"path":529,"words":530,"published":531,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-广大选课脚本",110,"2024-07-26 01:34:28",{"path":533,"words":534,"published":535,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数学分析笔记其二",14,"2024-07-26 23:54:02",{"path":537,"words":538,"published":539,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习其二",12856,"2024-07-26 02:48:08",{"path":541,"words":542,"published":543,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-数据结构复习相关",32856,"2024-07-26 02:24:14",{"path":545,"words":546,"published":547,"date":156},"\u002Fposts\u002F2024\u002F2024-07-26-线性代数与空间解析几何知识点全汇总",6110,"2024-07-26 03:27:55",{"path":549,"words":550,"published":551,"date":156},"\u002Fposts\u002F2024\u002F2024-07-31-typora-picgo-兰空图床打造markdown写作环境",311,"2024-07-31 12:56:23",{"path":553,"words":554,"published":555,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-jupyter配置中文",441,"2024-09-02 23:49:05",{"path":557,"words":558,"published":559,"date":156},"\u002Fposts\u002F2024\u002F2024-09-02-自定义vscode背景图片",100,"2024-09-02 23:39:00",{"path":561,"words":562,"published":563,"date":156},"\u002Fposts\u002F2024\u002F2024-09-03-制作gzhu校园网路由器",1423,"2024-09-03 23:43:18",{"path":565,"words":566,"published":567,"date":156},"\u002Fposts\u002F2024\u002F2024-09-26-09-25-2024",136,"2024-09-26 00:49:26",{"path":569,"words":570,"published":571,"date":156},"\u002Fposts\u002F2024\u002F2024-11-04-创建一个网络包解码器分析devp2p协议",1943,"2024-11-04 16:45:19",{"path":573,"words":574,"published":575,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记常微分",16,"2024-12-09 22:51:00",{"path":577,"words":574,"published":578,"date":156},"\u002Fposts\u002F2024\u002F2025-03-09-2024一些笔记概率论","2025-03-09 22:51:00",{"path":580,"words":581,"published":582,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-windows下释放docker占用的wsl空间",164,"2025-03-01 13:54:15",{"path":584,"words":585,"published":586,"date":156},"\u002Fposts\u002F2025\u002F2025-03-01-爬虫实战-爬取广州大学课程表",774,"2025-03-01 14:55:48",{"path":588,"words":530,"published":589,"date":156},"\u002Fposts\u002F2025\u002F2025-04-03-hexo集成gitalk的问题","2025-04-03 14:26:34",{"path":591,"words":592,"published":593,"date":156},"\u002Fposts\u002F2025\u002F2025-09-22-记一次配置obsidian配合hexo写博客",92,"2025-09-22 16:47:52",{"path":595,"words":596,"published":597,"date":156},"\u002Fposts\u002F2025\u002F2025-10-24-10-20课题",204,"2025-10-24 08:15:01",{"path":599,"words":600,"published":601,"date":156},"\u002Fposts\u002F2025\u002F2025-11-02-组会朝花夕拾",501,"2025-11-02 18:56:59",{"path":603,"words":604,"published":605,"date":156},"\u002Fposts\u002F2025\u002F2025-11-05-基于随机加权推断模型im的参数估计算法",481,"2025-11-05 20:51:41",{"path":607,"words":608,"published":609,"date":156},"\u002Fposts\u002F2025\u002F2025-11-09-关于软考高项网规",884,"2025-11-09 19:54:52",{"path":611,"words":612,"published":613,"date":156},"\u002Fposts\u002F2025\u002F2025-11-17-arch-linux运行appimage相关",365,"2025-11-17 09:59:59",{"path":615,"words":616,"published":617,"date":156},"\u002Fposts\u002F2025\u002F2025-11-19-相关概念",2058,"2025-11-19 11:06:20",{"path":619,"words":620,"published":621,"date":156},"\u002Fposts\u002F2025\u002F2025-11-21-web可视化实践canvas",6393,"2025-11-21 14:50:48",{"path":623,"words":624,"published":625,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-使用-github-actions-自动部署基于vite的项目到-github-pages",272,"2025-11-23 01:59:24",{"path":627,"words":628,"published":629,"date":156},"\u002Fposts\u002F2025\u002F2025-11-22-关于前端包管理器npmpnpmyarn和bun",4890,"2025-11-22 21:21:15",{"path":631,"words":632,"published":633,"date":156},"\u002Fposts\u002F2025\u002F2025-11-23-undo-redo-机制具体实现",7839,"2025-11-23 19:15:00",{"path":635,"words":636,"published":637,"date":156},"\u002Fposts\u002F2025\u002F2025-11-27-前端安全-关于xss与crsf",1866,"2025-11-28 02:05:25",{"path":639,"words":640,"published":641,"date":156},"\u002Fposts\u002F2025\u002F2025-12-05-现代协同-2d-画布编辑器pixijs-v8",4285,"2025-12-05 02:00:16",{"path":643,"words":644,"published":645,"date":156},"\u002Fposts\u002F2025\u002F2025-12-07-杂谈-课题组系统设计",3710,"2025-12-07 21:09:33",{"path":647,"words":648,"published":649,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-javascript中的数组方法与栈stack和队列queue的实现",474,"2025-11-29 16:58:15",{"path":651,"words":652,"published":653,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript-实现哈希表",189,"2025-11-27 11:31:39",{"path":655,"words":656,"published":657,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于javascript的set方法",332,"2025-12-25 15:26:18",{"path":659,"words":660,"published":661,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于动态规划(背包问题为例)",1238,"2025-11-17 18:24:04",{"path":663,"words":664,"published":665,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于滑动窗口",712,"2025-11-20 15:04:40",{"path":667,"words":668,"published":669,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-关于链表(javascript)",500,"2025-11-25 13:00:48",{"path":671,"words":672,"published":673,"date":156},"\u002Fposts\u002F2025\u002F2025-12-25-面试算法acm模式构建构建输入输出模板",2051,"2025-12-25 23:09:45",{"path":675,"words":676,"published":677,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascript-数字数组字符串的处理",483,"2025-12-26 11:20:25",{"path":679,"words":680,"published":681,"date":156},"\u002Fposts\u002F2025\u002F2025-12-26-javascripttypescript-的顺序表链表实现",446,"2025-12-26 12:16:12",{"path":683,"words":684,"published":685,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-1-实现基础yuan素渲染和状态控制",2136,"2025-12-28 01:23:08",{"path":687,"words":688,"published":689,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-前端画布设计vol-2-实现富文本编辑",1838,"2025-12-28 02:58:47",{"path":691,"words":692,"published":693,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-算法刷题-关于链表操作",2135,"2025-12-27 16:12:42",{"path":695,"words":696,"published":697,"date":156},"\u002Fposts\u002F2025\u002F2025-12-27-配置dnscrypt-proxy实现加密dns服务windows",1899,"2025-11-15 01:06:37",{"path":699,"words":700,"published":701,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-关于网络请求xhrajaxfetchaxios",7788,"2025-10-28 15:48:46",{"path":703,"words":704,"published":705,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-接口封装与请求规范axios为例",2373,"2025-12-29 01:01:18",{"path":707,"words":708,"published":709,"date":156},"\u002Fposts\u002F2025\u002F2025-12-28-前端-身份验证管理-基于-jwt-token-的实现",2709,"2025-11-23 22:04:41",{"path":711,"words":712,"published":713,"date":156},"\u002Fposts\u002F2025\u002F2025-12-29-记canvas画布项目开发",6254,"2025-12-29 04:52:15",{"path":715,"words":716,"published":717,"date":156},"\u002Fposts\u002F2025\u002Fabout-site",116,"2025-03-31 16:44:24",{"path":719,"words":720,"published":721,"date":156},"\u002Fposts\u002F2025\u002F使用neo4j图数据科学库gds进行中心度分析",143,"2025-04-02 23:37:24",{"path":723,"words":724,"published":725,"date":156},"\u002Fposts\u002F2026\u002F2026-01-03-论文实训草稿",10445,"2026-01-03 14:10:49",{"path":727,"words":728,"published":729,"date":156},"\u002Fposts\u002F2026\u002F2026-01-06-人工智能导论",11461,"2026-01-07 03:25:49",{"path":731,"words":732,"published":733,"date":156},"\u002Fposts\u002F2026\u002F2026-01-07-机器学习相关算法",82,"2026-01-08 02:28:13",{"path":735,"words":736,"published":737,"date":156},"\u002Fposts\u002F2026\u002F2026-01-16-关于低复杂度最长链共识算法设计",4466,"2026-01-16 10:33:23",{"path":739,"words":740,"published":741,"date":156},"\u002Fposts\u002F2026\u002F2026-01-19-杂记2026-01-19",5754,"2026-01-20 01:03:26",{"path":743,"words":744,"published":745,"date":156},"\u002Fposts\u002F2026\u002F2026-01-22-github-action-自动同步博客到-github-主页",1069,"2026-01-22 16:31:47",{"path":747,"words":748,"published":749,"date":156},"\u002Fposts\u002F2026\u002F2026-03-01-windows-wsl安装docker",257,"2026-03-01 20:55:31",{"path":751,"words":752,"published":753,"date":156},"\u002Fposts\u002F2026\u002F2026-03-14-关于-msys2",701,"2026-03-15 03:05:04",{"path":755,"words":756,"published":757,"date":156},"\u002Fposts\u002F2026\u002F2026-03-28-团队项目协作规范随记",2419,"2026-03-29 05:33:50",{"path":759,"words":760,"published":761,"date":156},"\u002Fposts\u002F2026\u002F2026-03-29-oh-my-posh配置分享",104,"2026-03-29 16:34:43",{"path":763,"words":764,"published":765,"date":156},"\u002Fposts\u002F2026\u002F2026-06-13-从上下文工程到-agent-harness-engineering",8840,"2026-06-13 21:06:20",{"path":767,"words":768,"published":769,"date":156},"\u002Fposts\u002F2026\u002F2026-07-13-简谈前端基建质量标准与ai友好建设",3814,"2026-07-13 21:06:20",{"path":771,"words":772,"published":773,"date":156},"\u002Fposts\u002F2026\u002F2026-07-15-agentic-rag-系统实践",13357,"2026-07-15 21:06:20",{"path":775,"words":776,"published":777,"date":156},"\u002Fposts\u002F2026\u002F2026-07-18-简谈sdd规范驱动开发-copy",4476,"2026-07-18 11:06:20",{"path":779,"words":780,"published":781,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-个人neovim配置分享",366,"2026-07-22 13:46:50",{"path":783,"words":784,"published":785,"date":156},"\u002Fposts\u002F2026\u002F2026-07-20-关于技术写作-设计文档",6763,"2026-07-20 13:46:50",{"path":787,"words":788,"published":789,"date":156},"\u002Fposts\u002F2026\u002F2026-07-29-fastapi-工程实践随记",3417,"2026-07-29 04:58:34",{"path":791,"words":792,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-06-19-rfc-liskin_code_agent",3563,"2026-06-19 15:18:20",{"path":795,"words":796,"published":797,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-07-25-rfc-glushkov_ogas",13461,"2026-07-28 23:46:50",{"path":799,"words":800,"published":793,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002F2026-08-03-adr-ogas-arkhiv",2698,{"path":802,"words":803,"published":804,"date":156},"\u002Fposts\u002Frfc_agentic_project\u002Frag\u002F2026-08-12-arkhiv_rag-vol-1",4366,"2026-08-12 15:18:20",{"path":806,"words":807,"published":808,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-25-力扣百题速练javascripttypescriptvol-1",3108,"2025-12-25 13:57:08",{"path":810,"words":811,"published":812,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-26-力扣百题速练javascripttypescriptvol-2",3185,"2025-12-26 13:57:08",{"path":814,"words":815,"published":816,"date":156},"\u002Fposts\u002Fleetcode\u002F2025-12-28-力扣百题速练javascripttypescriptvol-3",2533,"2025-12-29 02:15:44",{"path":818,"words":819,"published":820,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-17-力扣百题速练javascripttypescriptvol-4",3024,"2026-01-17 22:53:01",{"path":822,"words":823,"published":824,"date":156},"\u002Fposts\u002Fleetcode\u002F2026-01-19-力扣百题速练javascripttypescriptvol-5",293,"2026-01-19 15:15:12",{"path":826,"words":827,"published":828,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算spark系统与scala语言",4320,"2026-07-06 14:10:49",{"path":830,"words":831,"published":832,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算分类与回归分析",2081,"2026-07-07 12:40:29",{"path":834,"words":835,"published":836,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数值优化方法",2182,"2026-07-07 13:50:29",{"path":838,"words":839,"published":840,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算数据降维",1583,"2026-07-07 21:50:29",{"path":842,"words":843,"published":844,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算聚类分析",1882,"2026-07-07 16:50:29",{"path":846,"words":847,"published":848,"date":156},"\u002Fposts\u002F分布式处理与计算\u002F分布式处理与计算随机模拟与统计推断",2433,"2026-07-06 22:40:29",{"path":850,"words":851,"published":852,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-基本图像",10011,"2026-06-14 20:18:20",{"path":854,"words":855,"published":856,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-14-数据可视化-概论",10030,"2026-06-14 15:18:20",{"path":858,"words":859,"published":860,"date":156},"\u002Fposts\u002F数据可视化\u002F2026-06-15-数据可视化-可视化库",2032,"2026-06-15 20:18:20",{"path":862,"words":863,"published":864,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-图",5451,"2025-04-15 20:48:06",{"path":866,"words":867,"published":868,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-树",4211,"2025-04-30 02:19:06",{"path":870,"words":871,"published":872,"date":156},"\u002Fposts\u002F数据结构\u002F2025-09-29-数据结构-队列",921,"2025-04-11 15:30:08",{"path":874,"words":875,"published":876,"date":156},"\u002Fposts\u002F数据结构\u002F关于数据结构的一些想法",456,"2025-04-04 19:13:49",{"path":878,"words":879,"published":880,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-栈",920,"2025-04-18 00:17:37",{"path":882,"words":883,"published":884,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-算法复杂度",2153,"2025-04-05 16:09:55",{"path":886,"words":887,"published":888,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表链表",4572,"2025-04-06 00:24:40",{"path":890,"words":891,"published":892,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-线性表顺序表",4191,"2025-04-05 22:09:59",{"path":894,"words":895,"published":896,"date":156},"\u002Fposts\u002F数据结构\u002F数据结构-绪论",2881,"2025-04-05 11:31:22",{"path":898,"words":899,"published":156,"date":900},"\u002Fposts\u002F杂记\u002F2023-12-26-2023年12月26日",7,"2023-12-26 23:51:33",{"path":902,"words":899,"published":156,"date":903},"\u002Fposts\u002F杂记\u002F2024-01-01-2024团建","2024-01-01 01:51:27",{"path":905,"words":581,"published":156,"date":906},"\u002Fposts\u002F杂记\u002F2024-01-09-随记","2024-01-09 20:50:35",{"path":908,"words":909,"published":156,"date":910},"\u002Fposts\u002F杂记\u002F2024-03-12-花名",5275,"2024-03-12 16:04:23",{"path":912,"words":913,"published":156,"date":914},"\u002Fposts\u002F杂记\u002F2024-04-15-逆模因",1353,"2024-04-15 00:26:16",{"path":916,"words":917,"published":156,"date":918},"\u002Fposts\u002F杂记\u002F2024-05-03-艺作",27,"2024-05-03 00:01:00",{"path":920,"words":921,"published":156,"date":922},"\u002Fposts\u002F杂记\u002F2024-05-21-关于博客",1720,"2024-02-21 23:21:11",{"path":924,"words":925,"published":156,"date":926},"\u002Fposts\u002F杂记\u002F2024-06-20-dnvrc维克多崔专访-2023",2036,"2024-06-20 00:28:39",{"path":928,"words":760,"published":156,"date":929},"\u002Fposts\u002F杂记\u002F2024-06-25-6月25日随记","2024-06-25 12:46:36",{"path":931,"words":932,"published":156,"date":933},"\u002Fposts\u002F杂记\u002F2024-06-25-歌名-想見星星",148,"2024-06-25 22:47:59",{"path":935,"words":936,"published":156,"date":937},"\u002Fposts\u002F杂记\u002F2024-07-11-桂花岗",6,"2024-07-11 00:28:17",{"path":939,"words":940,"published":156,"date":941},"\u002Fposts\u002F杂记\u002F2024-07-15-rolling-bocci",9,"2024-07-15 21:25:56",{"path":943,"words":944,"published":156,"date":945},"\u002Fposts\u002F杂记\u002F2024-07-22-七月九日",34,"2024-07-09 17:54:23",{"path":947,"words":948,"published":156,"date":949},"\u002Fposts\u002F杂记\u002F2024-07-22-六月随记",1052,"2024-07-22 01:03:19",{"path":951,"words":952,"published":156,"date":953},"\u002Fposts\u002F杂记\u002F2024-07-22-石菖蒲",41,"2024-07-10 01:26:05",{"path":955,"words":514,"published":156,"date":956},"\u002Fposts\u002F杂记\u002F2024-07-23-新书","2024-07-23 01:05:49",{"path":958,"words":959,"published":156,"date":960},"\u002Fposts\u002F杂记\u002F2024-07-29-年前",74,"2024-07-29 23:59:07",{"path":962,"words":963,"published":156,"date":964},"\u002Fposts\u002F杂记\u002F2024-07-30-周边",138,"2024-07-30 02:03:23",{"path":966,"words":967,"published":156,"date":968},"\u002Fposts\u002F杂记\u002F2024-07-31-2024-7-31日",185,"2024-07-31 01:21:52",{"path":970,"words":971,"published":156,"date":972},"\u002Fposts\u002F杂记\u002F2024-08-02-八月",1710,"2024-08-30 00:31:02",{"path":974,"words":975,"published":156,"date":976},"\u002Fposts\u002F杂记\u002F2024-09-01-九月",1484,"2024-09-26 16:30:15",{"path":978,"words":979,"published":156,"date":980},"\u002Fposts\u002F杂记\u002F2024-09-08-2024年9月8日",97,"2024-09-08 13:59:36",{"path":982,"words":514,"published":156,"date":983},"\u002Fposts\u002F杂记\u002F2024-09-19-博客站的一周年","2024-09-18 23:36:24",{"path":985,"words":986,"published":156,"date":987},"\u002Fposts\u002F杂记\u002F2024-10-03-十月",1028,"2024-10-31 23:54:27",{"path":989,"words":990,"published":156,"date":991},"\u002Fposts\u002F杂记\u002F2024-11-04-十一月",2134,"2024-11-30 00:04:39",{"path":993,"words":994,"published":156,"date":995},"\u002Fposts\u002F杂记\u002F2024-11-10-gzhu-site-193",80,"2024-11-10 19:19:12",{"path":997,"words":998,"published":156,"date":999},"\u002Fposts\u002F杂记\u002F2024-12-01-十二月",455,"2024-12-30 23:13:47",{"path":1001,"words":1002,"published":156,"date":1003},"\u002Fposts\u002F杂记\u002F2024-12-21-年末",23,"2024-12-21 23:21:49",{"path":1005,"words":522,"published":156,"date":1006},"\u002Fposts\u002F杂记\u002F2025-01-30-一月","2025-01-30 23:44:41",{"path":1008,"words":1009,"published":156,"date":1010},"\u002Fposts\u002F杂记\u002F2025-03-01-二月",224,"2025-02-28 00:11:08",{"path":1012,"words":1013,"published":156,"date":1014},"\u002Fposts\u002F杂记\u002F2025-03-01-博客杂谈",344,"2025-03-01 16:03:18",{"path":1016,"words":1017,"published":156,"date":1018},"\u002Fposts\u002F杂记\u002F2025-03-05-三月",2090,"2025-03-05 19:17:28",{"path":1020,"words":1021,"published":156,"date":1022},"\u002Fposts\u002F杂记\u002F2025-07-10-七月",361,"2025-07-10 22:04:32",{"path":1024,"words":1025,"published":156,"date":1026},"\u002Fposts\u002F杂记\u002F2025-09-21-九月",781,"2025-09-21 20:53:37",{"path":1028,"words":1029,"published":156,"date":1030},"\u002Fposts\u002F杂记\u002F2025-10-09-十月",591,"2025-10-09 00:35:07",{"path":1032,"words":1033,"published":156,"date":1034},"\u002Fposts\u002F杂记\u002Fcontrol",13,"2023-09-25 13:03:59",{"path":1036,"words":1037,"published":156,"date":1038},"\u002Fposts\u002F杂记\u002Fquadim四叉树图像处理",1094,"2023-10-21 11:27:06",{"path":1040,"words":1041,"published":156,"date":1042},"\u002Fposts\u002F杂记\u002Fsuccess",24,"2023-09-22 15:59:07",{"path":1044,"words":1045,"published":156,"date":1046},"\u002Fposts\u002F杂记\u002F三光年",295,"2023-11-18 04:18:40",{"path":1048,"words":1049,"published":156,"date":1050},"\u002Fposts\u002F杂记\u002F加密测试",961,"2023-11-21 14:24:01",{"path":1052,"words":1053,"published":156,"date":1054},"\u002Fposts\u002F杂记\u002F啊啊啊啊啊啊啊",54,"2023-09-20 17:29:33",{"path":1056,"words":1057,"published":156,"date":1058},"\u002Fposts\u002F杂记\u002F杂谈",124,"2023-09-25 23:11:32",{"path":1060,"words":1061,"published":156,"date":1062},"\u002Fposts\u002F杂记\u002F艹",25,"2023-10-21 17:40:43",{"path":1064,"words":1065,"published":1066,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习卷积神经网络",3168,"2026-06-07 11:23:08",{"path":1068,"words":1069,"published":1070,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习循环神经网络",2348,"2026-06-07 11:33:08",{"path":1072,"words":1073,"published":1074,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习改进学习方法",3360,"2026-06-07 10:13:08",{"path":1076,"words":1077,"published":1078,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习深度生成模型",2727,"2026-06-07 11:43:08",{"path":1080,"words":1081,"published":1082,"date":156},"\u002Fposts\u002F神经网络\u002F神经网络与深度学习神经网络基础",3205,"2026-06-07 10:03:08",{"id":1084,"title":1085,"abbrlink":1086,"body":1087,"category":152,"cover":1114,"date":156,"description":2096,"extension":2097,"mathjax":2098,"meta":2099,"navigation":2098,"path":639,"published":641,"readingMinutes":534,"seo":2102,"stem":2103,"sticky":156,"swiper_index":156,"tags":2104,"updated":156,"words":640,"__hash__":2105},"posts\u002Fposts\u002F2025\u002F2025-12-05-现代协同 2D 画布编辑器（PixiJS v8）.md","2025-12-05-现代协同 2D 画布编辑器（PixiJS v8）","17798",{"type":1088,"value":1089,"toc":2053},"minimark",[1090,1095,1105,1108,1115,1119,1125,1136,1141,1147,1150,1157,1161,1164,1169,1175,1180,1186,1189,1207,1210,1213,1217,1251,1254,1256,1259,1262,1268,1274,1280,1286,1292,1298,1304,1310,1316,1322,1328,1334,1340,1343,1350,1353,1356,1362,1368,1374,1380,1386,1392,1398,1404,1410,1416,1422,1428,1434,1437,1445,1448,1451,1454,1457,1462,1465,1470,1473,1481,1484,1489,1492,1498,1501,1507,1510,1512,1514,1517,1521,1524,1527,1530,1544,1547,1566,1572,1575,1593,1598,1601,1622,1627,1630,1649,1652,1655,1678,1681,1684,1701,1705,1708,1730,1733,1736,1748,1753,1756,1762,1768,1774,1780,1783,1786,1789,1796,1800,1807,1867,1873,1924,1930,1956,1962,2000,2006,2018,2024,2048],[1091,1092,1094],"h1",{"id":1093},"bddraw_dev-字节工训营画布项目","BDdraw_DEV 字节工训营画布项目",[1096,1097,1098,1099],"p",{},"代码仓库：\n",[1100,1101,1102],"a",{"href":1102,"rel":1103},"https:\u002F\u002Fgithub.com\u002FZhongye1\u002FBDdraw_DEV",[1104],"nofollow",[1096,1106,1107],{},"现代协同 2D 画布编辑器 · React 18 + TypeScript + Vite + TailwindCSS + Zustand + PixiJS v8",[1096,1109,1110],{},[1111,1112],"img",{"alt":1113,"src":1114},"alt text","https:\u002F\u002Fpica.zhimg.com\u002F80\u002Fv2-4d41cf5d8fba335823e8da128df17218_720w.webp",[1116,1117,1118],"h4",{"id":1118},"运行项目",[1096,1120,1121],{},[1122,1123,1124],"strong",{},"frontend",[1126,1127,1133],"pre",{"className":1128,"code":1130,"language":1131,"meta":1132},[1129],"language-bash","git clone git@github.com:Zhongye1\u002FBDdraw_DEV.git\n\ncd BDdraw_DEV (进入项目)\nbun install (安装依赖包)\nbun start (启动服务)\n","bash","",[1134,1135,1130],"code",{"__ignoreMap":1132},[1096,1137,1138],{},[1122,1139,1140],{},"backend",[1126,1142,1145],{"className":1143,"code":1144,"language":1131,"meta":1132},[1129],"cd BDdraw_DEV\u002FALD_Backend\u002F\nbun install #安装依赖\nbun index.ts  #启动后端服务\n",[1134,1146,1144],{"__ignoreMap":1132},[1096,1148,1149],{},"推荐使用 bun 包管理器，见个人博客",[1096,1151,1152],{},[1100,1153,1156],{"href":1154,"rel":1155},"https:\u002F\u002Fzhongye1.github.io\u002FArknight-notes\u002Fposts\u002F15722.html",[1104],"关于包管理器 npm,pnpm,yarn 和 bun 以及我为何选择后者",[1116,1158,1160],{"id":1159},"docker-部署","Docker 部署",[1096,1162,1163],{},"项目支持通过 Docker 进行容器化部署，使用 Node 22 和 Bun 包管理器。",[1096,1165,1166],{},[1122,1167,1168],{},"开发环境部署：",[1126,1170,1173],{"className":1171,"code":1172,"language":1131,"meta":1132},[1129],"docker-compose up -d\n",[1134,1174,1172],{"__ignoreMap":1132},[1096,1176,1177],{},[1122,1178,1179],{},"生产环境部署：",[1126,1181,1184],{"className":1182,"code":1183,"language":1131,"meta":1132},[1129],"docker-compose -f docker-compose.prod.yml up -d\n",[1134,1185,1183],{"__ignoreMap":1132},[1096,1187,1188],{},"部署完成后，可以通过以下地址访问：",[1190,1191,1192,1200],"ul",{},[1193,1194,1195,1196],"li",{},"前端应用: ",[1100,1197,1198],{"href":1198,"rel":1199},"http:\u002F\u002Flocalhost:5000\u002FBDdraw_DEV\u002F",[1104],[1193,1201,1202,1203],{},"后端 API 文档: ",[1100,1204,1205],{"href":1205,"rel":1206},"http:\u002F\u002Flocalhost:3000\u002Fswagger-ui",[1104],[1116,1208,1209],{"id":1209},"整体架构设计",[1096,1211,1212],{},"项目采用了模块化的架构设计，将不同的功能划分为独立的模块，以方便后续维护和扩展",[1214,1215,1216],"h2",{"id":1216},"特性",[1190,1218,1219,1222,1225,1228,1231,1234,1237,1240,1242,1245,1248],{},[1193,1220,1221],{},"60 FPS 渲染（得益于 PixiJS WebGL）",[1193,1223,1224],{},"完整撤销\u002F重做（Command Pattern + 防抖快照）",[1193,1226,1227],{},"多元素选择与群组操作",[1193,1229,1230],{},"画布元素变换控制器",[1193,1232,1233],{},"富文本所见即所得编辑（WanngEditor + PIXI.HTMLText）",[1193,1235,1236],{},"图片插入 + 内置滤镜（模糊、亮度、灰度等）",[1193,1238,1239],{},"插件式元素系统",[1193,1241,1239],{},[1193,1243,1244],{},"完整的 TypeScript 类型支持",[1193,1246,1247],{},"现代开发体验（Vite + ESLint + Prettier + Husky）",[1193,1249,1250],{},"集成 GitHub-Actions 支持， 实现每次 push 到 main 分支后，GitHub 自动构建 → 自动发布页面的操作",[1252,1253],"hr",{},[1252,1255],{},[1257,1258,279],"h3",{"id":279},[1096,1260,1261],{},"这时候需要简单做一个技术选型分析，根据任务拆解，选择了如下技术栈",[1096,1263,1264,1267],{},[1122,1265,1266],{},"【框架】","【技术方案：采用 React 18 + TypeScript 5 构建应用，React 提供完整的 UI 生态，TypeScript 提供更清晰可靠的类型安全，相比 JavaScript 更易于维护】",[1096,1269,1270,1273],{},[1122,1271,1272],{},"【构建工具】","【技术方案：使用 Vite 5 作为构建工具，其开发服务器启动和热模块替换（HMR）速度明显快于 Webpack】",[1096,1275,1276,1279],{},[1122,1277,1278],{},"【路由】","【技术方案：采用 React Router DOM 6 实现路由管理，API 稳定且文档完善】",[1096,1281,1282,1285],{},[1122,1283,1284],{},"【样式】","【技术方案：使用 Tailwind CSS 3 + PostCSS 处理样式，开发时编写样式更快，生产环境会自动进行 tree-shaking 优化，相比 CSS Modules 和 styled-components 更高效且原子化更直观，对 AI 工具友好】",[1096,1287,1288,1291],{},[1122,1289,1290],{},"【样式扩展】","【技术方案：少量使用 Less 覆盖 Tailwind 主题变量，保持兼容性】",[1096,1293,1294,1297],{},[1122,1295,1296],{},"【SVG 处理】","【技术方案：使用 SVGR 1.5 处理 SVG，Vite 原生支持，可以将 SVG 作为 React 组件使用，比直接使用 SVG 或 SVG sprite 更灵活】",[1096,1299,1300,1303],{},[1122,1301,1302],{},"【UI 组件库】","【技术方案：采用 shadcn\u002Fui（latest）和 Arco Design 2 实现 UI 组件，易于使用，符合字节项目使用字节组件库的习惯】",[1096,1305,1306,1309],{},[1122,1307,1308],{},"【全局状态】","【技术方案：采用 Zustand 4 管理全局状态，API 简洁、性能良好且无样板代码，相比 Redux Toolkit、Pinia、Jotai 代码量更少且配有 Devtools】",[1096,1311,1312,1315],{},[1122,1313,1314],{},"【图形\u002F画布】","【技术方案：使用 PixiJS 8 + pixi-viewport 实现图形和画布功能，基于 WebGL 渲染，适合处理大量精灵元素，相比其他可选方案性能更高】",[1096,1317,1318,1321],{},[1122,1319,1320],{},"【富文本编辑器】","【技术方案：采用 WangEditor 5 作为富文本编辑器，轻量且文档和社区均为中文，相比 Slate\u002FTipTap 等编辑器，默认输出的 HTML 可直接给 PixiJS HTMLText 进行渲染】",[1096,1323,1324,1327],{},[1122,1325,1326],{},"【图标】","【技术方案：使用 Lucide React 图标库，图标数量多、风格统一且支持 Tree-shaking】",[1096,1329,1330,1333],{},[1122,1331,1332],{},"【工具库】","【技术方案：采用 nanoid 3 为画布元素生成唯一标识符等操作，轻量实用】",[1096,1335,1336,1339],{},[1122,1337,1338],{},"【代码质量】","【技术方案：使用 ESLint + Stylelint + Prettier + Husky + lint-staged + commitlint 保证团队代码风格一致，这是中大型项目的基本配置，有利于多人协作开发】",[1096,1341,1342],{},"此外，还配置了 react 开发者工具 react-dev-inspector，配置了一下，开发环境下 ctrl+q 可以实现点击页面上的组件，在 VSCode 中自动跳转到对应文件，并定位到对应行号，方便调试（先前写 vue 也用过类似的）",[1096,1344,1345,1346],{},"项目 ",[1100,1347,1348],{"href":1348,"rel":1349},"https:\u002F\u002Freact-dev-inspector.zthxxx.me\u002Fdocs",[1104],[1257,1351,1352],{"id":1352},"功能要素和方案",[1096,1354,1355],{},"分析以上需求，查阅相关资料后，进行各个核心模块的技术方案选型，确定初步实现方案",[1096,1357,1358,1361],{},[1122,1359,1360],{},"【基础渲染引擎】","【技术方案：PixiJS v8（WebGL）提供高性能 2D 渲染，根据不同元素类型创建对应的 Pixi 对象（图形、文本、图像），通过 pixi-viewport 实现无限画布的视口控制，支持缩放、拖拽等交互】",[1096,1363,1364,1367],{},[1122,1365,1366],{},"【无限画布视口】","【技术方案：pixi-viewport（内置 zoom、drag、decelerate、clampZoom）库创建无限画布，在 StageManagerCore.ts 中初始化 viewport，并添加拖拽、缩放等交互功能，支持鼠标中键拖拽画布、滚轮缩放等常见操作】",[1096,1369,1370,1373],{},[1122,1371,1372],{},"【富文本编辑】","【技术方案：WangEditor 5 作为富文本编辑器，提供完整的文本编辑功能，编辑结果以 HTML 格式存储在元素的 text\u002Fstring 属性中，元素使用 PixiJS 内置的 HTMLText 进行渲染实现富文本效果】",[1096,1375,1376,1379],{},[1122,1377,1378],{},"【状态管理与数据结构】","【技术方案：Zustand 作为全局状态管理库，通过 structuredClone 函数手动创建状态快照，管理画布元素、选中状态、工具类型等，通过中间件监听状态变化并触发重渲染，在特定的 ts 中定义所有状态和操作方法】",[1096,1381,1382,1385],{},[1122,1383,1384],{},"【图片上传显示与滤镜】","【技术方案：PixiJS 内置 Filter 系统包括 BlurFilter、ColorMatrixFilter（黑白、对比度、饱和度）实现图像处理效果，支持模糊、亮度调整、灰度等多种滤镜效果，在 ElementRenderer.ts 中根据元素的 filter 属性应用相应滤镜，支持 blur（模糊）、brightness（亮度）、grayscale（灰度）等滤镜类型】",[1096,1387,1388,1391],{},[1122,1389,1390],{},"【选中与变换系统】","【技术方案：SelectionManager + TransformOverlay（8 个把手 + 旋转把手）实现变换控件渲染，支持单个元素选中和多个元素群组选中，提供 8 个控制点和 1 个旋转点进行变换操作，根据不同元素类型提供不同的控制方式】",[1096,1393,1394,1397],{},[1122,1395,1396],{},"【旋转与组合嵌套】","【技术方案：每个元素维护自己的 matrix（局部矩阵），组合后父容器统一应用矩阵变换，支持多层级嵌套和复杂变换】",[1096,1399,1400,1403],{},[1122,1401,1402],{},"【Minimap】","【技术方案：单独一个小的 Pixi.Application（共享 texture 缓存）实现缩略图功能，主画布所有容器使用 cacheAsBitmap 后生成低分辨率 texture，实时更新到小画布，视口框用一个半透明矩形表示在主画布中的位置】",[1096,1405,1406,1409],{},[1122,1407,1408],{},"【元素永久缓存】","【技术方案：使用 spriteMap 来存储 PIXI 对象，元素更新时只修改属性并设置 container.dirty = true，而不是销毁重建，来解决拖拽中断、光标丢失、闪烁等问题】",[1096,1411,1412,1415],{},[1122,1413,1414],{},"【辅助对齐线】","【技术方案：拖拽时实时遍历所有元素 bounds，计算对齐情况（水平\u002F垂直\u002F间距相等），差值\u003C6px 就吸附并画蓝线，支持水平、垂直对齐以及等间距对齐等多种对齐方式，当距离小于阈值时自动吸附并对齐】",[1096,1417,1418,1421],{},[1122,1419,1420],{},"【Undo\u002FRedo】","【技术方案：Command Pattern + structuredClone 完整快照（每步 before\u002Fafter）实现撤销\u002F重做功能，通过管理命令栈（undo，redo 栈），使用 structuredClone 创建状态快照，记录操作前后的完整状态，来支持添加元素、删除元素、修改元素属性等操作的撤销\u002F重做，针对拖拽和调整大小操作的命令生成逻辑可能还要具体再处理一套】",[1096,1423,1424,1427],{},[1122,1425,1426],{},"【数据持久化与离线】","【技术方案：Zustand-persist + localForage（IndexedDB）实现数据持久化和离线使用，使用 Zustand 的持久化中间件保存状态，通过 localForage 将数据存储到 IndexedDB 中，实现数据的自动保存和恢复功能】",[1096,1429,1430,1433],{},[1122,1431,1432],{},"【实时协同】","【技术方案：Y.js + y-websocket（或自己写 CRDT）+ Operation Transform 合并策略实现无冲突的实时协同编辑，通过 y-websocket 插件实现服务端同步（问的 AI），有个思路是把操作打给时间 tag，然后然后按时间合并】",[1116,1435,1436],{"id":1436},"项目架构树",[1126,1438,1443],{"className":1439,"code":1441,"language":1442,"meta":1132},[1440],"language-sh","BDdraw_DEV\u002F\n├── ALD_Backend\u002F                    # 后端服务目录\n│   ├── src\u002F                        # 后端源代码\n│   │   ├── api\u002F                    # API接口目录\n│   │   │   ├── Room_management\u002F    # 房间管理相关API\n│   │   │   │   ├── types\u002F          # 房间管理相关类型定义\n│   │   │   │   │   ├── Room_CRUD_types.ts  # 房间增删改查类型定义\n│   │   │   │   │   ├── Room_List_types.ts  # 房间列表类型定义\n│   │   │   │   │   ├── Room_users_types.ts # 房间用户类型定义\n│   │   │   │   │   └── index.ts            # 类型索引文件\n│   │   │   │   ├── CORE.ts         # 核心房间管理逻辑\n│   │   │   │   ├── Room_CRUD.ts    # 房间增删改查操作实现\n│   │   │   │   ├── Room_List.ts    # 房间列表管理实现\n│   │   │   │   └── Room_users.ts   # 房间用户管理实现\n│   │   │   ├── USER_management\u002F    # 用户管理相关API\n│   │   │   │   ├── auth_API.ts     # 用户认证API实现\n│   │   │   │   └── auth_API_types.ts  # 用户认证类型定义\n│   │   │   └── index.ts            # API索引文件\n│   │   ├── auth.ts                 # 认证模块实现\n│   │   ├── collab.ts               # 协作功能模块实现\n│   │   └── db.ts                   # 数据库连接和操作实现\n│   ├── ARCHITECTURE.md             # 后端架构说明文档\n│   ├── README.md                   # 后端说明文档\n│   ├── index.ts                    # 后端服务入口文件\n│   ├── package.json                # 后端依赖配置文件\n│   └── tsconfig.json               # 后端TypeScript配置\n├── src\u002F                            # 前端源代码目录\n│   ├── api\u002F                        # 前端API客户端\n│   │   ├── types\u002F                  # API类型定义\n│   │   │   ├── Room_management\u002F    # 房间管理相关类型定义\n│   │   │   │   ├── Room_CRUD_types.ts  # 房间增删改查类型定义\n│   │   │   │   ├── Room_List_types.ts  # 房间列表类型定义\n│   │   │   │   ├── Room_users_types.ts # 房间用户类型定义\n│   │   │   │   └── index.ts            # 类型索引文件\n│   │   │   ├── auth_API_types.ts   # 认证相关类型定义\n│   │   │   └── index.ts            # API类型索引文件\n│   │   ├── utils\u002F                  # API工具函数\n│   │   │   └── apiClient.ts        # API客户端工具\n│   │   ├── apiService.ts           # API服务封装实现\n│   │   └── index.ts                # API索引文件\n│   ├── components\u002F                 # React组件目录\n│   │   ├── Richtext_editor\u002F        # 富文本编辑器组件\n│   │   │   ├── BottomTextEditor.tsx    # 底部文本编辑器实现\n│   │   │   └── Richtext_editor.tsx     # 富文本编辑器主组件\n│   │   ├── canvas_toolbar\u002F         # 画布工具栏组件\n│   │   │   ├── ContextMenu.tsx     # 上下文菜单实现\n│   │   │   └── TopToolbar.tsx      # 顶部工具栏实现\n│   │   ├── collaboration\u002F          # 协作功能组件\n│   │   │   ├── CollaboratorCursors.tsx # 协作者光标显示组件\n│   │   │   └── RemoteSelectionLayer.tsx # 远程选择层组件\n│   │   ├── error-page\u002F             # 错误页面组件\n│   │   │   └── index.tsx           # 错误页面实现\n│   │   ├── header\u002F                 # 页面头部组件\n│   │   │   ├── contents\u002F           # 头部内容组件\n│   │   │   │   ├── ExportCanvasModal.tsx   # 导出画布模态框\n│   │   │   │   └── StageManagerContext.tsx # 舞台管理上下文\n│   │   │   └── index.tsx           # 头部组件入口\n│   │   ├── image-insert-modal\u002F     # 图片插入模态框组件\n│   │   │   └── index.tsx           # 图片插入模态框实现\n│   │   ├── layout\u002F                 # 布局组件\n│   │   │   └── index.tsx           # 布局组件实现\n│   │   ├── minimap\u002F                # 小地图组件\n│   │   │   └── Minimap.tsx         # 小地图实现\n│   │   ├── property-panel\u002F         # 属性面板组件\n│   │   │   └── index.tsx           # 属性面板实现\n│   │   ├── settings\u002F               # 设置组件\n│   │   │   └── setting.tsx         # 设置组件实现\n│   │   ├── ui\u002F                     # 基础UI组件\n│   │   │   ├── blackwhitebutton.tsx    # 黑白按钮组件\n│   │   │   ├── button.tsx          # 按钮组件\n│   │   │   ├── icon-circle.tsx     # 圆形图标组件\n│   │   │   ├── icon-clear.tsx      # 清除图标组件\n│   │   │   ├── icon-rect.tsx       # 矩形图标组件\n│   │   │   ├── icon-select.tsx     # 选择图标组件\n│   │   │   └── icon-triangle.tsx   # 三角形图标组件\n│   │   ├── AnimatedRoutes.tsx      # 动画路由组件\n│   │   ├── ParallaxBackground.tsx  # 视差背景组件\n│   │   └── WipeTransition.tsx      # 擦除过渡动画组件\n│   ├── hooks\u002F                      # 自定义React Hooks\n│   │   ├── use-localstorage-state.ts   # localStorage状态管理Hook\n│   │   └── use_React_hotkeys_management.ts # 快捷键管理Hook\n│   ├── lib\u002F                        # 工具库和核心功能模块\n│   │   ├── AddElementCommand.ts    # 添加元素命令实现\n│   │   ├── RemoveElementCommand.ts # 删除元素命令实现\n│   │   ├── UndoRedoManager.ts      # 撤销重做管理器实现\n│   │   ├── UpdateElementCommand.ts # 更新元素命令实现\n│   │   ├── UpdateElementPropertyCommand.ts # 更新元素属性命令实现\n│   │   ├── constants.ts            # 常量定义文件\n│   │   ├── env.ts                  # 环境变量配置\n│   │   ├── minimapUtils.ts         # 小地图工具函数\n│   │   └── utils.ts                # 通用工具函数\n│   ├── pages\u002F                      # 页面组件目录\n│   │   ├── auth\u002F                   # 认证相关页面\n│   │   │   ├── Login.tsx           # 登录页面实现\n│   │   │   └── Register.tsx        # 注册页面实现\n│   │   ├── canvas\u002F                 # 画布主页面\n│   │   │   ├── Pixi_STM_modules\u002F   # Pixi.js状态管理模块\n│   │   │   │   ├── core\u002F           # 核心类和初始化逻辑\n│   │   │   │   │   ├── Core_StageManager.ts    # 核心舞台管理器\n│   │   │   │   │   ├── ElementRender.ts        # 元素渲染器\n│   │   │   │   │   ├── TF_controler_Renderer.ts # 变换控制器渲染器\n│   │   │   │   │   └── types.ts                # 核心类型定义\n│   │   │   │   ├── interaction\u002F    # 交互处理模块\n│   │   │   │   │   ├── Base_InteractionHandler.ts   # 基础交互处理器\n│   │   │   │   │   └── Stage_InteractionHandler.ts  # 舞台交互处理器\n│   │   │   │   ├── shared\u002F         # 共享类型定义\n│   │   │   │   │   └── types.ts    # 共享类型定义文件\n│   │   │   │   ├── utils\u002F          # 工具函数目录\n│   │   │   │   │   ├── commandUtils.ts      # 命令工具函数\n│   │   │   │   │   ├── cursorUtils.ts       # 光标工具函数\n│   │   │   │   │   ├── destroyUtils.ts      # 销毁工具函数\n│   │   │   │   │   ├── dragUtils.ts         # 拖拽工具函数\n│   │   │   │   │   ├── drawingUtils.ts      # 绘图工具函数\n│   │   │   │   │   ├── eraserUtils.ts       # 橡皮擦工具函数\n│   │   │   │   │   ├── geometryUtils.ts     # 几何工具函数\n│   │   │   │   │   ├── guidelineUtils.ts    # 辅助线工具函数\n│   │   │   │   │   ├── interactionUtils.ts  # 交互工具函数\n│   │   │   │   │   ├── renderUtils.ts       # 渲染工具函数\n│   │   │   │   │   ├── resizeUtils.ts       # 调整大小工具函数\n│   │   │   │   │   ├── rotationUtils.ts     # 旋转工具函数\n│   │   │   │   │   ├── scaleUtils.ts        # 缩放工具函数\n│   │   │   │   │   ├── selectionUtils.ts    # 选择工具函数\n│   │   │   │   │   └── stateUtils.ts        # 状态工具函数\n│   │   │   │   └── STM_modules.md  # 状态管理模块说明文档\n│   │   │   ├── Pixi_stageManager.ts    # Pixi舞台管理器入口\n│   │   │   └── index.tsx           # 画布页面入口文件\n│   │   ├── home\u002F                   # 主页\n│   │   │   ├── contents\u002F           # 主页内容组件\n│   │   │   │   └── AKN.tsx         # AKN内容组件\n│   │   │   └── index.tsx           # 主页入口文件\n│   │   ├── intro\u002F                  # 介绍页面\n│   │   │   └── index.tsx           # 介绍页面实现\n│   │   └── room\u002F                   # 房间管理页面\n│   │       └── RoomManagement.tsx  # 房间管理页面实现\n│   ├── router\u002F                     # 路由配置目录\n│   │   └── router.tsx              # 路由配置实现\n│   ├── stores\u002F                     # 状态存储目录(Zustand)\n│   │   ├── canvasStore.ts          # 画布状态存储\n│   │   ├── persistenceStore.ts     # 持久化状态存储\n│   │   └── themeStore.ts           # 主题状态存储\n│   ├── app.tsx                     # 应用根组件\n│   ├── main.tsx                    # 应用入口文件\n│   └── vite-env.d.ts               # Vite环境声明文件\n├── README.md                       # 项目说明文档\n├── components.json                 # 组件配置文件\n├── index.html                      # HTML入口文件\n├── lint-staged.config.js           # Lint-staged配置\n├── package.json                    # 项目依赖和脚本配置\n├── postcss.config.js               # PostCSS配置\n├── tailwind.config.js              # Tailwind CSS配置\n├── transmart.config.ts             # Transmart配置\n├── tsconfig.json                   # TypeScript配置\n├── tsconfig.node.json              # Node.js TypeScript配置\n└── vite.config.ts                  # Vite构建配置\n","sh",[1134,1444,1441],{"__ignoreMap":1132},[1257,1446,1447],{"id":1447},"项目架构设计",[1096,1449,1450],{},"项目采用数据驱动视图（Data-Driven View）模式，使用**React (UI) + Zustand (数据) + PixiJS (渲染)**的三层架构",[1096,1452,1453],{},"React 只负责 UI 和事件入口\nZustand 是唯一的真实数据源（纯 JSON，可持久化、可协同）\nPixiJS 层只做\"渲染 + 交互计算\"，所有对象永久缓存（Map），绝不每帧重建\n所有变换（拖拽、缩放、旋转、组合）都在 Pixi 层完成，最后再同步回 Zustand（单向数据流）",[1096,1455,1456],{},"项目主要划分为三个层次：渲染层、状态管理层和逻辑层，来实现关注点分离，提高代码的可维护性和可扩展性。",[1116,1458,1460],{"id":1459},"渲染层",[1122,1461,1459],{},[1096,1463,1464],{},"主要由 PixiJS (WebGL) 负责处理图形渲染，包括创建、更新和删除图形对象。这一层负责将状态管理层的数据转换为可视化的图形元素，并处理用户的交互操作，如拖拽、缩放和旋转等",[1116,1466,1468],{"id":1467},"状态管理层",[1122,1469,1467],{},[1096,1471,1472],{},"采用 Zustand 管理 JSON 画布数据。\n先定义一个 CanvasState 接口（JSON 数据结构，包含 id, type, x, y, width, height 等属性）",[1126,1474,1479],{"className":1475,"code":1477,"language":1478,"meta":1132},[1476],"language-ts","interface CanvasState {\n    tool: ToolType; \u002F\u002F 当前工具类型\n    elements: Record\u003Cstring, CanvasElement>; \u002F\u002F 画布元素集合\n    selectedIds: string[]; \u002F\u002F 选中元素ID列表\n    editingId: string | null; \u002F\u002F 正在编辑的元素ID\n    clipboard: CanvasElement[] | null; \u002F\u002F 剪贴板数据\n    pasteOffset: number; \u002F\u002F 粘贴偏移计数\n    currentStyle: {\n        fill: string;\n        stroke: string;\n        strokeWidth: number;\n        \u002F\u002F ... 其他样式属性\n    };\n}\n","ts",[1134,1480,1477],{"__ignoreMap":1132},[1096,1482,1483],{},"使用 Zustand 状态管理库，其中 elements 被定义为 Record\u003Cstring, CanvasElement>类型，表示一个以 id 为键，CanvasElement 为值的对象，用于存储画布上的所有元素。更新元素时使用 structuredClone 函数来克隆状态数据。后续持久化存储和撤销重做机制也是基于这一套状态管理来实现。这一层作为数据核心，主要维护画布上所有元素的状态信息，通过集中管理状态，确保了数据的一致性，便于后续的协同编辑和撤销重做功能的开发。",[1116,1485,1487],{"id":1486},"逻辑层",[1122,1488,1486],{},[1096,1490,1491],{},"核心是 StageManagerCore 类，通过 StageManagerState 接口管理交互状态，包括当前交互模式、起始位置、当前元素 ID、初始元素状态等，处理多种交互模式：",[1126,1493,1496],{"className":1494,"code":1495,"language":1131,"meta":1132},[1129],"idle - 空闲状态\npanning - 画布平移\nselecting - 选择元素\ndragging - 拖拽元素\nresizing - 调整元素大小\ndrawing - 绘制元素\ntexting - 文本编辑\nerasing - 擦除元素\n",[1134,1497,1495],{"__ignoreMap":1132},[1096,1499,1500],{},"处理多种元素操作逻辑：",[1126,1502,1505],{"className":1503,"code":1504,"language":1131,"meta":1132},[1129],"创建元素 - 根据不同工具类型创建相应元素\n选择元素 - 支持单选和多选\n拖拽元素 - 记录初始状态，计算偏移量\n调整大小 - 通过控制手柄调整元素尺寸\n删除元素 - 通过橡皮擦工具删除元素\n",[1134,1506,1504],{"__ignoreMap":1132},[1096,1508,1509],{},"通过这种方式来实现面向对象编程并封装业务逻辑，提高代码的可维护性，利用后续拓展",[1252,1511],{},[1252,1513],{},[1257,1515,1516],{"id":1516},"数据流程",[1518,1519],"mermaid",{"code":1520},"graph TD\n    A[用户交互] --> B{交互类型}\n    B -->|创建元素| C[StageManagerCore.onPointerDown]\n    B -->|拖拽元素| D[StageManagerCore.onPointerMove]\n    B -->|调整大小| E[StageManagerCore.onHandleDown]\n    B -->|选择元素| F[StageManagerCore.onPointerUp]\n\n    C --> G[Zustand Store.addElement]\n    D --> H[Zustand Store.updateElement]\n    E --> I[Zustand Store.updateElement]\n    F --> J[Zustand Store.setSelected]\n\n    G --> K[Zustand 状态更新]\n    H --> K\n    I --> K\n    J --> K\n\n    K --> L{状态变化}\n    L -->|元素变化| M[ElementRenderer.renderElements]\n    L -->|选择变化| N[TransformerRenderer.renderTransformer]\n\n    M --> O[PixiJS 图形渲染]\n    N --> O\n\n    O --> P[用户看到更新结果]\n\n    K --> Q[Zustand 持久化]\n    Q --> R[本地存储\u002FIndexedDB]\n\n    K --> S[撤销\u002F重做管理]\n    S --> T[命令栈管理]\n\n    style A fill:#e1f5fe\n    style O fill:#e8f5e8\n    style K fill:#fff3e0\n    style Q fill:#fce4ec",[1096,1522,1523],{},"流程如下：",[1116,1525,1526],{"id":1526},"用户交互输入",[1096,1528,1529],{},"所有用户交互事件由 StageManagerCore 处理\n用户通过鼠标、键盘等方式与画布进行交互：",[1190,1531,1532,1535,1538,1541],{},[1193,1533,1534],{},"创建新元素（点击工具栏选择图形类型后在画布上绘制）",[1193,1536,1537],{},"拖拽元素（选中元素后拖动）",[1193,1539,1540],{},"调整元素大小（拖拽元素控制点）",[1193,1542,1543],{},"选择元素（点击或框选元素）",[1116,1545,1546],{"id":1546},"创建元素流程",[1548,1549,1550,1553,1559],"ol",{},[1193,1551,1552],{},"用户在画布上按下鼠标开始绘制",[1193,1554,1555,1558],{},[1100,1556,1557],{"href":1132},"onPointerDown","捕获事件，创建新元素",[1193,1560,1561,1562,1565],{},"调用 Zustand store 的",[1100,1563,1564],{"href":1132},"addElement","方法添加元素",[1567,1568,1569],"blockquote",{},[1096,1570,1571],{},"创建元素时的中间状态要锁定撤销\u002F重做管理器防止记录中间的一堆状态",[1116,1573,1574],{"id":1574},"拖拽元素流程",[1548,1576,1577,1580,1586],{},[1193,1578,1579],{},"用户按下并拖动已选中的元素",[1193,1581,1582,1585],{},[1100,1583,1584],{"href":1132},"onPointerMove","持续捕获鼠标移动事件",[1193,1587,1588,1589,1592],{},"实时调用 Zustand store 的",[1100,1590,1591],{"href":1132},"updateElement","更新元素位置",[1567,1594,1595],{},[1096,1596,1597],{},"拖拽元素时也是中间状态要锁定撤销\u002F重做管理器防止记录中间的一堆状态",[1116,1599,1600],{"id":1600},"调整大小流程",[1548,1602,1603,1606,1612,1617],{},[1193,1604,1605],{},"用户拖拽元素的控制点（resize handle）",[1193,1607,1608,1611],{},[1100,1609,1610],{"href":1132},"onHandleDown","捕获控制点拖拽事件",[1193,1613,1614,1616],{},[1100,1615,1584],{"href":1132},"计算缩放比例并更新元素大小",[1193,1618,1561,1619,1621],{},[1100,1620,1591],{"href":1132},"更新元素属性",[1567,1623,1624],{},[1096,1625,1626],{},"调整元素大小时也是中间状态要锁定撤销\u002F重做管理器防止记录中间的一堆状态",[1116,1628,1629],{"id":1629},"交互结束处理",[1548,1631,1632,1639,1646],{},[1193,1633,1634,1635,1638],{},"用户释放鼠标按键，",[1100,1636,1637],{"href":1132},"onPointerUp","处理交互结束,解锁撤销\u002F重做管理器",[1193,1640,1641,1642,1645],{},"创建相应的命令（",[1100,1643,1644],{"href":1132},"UpdateElementCommand","并添加到命令栈中",[1193,1647,1648],{},"清理临时状态",[1116,1650,1651],{"id":1651},"状态更新",[1096,1653,1654],{},"Zustand 作为全局状态管理器，处理所有状态更新：",[1548,1656,1657,1666,1672],{},[1193,1658,1659,1661,1662,1665],{},[1122,1660,1651],{},"：自定义一套",[1100,1663,1664],{"href":1132},"originalSet","方法更新状态",[1193,1667,1668,1671],{},[1122,1669,1670],{},"撤销\u002F重做处理","：创建状态快照并生成命令对象",[1193,1673,1674,1677],{},[1122,1675,1676],{},"状态订阅","：通知所有订阅者状态变化",[1116,1679,1680],{"id":1680},"渲染更新",[1096,1682,1683],{},"Zustand 状态变化触发 StageManagerCore 的订阅回调：",[1548,1685,1686,1692,1698],{},[1193,1687,1688,1691],{},[1100,1689,1690],{"href":1132},"ElementRenderer.renderElements"," 根据元素数据更新 PixiJS 图形对象",[1193,1693,1694,1697],{},[1100,1695,1696],{"href":1132},"TransformerRenderer.renderTransformer"," 更新选中元素的变换控制器",[1193,1699,1700],{},"PixiJS 自动进行渲染",[1116,1702,1704],{"id":1703},"撤销重做管理","撤销\u002F重做管理",[1096,1706,1707],{},"通过命令模式实现撤销\u002F重做功能：",[1548,1709,1710,1720,1723],{},[1193,1711,1712,1713,1715,1716,1719],{},"每个操作生成对应的命令对象（",[1100,1714,1644],{"href":1132},"、",[1100,1717,1718],{"href":1132},"SnapshotCommand","等）",[1193,1721,1722],{},"命令对象保存操作前后的状态快照",[1193,1724,1725,1726,1729],{},"通过",[1100,1727,1728],{"href":1132},"UndoRedoManager","管理命令栈，实现撤销和重做功能",[1116,1731,1732],{"id":1732},"数据持久化阶段",[1096,1734,1735],{},"Zustand 状态变化同时触发数据持久化：",[1548,1737,1738,1745],{},[1193,1739,1740,1741,1744],{},"状态通过",[1100,1742,1743],{"href":1132},"persist","中间件自动保存到本地存储",[1193,1746,1747],{},"数据存储在 IndexedDB 中，来支持离线使用",[1567,1749,1750],{},[1096,1751,1752],{},"这一块还在写",[1257,1754,1755],{"id":1755},"设计的相关考虑",[1096,1757,1758,1761],{},[1122,1759,1760],{},"解耦","：渲染层、状态管理层和逻辑层相互独立，便于维护和扩展",[1096,1763,1764,1767],{},[1122,1765,1766],{},"便于后续的协同编辑","：实现多人协同，要监听 WebSocket 消息，然后更新 Zustand Store。StageManager 可以去监听到 Store 的变化，并作出相应的渲染更新",[1096,1769,1770,1773],{},[1122,1771,1772],{},"对撤销\u002F重做的实现","：因为所有状态都在 Store 里，只需要保存\u002F恢复 Store 的快照",[1096,1775,1776,1779],{},[1122,1777,1778],{},"序列化\u002F反序列化","：保存项目只需 JSON.stringify(store.elements)",[1116,1781,1782],{"id":1782},"目前的问题",[1096,1784,1785],{},"【待补充】",[1214,1787,1788],{"id":1788},"项目预览",[1096,1790,1791,1792],{},"部署地址：",[1100,1793,1794],{"href":1794,"rel":1795},"https:\u002F\u002Fzhongye1.github.io\u002FBDdraw_DEV\u002F",[1104],[1257,1797,1799],{"id":1798},"todo","TODO",[1116,1801,1803],{"id":1802},"p0基础渲染",[1804,1805,1806],"del",{},"【P0】基础渲染",[1190,1808,1809,1831,1836],{},[1193,1810,1811,1814],{},[1804,1812,1813],{},"支持图形渲染，需要支持至少 3 种不同图形，比如矩形、圆角矩形、圆形、三角形等。需要支持以下图形属性：",[1190,1815,1816,1821,1826],{},[1193,1817,1818],{},[1804,1819,1820],{},"背景色（background）",[1193,1822,1823],{},[1804,1824,1825],{},"边框宽度（border-width）",[1193,1827,1828],{},[1804,1829,1830],{},"边框颜色（border-color）",[1193,1832,1833],{},[1804,1834,1835],{},"支持图片渲染，需要支持 png、jpeg 格式，支持设置三种简单滤镜",[1193,1837,1838,1841],{},[1804,1839,1840],{},"支持富文本文字渲染，需要支持以下文本属性：",[1190,1842,1843,1848,1853,1858,1862],{},[1193,1844,1845],{},[1804,1846,1847],{},"字体（font-family）",[1193,1849,1850],{},[1804,1851,1852],{},"字号（font-size）",[1193,1854,1855],{},[1804,1856,1857],{},"颜色（color）",[1193,1859,1860],{},[1804,1861,1820],{},[1193,1863,1864],{},[1804,1865,1866],{},"BIUS（加粗、斜体、下划线、删除线）",[1116,1868,1870],{"id":1869},"p0画布交互",[1804,1871,1872],{},"【P0】画布交互",[1190,1874,1875,1892,1909,1914,1919],{},[1193,1876,1877,1880],{},[1804,1878,1879],{},"支持无限画布的缩放、滚动、拖拽",[1190,1881,1882,1887],{},[1193,1883,1884],{},[1804,1885,1886],{},"支持无限画布滚动条",[1193,1888,1889],{},[1804,1890,1891],{},"支持无限画布的 minimap 功能",[1193,1893,1894,1897],{},[1804,1895,1896],{},"支持选区功能：",[1190,1898,1899,1904],{},[1193,1900,1901],{},[1804,1902,1903],{},"点击选中单个元素",[1193,1905,1906],{},[1804,1907,1908],{},"框选选中多个元素",[1193,1910,1911],{},[1804,1912,1913],{},"支持数据持久化，每次操作后自动保存数据，刷新页面数据仍然存在",[1193,1915,1916],{},[1804,1917,1918],{},"快捷键复制选中元素",[1193,1920,1921],{},[1804,1922,1923],{},"支持辅助线功能",[1116,1925,1927],{"id":1926},"p0调参工具栏",[1804,1928,1929],{},"【P0】调参工具栏",[1190,1931,1932],{},[1193,1933,1934,1937],{},[1804,1935,1936],{},"浮动工具栏",[1190,1938,1939,1945,1950],{},[1193,1940,1941,1944],{},[1804,1942,1943],{},"当选中文本元素时出现在上方，支持设置不同文本属性","（做了个编辑器）",[1193,1946,1947],{},[1804,1948,1949],{},"当选中图形元素时出现在上方，支持设置不同图形属性",[1193,1951,1952,1955],{},[1804,1953,1954],{},"选中文本元素的部分文字时也能够出现，支持设置局部文本的文本属性","（编辑器内编辑可实现）",[1116,1957,1959],{"id":1958},"p0元素编辑",[1804,1960,1961],{},"【P0】元素编辑",[1190,1963,1964,1969,1974,1979,1984,1989,1994],{},[1193,1965,1966],{},[1804,1967,1968],{},"支持双击文本进入编辑，可以输入\u002F删除文本内容",[1193,1970,1971],{},[1804,1972,1973],{},"支持对选中元素（单个或多个）删除",[1193,1975,1976],{},[1804,1977,1978],{},"支持对选中元素（单个或多个）拖拽",[1193,1980,1981],{},[1804,1982,1983],{},"支持对选中元素（单个或多个）缩放",[1193,1985,1986],{},[1804,1987,1988],{},"支持对选中元素（单个或多个）旋转",[1193,1990,1991],{},[1804,1992,1993],{},"支持对多个元素进行组合操作，组合可以嵌套",[1193,1995,1996,1999],{},[1804,1997,1998],{},"支持对多个元素进行打组、解组~~~~(组操作 bug 复现了，目前在修)","（已修复）",[1116,2001,2003],{"id":2002},"p0性能优化",[1804,2004,2005],{},"【P0】性能优化",[1190,2007,2008,2013],{},[1193,2009,2010],{},[1804,2011,2012],{},"画布存在 100 个元素，打开页面到渲染完成 \u003C 3s",[1193,2014,2015],{},[1804,2016,2017],{},"同时操作 100 个元素，FPS 50+",[1116,2019,2021],{"id":2020},"p1协同",[1804,2022,2023],{},"【P1】协同",[1190,2025,2026,2036,2042],{},[1193,2027,2028,2031,2032,2035],{},[1804,2029,2030],{},"支持 undo & redo 操作"," ",[1804,2033,2034],{},"（大体实现了，可能要修一下 undo，redo 栈，有个不能稳定复现的 bug）","（已实现）",[1193,2037,2038,2041],{},[1804,2039,2040],{},"支持协同编辑，多人打开同一个画布可以协同编辑"," (写了个 Node.js 后端)",[1193,2043,2044,2047],{},[1804,2045,2046],{},"支持离线编辑，断网后仍然可以对画布编辑，恢复网络后自动提交数据","（IndexedDB）",[1567,2049,2050],{},[1096,2051,2052],{},"各模块的技术文档补充中\n此文档最后编辑于 2025.11.27\n项目开发中，欢迎提 issue 和 pr",{"title":1132,"searchDepth":2054,"depth":2054,"links":2055},4,[2056,2057,2058,2059,2086],{"id":1118,"depth":2054,"text":1118},{"id":1159,"depth":2054,"text":1160},{"id":1209,"depth":2054,"text":1209},{"id":1216,"depth":2060,"text":1216,"children":2061},2,[2062,2064,2067,2072,2083],{"id":279,"depth":2063,"text":279},3,{"id":1352,"depth":2063,"text":1352,"children":2065},[2066],{"id":1436,"depth":2054,"text":1436},{"id":1447,"depth":2063,"text":1447,"children":2068},[2069,2070,2071],{"id":1459,"depth":2054,"text":1459},{"id":1467,"depth":2054,"text":1467},{"id":1486,"depth":2054,"text":1486},{"id":1516,"depth":2063,"text":1516,"children":2073},[2074,2075,2076,2077,2078,2079,2080,2081,2082],{"id":1526,"depth":2054,"text":1526},{"id":1546,"depth":2054,"text":1546},{"id":1574,"depth":2054,"text":1574},{"id":1600,"depth":2054,"text":1600},{"id":1629,"depth":2054,"text":1629},{"id":1651,"depth":2054,"text":1651},{"id":1680,"depth":2054,"text":1680},{"id":1703,"depth":2054,"text":1704},{"id":1732,"depth":2054,"text":1732},{"id":1755,"depth":2063,"text":1755,"children":2084},[2085],{"id":1782,"depth":2054,"text":1782},{"id":1788,"depth":2060,"text":1788,"children":2087},[2088],{"id":1798,"depth":2063,"text":1799,"children":2089},[2090,2091,2092,2093,2094,2095],{"id":1802,"depth":2054,"text":1806},{"id":1869,"depth":2054,"text":1872},{"id":1926,"depth":2054,"text":1929},{"id":1958,"depth":2054,"text":1961},{"id":2002,"depth":2054,"text":2005},{"id":2020,"depth":2054,"text":2023},"代码仓库：\nhttps:\u002F\u002Fgithub.com\u002FZhongye1\u002FBDdraw_DEV","md",true,{"uuid":2100,"slots":2101},"bed45620-d916-11f0-ba29-f162322acafb",{},{"title":1085,"description":2096},"posts\u002F2025\u002F2025-12-05-现代协同 2D 画布编辑器（PixiJS v8）",[134,154],"cGwbH_ddjqchNhBkZzDMV93Fwre_EHHj1tsUnzBglhg",1790443287473]