有人喜欢有人不喜欢,我只是提供一种方式,不提供脚本哈,有兴趣的自己研究。
前几天看 @PlayMcBKuwu 写的小尾巴,挺有趣的,感觉很有想法,但是很快就不推荐了,会污染帖子质量 & 索引,作为一个前端,就想着有没有什么办法可以既好玩又不会影响论坛的内容质量呢?
- 考虑能不能用 web component,既可以支持更丰富的 html,也可以屏蔽对这个 tag 的内容收集,很显然,editor 只支持少量的 tag,不支持 web component 自定义 tag
- svg 也不支持,支持 img
- 那就可以把 svg 内容转换为 dataUri,使用 img 渲染
还要考虑的问题是:svg 靠手写太难了,而且不支持文字排版,找了很久发现svg 支持 foreignObject,相等于可以在 svg 中嵌入 html,所以解决方案就是:使用 svg 的 foreignObject 渲染 html,然后转换成 dataURI。
文章后面有个 gist 示例,版权都是 @PlayMcBKuwu 的,我改了下交互,编辑器的最后输入 :tail: 自动添加,加了点 loading 效果。
最后声明,如果还是不妥,请管理员移除吧,我只是觉的好玩。
function blobToDataURL(blob) {
return new Promise((resolve) => {
const file = new FileReader()
file.onload = function(e) {
resolve(e.target.result)
}
file.readAsDataURL(blob)
})
}
async function createTemplate(content, source) {
// 加个多彩颜色吧
const html = `<span style="font-size:80%;background-image: linear-gradient(to right, #6B5B95, #FF6F61);color: transparent; background-clip: text">
「${content}」——《${source}》」
</span>
`
// 先渲染一遍,计算宽高
const container = document.querySelector('.topic-post .cooked')
if (!container) return ''
const div = document.createElement('div')
div.style.position = 'absolute'
div.style.opacity = '0';
div.style.zIndex = '-1000';
div.innerHTML = html;
container.appendChild(div)
const { width, height } = div.getBoundingClientRect();
container.removeChild(div)
const svg = `
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">${html}</div>
</foreignObject>
</svg>`;
const blob = new Blob( [svg], { type: 'image/svg+xml;charset=utf-8' } );
const dataUrl = await blobToDataURL(blob)
// dataUrl 记得移除 charset=utf-8; 否则无法保存
return `
***
<div style="text-align:center" class="_tail_containe">
<img width="${width}" height="${height}" src="${dataUrl.replace('charset=utf-8;', '')}"/>
</div>
`
}
