在 JavaScript 中将 latex 渲染为 svg 并用 paper.js 显示结果

render latex as svg in JavaScript and display the result with paper.js

以下代码给出“脚本错误”。非常感谢任何帮助。

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js"></script>

<script>
  window.MathJax = {
    // options
  };
</script>

<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>

<canvas id="canvas_1"></canvas>

javascript

var graphScope = new paper.PaperScope();
var canvas_1 = document.getElementById('canvas_1');
graphScope.setup(canvas_1);
graphScope.activate();

const latexToImg = function(formula) {
  return new Promise((resolve, reject) => {
    let wrapper = MathJax.tex2svg(`${formula}`, {
      em: 10,
      ex: 5,
      display: true
    })
    let output = {
      svg: "",
      img: ""
    }
    let mjOut = wrapper.getElementsByTagName("svg")[0]
    // mjOut.setAttribute("xmlns", "http://www.w3.org/2000/svg")
    output.svg = mjOut.outerHTML
    var image = new Image()
    image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(output.svg)));
    image.onload = function() {
      var canvas = document.createElement('canvas');
      canvas.width = image.width;
      canvas.height = image.height;
      var context = canvas.getContext('2d');
      context.drawImage(image, 0, 0);
      output.img = canvas.toDataURL('image/png');
      resolve(output.img)
    }
    image.onerror = function() {
      reject()
    }
  })
}

const svgGroup = graphScope.project.importSVG(latexToImg('x^2'));

快速查看您的代码后,我会说:

  1. 您正在向 importSVG 函数传递承诺
  2. importSVG 函数需要接收 SVG 字符串,您的承诺将使用 PNG 图像数据解析 url

MathJax 和 Paper.js 都直接使用 SVG,因此显然不需要创建中间 canvas 元素。此外,MathJax.tex2svg 创建一个 SVG DOM 元素,Paper.js 可以使用它(importSVG 可以使用 SVG 字符串、DOM 元素或 url 字符串)。这大大简化了代码,因为它删除了所有 canvas 操作并且所有操作都是同步的。

不过由于某些原因,尺寸很小,所以我将其放大了 20 倍。

var graphScope = new paper.PaperScope();
var canvas_1 = document.getElementById('canvas_1');
graphScope.setup(canvas_1);
graphScope.activate();
const latexToImg = function(formula) {
  let wrapper = MathJax.tex2svg(formula, {
    em: 10,
    ex: 5,
    display: true
  })
  return wrapper.querySelector('svg');
}
const svgGroup = graphScope.project.importSVG(latexToImg('x^2'));
var bounds;
svgGroup.scale(20);
// for automatic scaling, use these lines instead:
// bounds = svgGroup.strokeBounds;
// svgGroup.scale(40 / bounds.height);
bounds = svgGroup.strokeBounds;
svgGroup.position.x = -bounds.x;
svgGroup.position.y = -bounds.y;
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js"></script>
<script>
  window.MathJax = {
    // options
  };
</script>
<script type="text/javascript" id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
<canvas id="canvas_1"></canvas>