项目的话就直接使用脚手架生成一个Vue3+TS项目
npmcreatevue@latest为了方便,使用了ElementPlusUI库
npminstallelement-plus--save配置的话,可以查看文档,全局导入、按需导入都可以看自己的需求
项目搭建完后,就可以来分析一下本次需求大概会涉及哪些功能了
为了方便,我们当然还需要提供多种模版供用户自己选择
为了让生成的头像更具独一无二性,我们还需要提供用户自定义内容的功能,比如:用户输入文字、选择文字颜色等
本次需求的重点当然是合成头像了
用户合成完当然还得支持让他下载
合成模版部分,这里主要是需要考虑各个模版所需要的合成功能有哪些
//模版4constdrawImg4=(ctx:any)=>{constimg=newImage();img.src=user_img.value;constgqImg=newImage();gqImg.src=gqList.value[template_id.value-1].img;img.onload=()=>{ctx.drawImage(img,0,0,300,300);//绘制头像gqImg.onload=()=>{ctx.drawImage(gqImg,0,0,300,300);//绘制国庆图ctx.fillStyle=textColor.value;//设置文字颜色ctx.font="20pxkaiti";//设置文字大小及字体consttextList=text.value.split(",")[];//以中文逗号分割文字textList.forEach((item:string,i:number)=>{drawVerticalText(ctx,item"",20+i*20,186+i*20,{size:20,});//绘制文字});};canDownload.value=true;//合成完成};};这里主要的难点在于canvas默认不支持文字竖排绘制,所以这里需要特殊处理,原理其实就是遍历文字,计算文字高度,然后再一个一个去绘制
//文字竖排constdrawVerticalText=(context:any,text:string,x:number,y:number,font:any)=>{context.save();context.font=font;for(vari=0;i 搭建完就是这样的,我们写完代码只需要将代码提交上去就能够自动打包部署了 PC上体验下来,效果还可以。 开发过程中也遇到一些问题,来看看是如何解决的吧 canvas绘制图片不清晰的原因主要是: 因为canvas是点阵图,由一个个像素组成,当图像被放大时,一个像素会被强形拉伸至一个以上,多出来的像素均匀的分部在图像中,计算机为了使拉伸后的图像看起来平滑,会给这些多出来的像素计算出一个过渡色,缩小图像时,多个像素合成一个像素,计算机会用这多个像素的色彩值计算出一个过渡色来填充这个像素,不管是放大还是缩小,都会造成图像原有像素信息丢失。 所以只需要加上以下代码就能解决 优化完,清晰度提升还是非常明显的 手机上下载图片会失败,这主要是因为blob格式在手机上不能下载,base64格式有点大,那就只能上传CDN再进行下载了? 不需要,我们可以利用手机上的长按图片保存来实现 打包生成的_plugin-vue_export-helper.cdc0426e.js文件访问404,刚开始我还以为是打包路径配置的有问题,但如果是打包路径的问题的话也不会只有这一个文件有问题。 最终,我在vite的issues中找到了答案 简单点讲就是GithubPages阻止了以下划线字符开头的文件,所以会导致这个文件访问返回404. 解决方法就是修改打包逻辑: constINVALID_CHAR_REGEX=/[\u0000-\u001F"#$&*+,:;<=>[\]^`{|}\u007F]/g;constDRIVE_LETTER_REGEX=/^[a-z]:/i;build:{outDir:"dist",assetsDir:"assets",chunkSizeWarningLimit:2000,//解决包大小超过500kb的警告rollupOptions:{output:{manualChunks:{//elementPlus:["element-plus"],//highlightjs:["highlight.js"],},chunkFileNames:"assets/[name]-[hash].js",entryFileNames:"assets/[name]-[hash].js",assetFileNames:"assets/[name]-[hash].[ext]",sanitizeFileName:(name)=>{constmatch=DRIVE_LETTER_REGEX.exec(name);constdriveLetter=matchmatch[0]:"";return(driveLetter+name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX,"")//处理文件名中的非法字符);},},},},