繁体   English   中英

ReactJS - 内联 SVG 样式和 Google 字体

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM