[英]ReactJS - inline SVG styling and Google Fonts
我之前在这里发过一篇文章: 将 SVG 转换为 PNG 会丢失样式元素,但我的问题更广泛 - 我认为我们确定了原因,但现在我在实施解决方案时遇到了问题。
我认为发布一个关于特定 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 和填充)。
专门谈到自定义字体,我从各种资源中发现我需要将字体编码为数据 URI,并将其包含在内:导入: 使用 Google 字体与 SVG <object> dataURI: 如何在转换 svg 时包含 CSS 样式到 png
我尝试了以下方法,但没有任何效果:
@字体脸
<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 错误,引用冒号 ':' 作为一个意外的字符,期待一个右括号 '}'
@进口
<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>
编辑:
我遇到了这个使用反引号的线程: Embedding SVG into ReactJS并尝试了这个,但仍然没有工作(尝试使用驼峰命名法和传统语法)
<style>
{ `@fontFace { fontFamily: 'pacifico'; src: url(data:application/font-woff2;charset=utf-8;base64,....; } ` }
</style>
它不会抛出任何错误,但是当绘制到画布上时它与以前没有什么不同
更新:我想通了
我使用了一个名为“computed-style-to-inline-style”的插件,它基本上将 CSS 中的任何样式设置为与您的 SVG 内联。 这对于渲染和绘制图标非常有用(不必包括那些内联的),但这似乎也是为什么我的<Rect>
被清除的罪魁祸首,并且字体没有被包含在<Text>
这是我用于 SVG 对象的更新样式:
return (
<svg width="300" height="100" className={"logo-"+id} xmlns="http://www.w3.org/2000/svg">
<svg xmlns="http://www.w3.org/2000/svg">
<style>
{ `.rect { fill: {style.backgroundColor} }`}
</style>
<rect
id="background"
className="rect"
x="0"
y="0"
width="300"
height="100"
rx={style.bgBorderRadius}
ry={style.bgBorderRadius}
style={{fill: style.backgroundColor}}
stroke="2" />
</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">
<style>
{ `@font-face {
font-family: 'Pacifico';
src: url(data:application/font-woff2;charset=utf-8;base64,d09GMgA...) format('woff');
font-weight: normal;
font-style: normal;
} ` }
</style>
<text
style={{
fontSize:style.fontSize,
fontFamily: 'Pacifico',
fill: style.fontColor,
fontWeight: style.fontWeight,
fontStyle: style.fontStyle
}}
id="text"
x="90"
y="58"
stroke={style.fontStrokeColor}
strokeWidth={style.fontStrokeWidth}
textAlign="right"
>{style.companyName}</text>
</svg>
</svg>
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.