我之前在这里发过一篇帖子:Converting SVG to PNG loses styling elements,但我的问题更为广泛 - 我认为我们已经找到了原因,但现在我在实施解决方案时遇到了问题。
我认为发表一个新的问题,询问如何使用特定的 React 语法,为 SVG 元素提供内联自定义字体样式,会更有益处。
以下是我的 render() 函数:
这段代码中,'fontFamily:...'引起了webpack错误,错误提示为出现了意外字符':',期望是一个闭合括号'}'。同时,文中还出现了@import。
它不会抛出任何错误,但在绘制到画布时与之前没有任何区别。
我认为发表一个新的问题,询问如何使用特定的 React 语法,为 SVG 元素提供内联自定义字体样式,会更有益处。
以下是我的 render() 函数:
renderIcon() {
return this.props.logoStyle.iconGraphic.path.map((path) => {
return (
<path id={path.id} style={{"fill":this.props.logoStyle.iconColor}} d={path.d} />
);
});
}
renderLogo() {
let style = this.props.logoStyle;
return (
<svg width="300" height="100" className={"logo"} xmlns="http://www.w3.org/2000/svg">
<svg xmlns="http://www.w3.org/2000/svg">
<rect
id="background"
x="0"
y="0"
width="300"
height="100"
style={{fill: style.backgroundColor}}
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
width={style.iconSize}
height={style.iconSize}
viewBox="0 0 1000 1000"
x="10"
y="13"
id="svg4272">
<g>
{this.renderIcon()}
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<text
style={{
fontSize:style.fontSize,
fontFamily: style.fontFamily,
fill: style.fontColor
}}
id="text"
x="90"
y="58"
fontSize={style.fontSize}
>{style.companyName}</text>
</svg>
</svg>
);
}
render() {
let style = this.props.logoStyle;
//console.log(style);
return (
<div className="logo-preview">
{this.renderLogo()}
<canvas id="canvas" width="900" height="300"></canvas>
<button className="btn btn-success" onClick={this.onDownload}>Download</button>
</div>
);
}
页面看起来一切都很好,但是当用户按下按钮触发SVG绘制到#canvas并进行下载时,很明显它丢失了样式元素,因为它们没有真正地被呈现内联。
图标(从this.renderIcon())是唯一正确绘制的内容。
<rect>
被完全剥离(或至少失去了其填充),而<text>
失去了其自定义字体(但正确维护了fontSize和fill)。
具体说到自定义字体,我从各种资源中发现需要将字体编码为Data URI,并包含在行内:
导入:使用Google Fonts与SVG<object> dataURI: 将CSS样式包含在转换svg为png时我尝试了以下方法,但均无效:
@font-face
<svg xmlns="http://www.w3.org/2000/svg">
<style>
@font-face { font-family: 'pacifico'; src: url(data:application/font-woff;charset-utf08;base64,d09GR...) format('woff'); font-weight: normal; font-style: normal; }
</style>
<text
style={{
fontSize:style.fontSize,
fontFamily: style.fontFamily,
fill: style.fontColor
}}
id="text"
x="90"
y="58"
fontSize={style.fontSize}
>{style.companyName}</text>
</svg>
@fontFace (camelCase for React)
<svg xmlns="http://www.w3.org/2000/svg">
<style>
@fontFace { fontFamily: 'pacifico'; src: url(data:application/font-woff;charset-utf08;base64,d09GR...) format('woff'); fontWeight: normal; fontStyle: normal; }
</style>
<text
style={{
fontSize:style.fontSize,
fontFamily: style.fontFamily,
fill: style.fontColor
}}
id="text"
x="90"
y="58"
fontSize={style.fontSize}
>{style.companyName}</text>
</svg>
这段代码中,'fontFamily:...'引起了webpack错误,错误提示为出现了意外字符':',期望是一个闭合括号'}'。同时,文中还出现了@import。
<svg xmlns="http://www.w3.org/2000/svg">
<style>
@import url('https://fonts.googleapis.com/css?family=Pacifico');
</style>
<text
style={{
fontSize:style.fontSize,
fontFamily: style.fontFamily,
fill: style.fontColor
}}
id="text"
x="90"
y="58"
fontSize={style.fontSize}
>{style.companyName}</text>
</svg>
编辑:
我看到了这个使用反引号的帖子:在 ReactJS 中嵌入 SVG 我尝试了这个方法,但仍然没有起作用(使用了驼峰和传统语法都试过了)。
<style>
{ `@fontFace { fontFamily: 'pacifico'; src: url(data:application/font-woff2;charset=utf-8;base64,....; } ` }
</style>
它不会抛出任何错误,但在绘制到画布时与之前没有任何区别。