尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
小程序 Canvas 画招聘海报:750×1334 设计稿 + 网络图预下载,我踩过的 4 个坑
招聘岗位要生成分享海报设计师给了 750×1334 的设计稿要求小程序端 Canvas 渲染。真上手才发现Canvas 画图这活儿水太深——设计稿 1:1 照搬不行网络图直接 draw 不行多渲染几次画面还会越变越小。这套逻辑我写进了 job-uniapp 的 posterRenderer.js把坑一个个填平了分享下过程。设计稿 750×1334代码里就认这个数海报所有坐标都按设计稿 750 宽来写绘制时再整体缩放。这样设计师给的标注能直接抄不用每个元素单独换算constDESIGN_WIDTH750;constDESIGN_HEIGHT1334;// 绘制入口把 750×1334 的坐标系缩放到实际画布exportasyncfunctiondrawPoster(ctx,options){const{canvasW,canvasH}options;constscaleMath.min(canvasW/DESIGN_WIDTH,canvasH/DESIGN_HEIGHT);ctx.scale(scale,scale);// ... 后续所有 draw 都用设计稿坐标ctx.fillText(hireTitle,padL,curY34);ctx.fillText(metaLine,padL,curY22);}重点来了scale 只做一次。如果每次渲染都无条件ctx.scale(scale, scale)transform 矩阵会叠加画着画着整个画面就缩小甚至看不见了。所以绘制前必须先重置/** 绘制前重置变换矩阵避免多次 render 后 scale 累积导致画面缩小 */exportfunctionresetPosterTransform(ctx,designScale1){if(!ctx||!ctx.__isModern||!ctx.__native)return;ctx.setTransform(1,0,0,1,0,0);if(designScaledesignScale!1){ctx.scale(designScale,designScale);}}网络图不能直接画先下载成本地路径岗位主视觉是后台配置的 CDN 图片小程序 Canvas 对网络图支持不稳定安卓尤其明显直接 draw 可能白屏。正确姿势是先用uni.downloadFile拉成本地临时路径再画下载失败就退回uni.getImageInfo/** 网络图预下载为本地临时路径供小程序 Canvas 稳定绘制 */exportfunctionprefetchImageForCanvas(src){returnnewPromise((resolve,reject){consturlresolveImageSrc(src);if(!url){resolve();return;}if(!isNetworkImageSrc(url)){resolve(url);return;}constfallbackGetInfo(){uni.getImageInfo({src:url,success:(info)resolve(info.path||url),fail:()reject(newError(prefetch fail))});};uni.downloadFile({url,success:(res){if(res.statusCode200res.tempFilePath){resolve(res.tempFilePath);}else{fallbackGetInfo();}},fail:fallbackGetInfo});});}多张图要串行下载再画不能一张张异步撒出去——不然第二张还没下完Canvas 已经开始画了图的位置全是空的。高 DPR 屏不糊逻辑坐标和像素坐标分开iPhone 的 DPR 是 3安卓一堆 2.x。如果画布逻辑尺寸直接设成设计稿尺寸高分屏上必然糊。处理方式是画布的实际像素尺寸 逻辑尺寸 × DPR然后ctx.scale(dpr, dpr)把坐标系拉回逻辑坐标exportfunctioninitPosterCanvas2d(componentInstance,selector,logicalWidth,logicalHeight){constqueryuni.createSelectorQuery().in(componentInstance);// ...constdpruni.getSystemInfoSync().pixelRatio||2;constcanvasres[0].node;canvas.widthlogicalWidth*dpr;canvas.heightlogicalHeight*dpr;constctxcanvas.getContext(2d);ctx.scale(dpr,dpr);// 之后画布代码全部用逻辑坐标returnctx;}这块是老生常谈但特别容易漏——漏了canvas.width w * dpr这行真机预览直接糊成一团模拟器上还看不出来非得拿手机测。踩坑记录分享到微信后海报上的字消失了现象海报在页面里预览正常用户点保存到相册也正常唯独分享给微信好友时分享出去的图片上文字全部消失只剩背景和头像。排查过程先怀疑是分享时机问题——分享发生在 canvas 还没画完时于是给分享加了个 await 等待drawPoster完成没用。又怀疑是canvasToTempFilePath的时机加了setTimeout延迟 500ms还是没用。最后把生成好的图片路径在本地预览打开发现本地路径的图是完整的只有通过分享通道出去的图缺字。定位思路本地正常、分享异常问题不在绘制而在分享时的图片来源。看代码发现分享用的是实时画布再截一次图的逻辑分享前临时调用canvasToTempFilePath重新生成而这次生成时背景图还没绘制完异步加载没等到——文字画在还没出现的背景上或者画布在截图瞬间被清了。最终解决分享和保存统一走同一张已生成好的临时文件先生成一次存到tempFilePath分享和保存都引用它绝不在分享瞬间重新截画布exportasyncfunctionbuildPosterFile(canvas,fileTypejpg){consttempawaitnewPromise((resolve,reject){uni.canvasToTempFilePath({canvasId:posterCanvas,success:(res)resolve(res.tempFilePath),fail:reject,});});returntemp;}// 分享 / 保存统一使用 buildPosterFile 产出的同一张图顺便说一句保存相册还要先弹授权用户拒绝过一次再调用uni.saveImageToPhotosAlbum会直接失败——先uni.getSetting查授权状态没授权就先uni.openSetting引导用户开这坑我一开始也没接住。可直接复用的清单设计稿坐标 一次性 scale多渲染必须 resetPosterTransform防 transform 累积画面缩小。网络图先downloadFile再画多图串行预下载画布上永远画本地路径。高 DPR 屏canvas.width logicalW * dprctx.scale(dpr, dpr)真机不糊。分享与保存复用同一张 tempFilePath别在分享瞬间重截画布。保存相册前先查授权拒绝过就openSetting引导别硬调saveImageToPhotosAlbum。项目源码https://gitee.com/gzqkl/job-uniapp
RELATED

相关推荐

用工订单状态机:从待确认到已完成,我拿 6 个状态挡住了所有非法跳变

用工订单状态机:从待确认到已完成,我拿 6 个状态挡住了所有非法跳变

零工平台的工单,生命周期比想象中长:用户提交申请 → 雇主确认 → 开工打卡 → 完工结算 → 双方评价 → 完成。早期版本里状态就是个字符串字段,service 里随手 order.setOrderStatus("WORKING"),改着改着就乱了——有…

📅 2026/10/10 4:44:24
安卓新闻App源码实战:从环境配置到功能扩展的完整指南

安卓新闻App源码实战:从环境配置到功能扩展的完整指南

简介:这是一套基于 Android Studio 开发的安卓新闻 App 项目源码与配套报告,面向计算机相关专业正在准备期末大作业的学生,以及需要项目实战练习的初学者。项目经导师指导并通过评审,获得 98 分,难度适中,源…

📅 2026/10/10 4:39:24
OpenClaw安装全记录:从环境准备到编译排错,一步步带你跑通

OpenClaw安装全记录:从环境准备到编译排错,一步步带你跑通

说个事儿,折腾了两天两夜,OpenClaw 终于在我机器上跑起来了。看着终端里跳出那行版本号的时候,我长舒了一口气——这东西的安装坑是真的多,网上资料又七零八落,一个人闷头试错实在太费劲。所以这篇不是教程复读&#x…

📅 2026/10/10 4:39:24
MORE NEWS

更多资讯

📰

CSP-J/S初赛1000页资料集高效使用指南:从知识模块到错题归因

简介:这份资料集面向备战NOIP CSP-J(入门级)与CSP-S(提高级)初赛第一轮的青少年选手及信奥教练,系统梳理了初赛所需的核心知识体系。内容围绕计算机结构与组成、进制转换、原反补码、操作系统与网络基础展开…

📰

AI 代理技能模块实战:用自然语言生成可交互架构图

昨天在 GitHub 上刷到一个很有意思的仓库,名字叫 archify。项目定位很直白:给 AI 代理用的技能模块(skill module),让你用自然语言描述系统,AI 自动生成一张可以点击、缩放、带信息面板的可交互架构图。这个…

📰

俄罗斯条形码代办水有多深?从业15年老手揭秘8个隐形大坑

做俄罗斯市场的朋友,十个有九个问过同一个问题:做俄罗斯市场条形码申请找谁才不会被坑?我在条码代理行业摸爬滚打15年,服务过创维、科大讯飞、名创优品等上百家出口企业,今天说点得罪人的大实话。俄罗斯条形码申请机构…

📰

终端AI助手实战:让命令自动执行的安全设计与落地指南

我一直觉得,终端里的 AI 助手如果不碰命令,那就跟个只会念字典的翻译官一样,看着啥都懂,真上了战场却使唤不动。市面上的 AI 聊天工具已经够多了,但大多数都停在"帮你想清楚"的层面,而不是"…

📰

PL/SQL Developer 11 高效使用指南:窗口选择、模板变量与 Preferences 配置

简介:这份《PL/SQL Developer 11 中文手册》面向 Oracle 数据库开发人员、DBA 及 PL/SQL 初学者,用于解决工具上手难、功能查找不便的问题,帮助读者系统掌握这款 Windows 平台集成开发环境的使用方法。资源为单个 PDF 文档,压缩包…

📰

Codex反复重连5/5?从心跳机制到日志定位的完整排查指南

如果你也在用 Codex 跑一些耗时比较长的工程任务,大概率遇到过这样一个画面:任务进行到一半,终端底部突然出现一行Reconnecting...,计数器从 1 慢慢爬到 5,你以为它要恢复了,结果数字停在 5/5 没多久&#…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬