当前位置: 首页 > Web前端 > vue.js

uniapp-画海报的各种工具

时间:2023-03-31 18:51:00 vue.js

在日常的uniapp和小程序开发中,每当工作需要画海报时,就很头疼。需要封装我之前的代码(异步下载文件,ctx绘图方法....)复制过来,然后一个一个导入,或者找不到再去百度(那这漫长的一天就太浪费了,所以为了减少引入这些乱七八糟的工具,我做了一个专门用来画海报的工具库,这样可以减少我的工作量(hhh又可以钓鱼了,下面是插件的介绍-内置库,大家可以看看,目前功能已经全部完善。绘图海报工具简介创建绘图海报Canvas矩形方法,内置图像绘制、圆角矩形绘制、换行字体绘制等方法。接近原生开发体验,上手简单,只需要考虑业务逻辑,不需要考虑其他问题,语法结构好,不会绘制uni/wx矩形陷入回调地狱,支持原生小程序和多终端应用程序与uniapp的合作。当环境为原生小程序时,会自动切换到性能更好的type2d绘制方式。将复杂的逻辑组合成简单的方法并扩展Strong,可以使用use|useCtx引入扩展。支持typescript,支持vue3模板,具体使用参考useDrawPoster。api文档:u-draw-poster插件市场:dcloud/u-draw-posternpminstallplug-innpmi--save-devu-draw-poster启用本插件的uni条件编译(重要)//vue.config.jsmodule.exports={transpileDependencies:['u-draw-poster'],};1.创建海报绘图工具//注意:如果使用HBuilder导入,需要import'@/js_sdk/u-draw-poster'importDrawPosterfrom'u-draw-poster'asynconReady(){//传入选择器,初始化绘图工具(注意,不需要传入#符号)使用微信小程序时,会自动启用type2d绘图constdp=awaitDrawPoster.build("canvas")}2.设置画布大小//设置矩形宽度和高度为100pxdp.canvas.width=100dp.canvas.height=1003.绘制任何内容//绘制背景和文本dp.draw((ctx)=>{ctx.fillStyle="#F4F4F4";ctx.fillRect(0,0,dp.canvas.width,dp.canvas.height);ctx.textBaseline="顶部";ctx.textAlign="开始";ctx.fillStyle="白色";ctx.font=`粗体${22}pxsans-serif`;ctx.fillText('周先生',dp.canvas.width/2,38.5);})//绘制图片内容dp.draw(async(ctx)=>{//......})值得注意的是draw方法会自动执行ctx.save/ctx.restore,不需要手动操作绘图栈。dp.draw((ctx)=>{/*...*/})//相当于ctx.save()/*...*/ctx.restore()4.绘制dp.draw不会立即绘制,只是将任务添加到任务栈中,需要使用dp.awaitCreate函数绘制,绘制完成后该函数会弹出所有任务。dp.awaitCreate在非二维绘图中绘图任务完成后会自动执行ctx.draw方法,绘图会被认为异步结束。dp.draw((ctx)=>{/*...*/})dp.draw(async(ctx)=>{/*...*/})//由于每个任务都可能有异步绘图任务,所以需要使用await等待绘制constresult=awaitdp.awaitCreate();//如果绘制成功,会返回一个数组,每个任务的绘制状态console.log("drawdrawingstatus:“,结果);//drawdrawingstatus:[true]5.生成图片的本地地址。如果需要保存为图片,可以使用dp.createImgUrl创建图片的本地地址,保存在wx或者uni的api中。dp.draw(async(ctx)=>{/*...*/})constresult=awaitdp.awaitCreate();constposterImgUrl=awaitdp.createImagePath();console.log("绘制绘图状态:",result);//[true]console.log("绘图生成本地地址:",posterImgUrl);//...tmp...也可以不使用dp.awaitCreate方法,调用dp.createImagePath时会自动检测任务列表,如果有则在执行绘图任务后创建地址。dp.draw(async(ctx)=>{/*...*/})//跳过drawPoster.awaitCreate,直接生成地址constposterImgUrl=awaitdp.createImagePath();console.log("绘制生成本地地址:",posterImgUrl);创建绘图扩展APIdrawPoster时,它会自动向ctx(画笔)添加/覆盖扩展方法,以构建海报矩形。dp.draw(async(ctx)=>{//ctx.drawImage|ctx.drawRoundImage|ctx.fillWarpText|....})绘制图片(ctx.drawImage)ctx.drawImage(url,x,y,w,h)DrawPoster绘制图像与原生图像不同。ctx.drawImage内置了downloadFile,只需要传入本地/网络地址即可。支持二维和非二维绘图,绘图方法相同。需要等待等待绘图。注意:当绘图环境为H5时,uniapp用本地图片绘图时不要使用较大的图片,否则创建图片时会生成失败。dp.draw(async(ctx)=>{consturl="/static/logo.png"//consturl="https://...."awaitctx.drawImage(url,88,174.94,198.98,36);})参数描述url网络图片地址,或者local/static中的图片路径。图像左上角的x,y坐标。width,height图片的大小。换行字体(ctx.fillWarpText)ctx.fillWarpText(options)传给配置对象绘制换行字体。以下是可配置的项目。interfaceFillWarpTextOpts{//绘制一个字符串,需要的itemtext:string;//绘制最长高度,默认100pxmaxWidth?:number;//绘制线高,默认为当前字体的默认宽度lineHeight?:number;//绘制的线条数,默认限制为2层layer?:number;//绘制x轴,默认为0x?:number;//绘制y轴,默认为0y?:number;//设置换行符,默认为空,如果设置,maxWidth|layer将被禁用splitText?:string;//不立即绘制?notFillText?:boolean;}//当`notFillText`为`true`时,不进行绘图,该函数会返回一个绘图信息队列//用于表示每行字体对应的绘图信息,如下是返回的结构信息,可以用它来计算换行字体的宽度,也可以用array.forEach和ctx.fillText来绘制。[{text:string,y:number,x:number}//....]圆角矩形(ctx.fillRoundRect)ctx.fillWarpText(x,y,w,h,r)dp.draw(async(ctx)=>{//设置矩形的颜色ctx.fillStyle="#fff";//绘制ctx.fillRoundRect(15,179,345,365.5,10);})参数说明左上角的x,y坐标长方形的一角。width,height矩形的大小。r矩形的圆弧半径。圆角矩形边框(ctx.strokeRoundRect)ctx.strokeRoundRect(x,y,w,h,r)参数描述矩形左上角的x,y坐标。width,height矩形的大小。r矩形的圆弧半径。圆形图像(ctx.drawRoundImage)ctx.drawRoundImage(url,x,y,w,h,r)dp.draw(async(ctx)=>{consturl="static/logo.png"//consturl="https://...."awaitctx.drawRoundImage(url,0,0,100,100,50);});参数描述url网络图片地址,或者local/static中的图片路径。图像左上角的x,y坐标。width,height图片的大小。r图像的弧度半径。绘制二维码(ctx.drawQrCode)生成二维码扩展。源代码使用uQRCode并做了一些修改。文件比较大,所以作为扩展插件使用。使用时,必须先引入插件。//注意:如果使用HBuilder导入,需要import'@/js_sdk/u-draw-poster'importDrawPosterfrom'u-draw-poster'importdrawQrCodefrom'u-draw-poster/dist/extends/draw-qr-code'//导入二维码绘图插件DrawPoster.useCtx(drawQrCode)asynconReady(){constdp=awaitDrawPoster.build("canvas")dp.canvas.width=200;dp.canvas.height=200dp。draw(ctx=>{ctx.drawQrCode({x:(dp.canvas.width/2)-50,y:(dp.canvas.height/2)-50,text:"http://www.baidu.com",size:100,});})}参数类型为必填说明xnumber无水平偏移长度ynumber无垂直偏移长度textString有二维码内容sizeNumber无二维码大小marginNumber无边距,二维码实际大小将根据设置的边距值进行缩放调整(默认:0)backgroundColorString为无背景色,如果设置为透明背景,需要设置fileType为'png',然后设置背景色为'rgba(255,255,255,0)'(default:'#ffffff')foregroundColorString无前景色(default:'#000000')errorCorrectLevelNumber无纠错级别,包括errorCorrectLevel.L,errorCorrectLevel.M,errorCorrectLevel.Q,errorCorrectLevel.H四个级别,L:最多可纠正7%的错误;M:最多可以纠正15%的错误;Q:最多可以纠正25%的错误;H:最多可以纠正30%的错误。全局实例API绘图构建(DrawPoster.build)DrawPoster.build(string|object)初始化构建绘图工具,传入查询字符串和配置对象。配置字符串的时候,直接查询字符串的画布。当配置对象时,需要object.selector。以下是选项的配置项。需要注意的是返回值是Promise,返回的是绘图构建对象dp。/**DrawPoster.buildbuildconfiguration*/interfaceDrawPosterBuildOpts{//querystring(必填),注意不要输错对应的canvasid,不需要传入#symbolselector:string;//选择组件范围componentThis?:any;//类型为二维绘图,默认开启,微信小程序动态加载type2d?:boolean;//绘制过程中是否显示加载框,默认不显示100,//加载提示文字loadingText?:'绘制海报...',//创建图片加载提示文字createText?:'生成图片中间...'}多图构建(DrawPoster.buildAll)DrawPoster.buildAll(Array)构建多个绘图工具,传入由参数string|组成的数组build函数中的options,返回多个绘图工具对象。key是canvasId,value是构造对象。挂载全局扩展(DrawPoster.use)DrawPoster.use(object)传入挂载配置对象,添加全局扩展方法,一般可用于海报绘制模板的封装,有时可有效减少代码同一个海报模板在不同的页面数量,使用方法如下。1.在任意位置添加扩展(建议在main.js中执行)importDrawPosterfrom'u-draw-poster'//全局添加绘制个人海报的扩展DrawPoster.use({name:"createMyCardImagePath",//dp为当前实例,其余参数为自定义传入参数handle:async(dp,opts)=>{//..自定义构建内容..returnawaitdp.createImagePath()}})二、页面使用定义扩展importDrawPosterfrom'u-draw-poster'asynconReady(){constdp=awaitDrawPoster.build("canvas")dp.canvas.width=100;dp.canvas.height=100constposterImg=awaitdp.createMyCardImagePath({/*...*/})}挂载绘图扩展(DrawPoster.useCtx)DrawPoster.useCtx(object)传入挂载配置对象,添加全局绘图扩展方法,用于自定义绘图方法的定义,使用方法如下。1.任意位置添加扩展(建议在main.js中执行)//全局添加绘制二维码的绘图扩展,实现DrawPoster.useCtx({name:"drawQrCode",//canvas(drawingnodes),ctx(drawingbrush),其余参数为自定义传入参数handle:async(canvas,ctx,url,x,y,w,h)=>{//..customdrawingcontent..},});二。绘图时使用自定义扩展dp.draw(ctx=>{consturl='http://www.baidu.com'awaitctx.drawQrCode(url,0,0,50,50)})绘制节点(dp.画布)dp.canvas|dp.画布宽度|dp.canvas.高度|...dp.canvas是全局的绘图根节点,在微信小程序中有专属的API。它将用作其他端的全局宽度和高度容器。当没有参数传递给dp.createImagePath时,dp.canvas.width|dp.canvas.height默认用于创建图像。以下是dp.canvas对象中存在的API和属性。界面画布{宽度:数字;高度:数字;//其余参数为微信小程序专属API,仅适用于微信小程序//详见微信小程序文档:https://developers.weixin.qq。com/miniprogram/dev/api/canvas/Canvas.html}创建绘图(dp.draw)dp.draw(asynccallback(ctx))drawer,接收executor函数,添加到绘图容器中,可以转换成一个asynchronousfunction处理图像绘制,也可以是同步函数。全局画笔(dp.ctx)dp.ctx是全局绘图画笔,可以在特殊情况下使用。建议只使用dp.draw函数进行绘图。等待绘制(dp.awaitCreate)dp.awaitCreate()异步绘制抽屉栈,成功后清空抽屉容器,返回成功栈状态数组(boolean[])。停止绘图(dp.stop)dp.stop()停止当前绘图栈,调用后会停止执行dp.awaitCreate|dp.createImagePath。创建图像(dp.createImagePath)dp.createImagePath(options)创建当前画布绘制完成后的本地图像地址。如果抽屉栈没有清空,会自动调用dp.awaitCreate()清栈。createImagePath将根据canvas.width和canvas.height创建图像。如果要自定义参数,awaitCreate方法可以接受一个配置对象,返回图片地址。以下是可配置的项目。接口CreateImagePathOptions{x?:数字;y?:数字;宽度?:数字;高度?:数字;destWidth?:数字;作用只是画海报。生成的资源要保存使用,使用图片组件展示。原因是方便操作,比如调整大小,或者长按H5端保存或者识别,所以画布要放在看不见的地方。它不能被隐藏display:none;overflow:hidden;否则它将是空白的。这里推荐canvas的隐藏样式代码。这个描述是uQRCode提供的描述,u-draw-poster也是适用的。canvas-hide{/*1*/位置:固定;右:100vw;底部:100vh;/*2*/z-index:-9999;/*3*/opacity:0;}常见问题微信小程序手机浏览空白微信小程序绘图如果有绘图,手机浏览器需要在后台添加downloadFile域名,重启开发者工具。微信小程序无法在真机上调试https://developers.weixin.qq....H5裁图异常。H5端绘制两个以上ctx.drawRoundImage圆角图片时,本地创建的base64显示异常。建议环境为h5时,限制圆角图片为一张,或者uni动态编译显示img标签。绘制后没有效果。注意DrawPoster.build无法检测你选择的canvasId是否正确,所以一定要和html中的canvas-id和canvas一致。小程序这边,由于会自动切换到type2d,所以必须加上动态编译。绘制多张图片,加载缓慢如果觉得等待多张图片加载加载慢,可以使用Promise.all同步绘制一些不需要处理图层覆盖的图片。dp.draw(async(ctx)=>{////用户头像awaitctx.drawRoundImage(headImgUrl,39,790,90,90,100);awaitPromise.all([ctx.drawImage('/static/logo1.png',20,20,35,35),ctx.drawImage('/static/tp.png',19,86,612,459),ctx.drawImage('/static/bw.png',188,559,274,50),////用户二维码ctx.drawImage(codeImgUrl,518,780,92,92),]);});注意:ctx.drawRoundImage不能放在Promise中。总之,由于ctx.drawRoundImage内部会调用ctx.clip方法,所以会和Promise.all中其他的图片绘制产生冲突。从而导致圆角失效。我的博客:毛先生的博客联系方式:951416545@qq.com