Стиль шрифта текста в svg не распространяется на png при загрузке - PullRequest
1 голос
/ 06 августа 2020

Я генерирую svg с текстом, используя D3. js для загрузки пользователем.

К сожалению, когда загружается svg, семейство шрифтов, примененное к тексту в svg, не появляются, когда SVG конвертируется в холст, а затем загружается как png.

Кажется, что стиль шрифта отсутствует.

Есть ли способ создать png с помощью это семейство шрифтов применяется?

Чтобы загрузить svg как png, я адаптировал ответ , описанный здесь .

Вот мой процесс:

Сначала я создаю svg.

     await d3.xml(`img_templates/${template}_${dimensions}.svg`)
        .then(data => {
        
            divsvg.append(data.documentElement) //Append svg to DOM 
           
        }); 

Затем я добавляю свои текстовые элементы в svg

 const quoteText = quoteGroup.append("text")
            .attr("class", "quote")
            .style("font-size", `15px`)
            .style("font-family", 'Merriweather')

Merriweather - это семейство шрифтов Google, которое я загружаю в заголовок a html страница примерно так:

 <head>
    <link href="https://fonts.googleapis.com/css2?family=Merriweather&display=swap" rel="stylesheet"> 
    <link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,700;1,400&display=swap" rel="stylesheet"> <!--Another font I use-->
    <script src="d3.min.js"></script>
    <script src=genImage.js></script> <!--The js code to interact with the svg --> 
  </head>

При загрузке я выполняю следующие функции в svg,

function downloadSVG(svgObj){
  
    var data = (new XMLSerializer()).serializeToString(svgObj);
     
    var DOMURL = window.URL || window.webkitURL || window;
    var img = new Image();
    var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
    var url = DOMURL.createObjectURL(svgBlob);
    
    img.onload = function () {
        var canvas = document.createElement("canvas");              
        canvas.width = this.width; 
        canvas.height = this.height; 
        var ctx = canvas.getContext("2d");

        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);
    
        var imgURI = canvas
            .toDataURL('image/png')
            .replace('image/png', 'image/octet-stream');
        // console.log(imgURI)
        triggerDownload(imgURI);
    };
    
    img.src = url;
}



function triggerDownload (imgURI) {
    var evt = new MouseEvent('click', {
      view: window,
      bubbles: false,
      cancelable: true
    });
  
    var a = document.createElement('a');
    a.setAttribute('download', 'MY_COOL_IMAGE.png');
    a.setAttribute('href', imgURI);
    a.setAttribute('target', '_blank');
  
    a.dispatchEvent(evt);
  }

При сериализации в строку svg выглядит так:

<svg xmlns="http://www.w3.org/2000/svg" width="484" height="484" viewBox="0 0 484 484" fill="none">

<g class="quoteGroup" transform="translate(42,100)">
<text class="quote" fill="#FFFFFF" style="font-size: 25px; font-family: Merriweather;"><tspan x="0">"I’m staying alone in Montauk at a</tspan><tspan x="0" dy="40px">friend’s house while he’s in Portugal</tspan><tspan x="0" dy="40px">(something about taxes and quality of</tspan><tspan x="0" dy="40px">life). After my morning coffee and</tspan><tspan x="0" dy="40px">power shake, it’s time to water the</tspan><tspan x="0" dy="40px">plants."</tspan></text>
</g>

<g class="headlineGroup" transform="translate(42,365)">
<text class="headline" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-style: italic;"><tspan x="0">Stop Thinking of the Breakup of Big Tech as Punishment</tspan></text>
</g>

<g class="publisherGroup" transform="translate(42,430)">
<text class="publisher" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-weight: bold;">Marker</text>
</g>

<g class="dateGroup" transform="translate(353,430)"><text class="date" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-weight: bold;">Aug 04, 2020</text></g>

</svg>

Насколько я могу судить, семейство шрифтов правильно указано в строке, но n svg преобразуется в холст, а затем в png, он теряется. Почему это могло произойти?

Пожалуйста, дайте мне знать, если я могу предоставить дополнительную информацию. Любая помощь приветствуется!

1 Ответ

0 голосов
/ 07 августа 2020

Для всех, кто обнаружит это с той же проблемой, я смог разобраться.

Благодаря предложению г-на Лонгсона я нашел следующий ответ Кайидо на этот вопрос .

Метод Kaiido GFontToDataURI работал отлично. Я включил это в свой код так:

            GFontToDataURI("https://fonts.googleapis.com/css2?family=Merriweather&display=swap")
                .then(cssRules => {
                    let fontRules = cssRules.join('\n')
                    d3.select("svg").append('defs').append('style').attr('type', 'text/css').text(fontRules)
                    console.log("Added Merriweather")
                })
                .catch(reason => console.log(reason)) 
            
            GFontToDataURI("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,700;1,400&display=swap")
                .then(cssRules => {
                    let fontRules = cssRules.join('\n')
                    d3.select("svg").append('defs').append('style').attr('type', 'text/css').text(fontRules)
                    console.log("Added roboto")
                })
                .catch(reason => console.log(reason)) 
...