使用 foreignObject 在微信小程序实现 svg 头像生成

前言

这段时间想要自己做一个玩具小程序,在写首页时,我就已经做到了需要展示小程序的模块。开始我随便找了一张图片进行占位。但是当我涉及到开发后端接口,头像就不能单纯使用同一张图了,虽然小程序官方提供了获取用户头像的能力,但却需要用户自己授权。在用户还未授权的这段时间,我当然需要去提供一个好看(✧∀✧)的默认头像。

寻求头像生成的方法

我先是在搜索引擎寻找提供生成头像的一些网站:

1.

等等还是很多的,但是要不就是我觉得不符合我的审美爱好,要不就是不提供生成服务,要不就是太复杂,虽然我有找到一些提供api接口的,但是 emm 国内访问不了。自己搭建服务也过于麻烦了。

眼前一亮

我搜到找了开源库react-nice-avatar,而且我也相对比较喜欢他的样式,可以根据字符串(可以使用用户的唯一 openid)哈希来生成唯一头像。

可行性研究

我先将项目进行clone下来,运行下来很顺利,项目基于 React,生成的方式是基于对 svg 的替换以及同一个 div 的 position 来控制 svg 的位置。下面的是项目结构。

解决在微信中显示 svg

因为之前遇到过需要在微信中显示 svg 图表,是通过转换成 background-image 来显示 svg,并且还需要对 svg 的 html 结构的一些字符进行替换。但是其中我发现头像的结构并不单纯涉及到 svg,其中还存在一些 div 用于控制 div 的位置。

解决办法

这时刚好我同事就在我旁边,我把我的疑惑告诉了他,他立刻就对我提到了一个 html 标签 foreignObject

对于兼容性( ie 哒咩)

方案测试

然后我将 div 包裹在了foreignObject中,显示正常!

项目改造

现在的项目是基于 react 来进行运行的,但是我其实需要的只是最终的头像 html 文本。

其实我只要将组件全部改造成返回 svg 文本的一个函数,最终在 index.ts 中进行拼接,就可以在保证原本的逻辑下得到我需要的结果。

接下来就是无聊的改造时间.....

替换过程

这里举一个替换的例子:

chroma-js 的 替换,项目中依赖了这个库来进行颜色处理,但是其实用到的只有两处。所以我的想法就是在 utils 中来实现所用到的两个方法,减少库的引入。 继续寻求 Gpt 的帮助

然后再引入处理最后需要用于 background-image 的 data:image/svg+xml ,改造就 ok 了。

进行测试

最后用产出的粘贴到小程序进行测试。意料之中的

嗯,显示失败了,一片空白....

错误排查

控制变量

同一个配置,切换到最开始时正常的分支,以及现在改造后错误的分支。 通过同一个配置生成图像。

js 复制代码
export function transformToBgImg(svgHTML: string): string {
  const txt = svgHTML
    .replace(
      "<svg",
      ~svgHTML.indexOf("xmlns")
        ? "<svg"
        : "<svg xmlns='http://www.w3.org/2000/svg'"
    )
    .replace(/\s+/g, " ");
  return `data:image/svg+xml,${txt}`
}

通过上面的函数来得到去除尽量多的连续空白字符。便于后续对比。

对于产生的区别,借助文本 diff 工具。可以很明显的看出来。

错误原因

过程就不具体讲了,这里直接贴出来排除的结果

  1. react 中使用的 props,在替换时忘记给变量包上双引号""
  2. props 中的驼峰写法的转换成 xxx-xxxx
  3. 将自闭和标签进行替换 <path/> => <path></path>

运行结果

项目地址

github.com/ayuan-gy/ni...

相关推荐
FungLeo21 分钟前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
用户842981424181039 分钟前
ByteJS,让重要的 JavaScript 以字节码运行。
javascript
dreams_dream2 小时前
微信小程序-使用npm包
微信小程序·小程序·npm
FungLeo2 小时前
成为全栈·Vue 管理后台篇·Vue Router如何守住多角色后台边界
前端·javascript·vue.js·rbac·vue router·路由守卫·前端权限
FungLeo2 小时前
成为全栈·Vue 管理后台篇·分页只显示第一页:从接口total 定位到前端修复
前端·vue.js·状态模式·分页·naive ui·服务端分页·前端问题排查
ZhengEnCi3 小时前
苹果滑动为什么有「肉感」:橡皮筋越界阻尼与弹簧动画的物理原理
前端
Moment3 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
L1mbo3 小时前
Lite模式 缓解微信开发者工具卡顿,附 uni-app 实践方案
前端·微信小程序
FungLeo3 小时前
成为全栈·Vue管理后台篇·仪表盘不是几张卡片:组合统计接口与角色视图
前端·javascript·vue.js·rbac·仪表盘·管理后台·tanstack query
程序员大阳3 小时前
HTML+CSS+JS对话式实战(7)-学生端活动报名功能开发
javascript·css·html·活动报名