Напишите формулы латекса в Fabric.js

Я хотел бы иметь возможность писать формулы в латексе на холсте Fabric.js, возможно, с помощью MathJax.

http://fabricjs.com/fabric-intro-part-2#text

Возможно ли это сделать?


person user1506145    schedule 18.05.2014    source источник


Ответы (1)


Я бы использовал средство визуализации SVG MathJax для создания файла SVG, а затем загрузил бы этот SVG в Fabric.js. Вот пример:

<!-- It is important to use the SVG configuration of MathJax! -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_SVG">
</script>

<!-- You might need at least Fabric 1.4.6, because of a bug with data URLs -->
<script type="text/javascript" src="https://raw.githubusercontent.com/kangax/fabric.js/master/dist/fabric.js">
</script>

<body>
  <canvas id="canvas" width="400" height="400"></canvas>

  <script type="text/javascript">
    // This function does the actual work
    function tex(text, callback) {
        // Create a script element with the LaTeX code
        var div = document.createElement("div");
        div.style.position = "absolute";
        div.style.left = "-1000px";
        document.body.appendChild(div);
        var se = document.createElement("script");
        se.setAttribute("type", "math/tex");
        se.innerHTML = text;
        div.appendChild(se);
        MathJax.Hub.Process(se, function() {
            // When processing is done, remove from the DOM
            // Wait some time before doing tht because MathJax calls this function before
            // actually displaying the output
            var display = function() {
                // Get the frame where the current Math is displayed
                var frame = document.getElementById(se.id + "-Frame");
                if(!frame) {
                    setTimeout(display, 500);
                    return;
                }

                // Load the SVG
                var svg = frame.getElementsByTagName("svg")[0];
                svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
                svg.setAttribute("version", "1.1");
                var height = svg.parentNode.offsetHeight;
                var width = svg.parentNode.offsetWidth;
                svg.setAttribute("height", height);
                svg.setAttribute("width", width);
                svg.removeAttribute("style");

                // Embed the global MathJAX elements to it
                var mathJaxGlobal = document.getElementById("MathJax_SVG_glyphs");
                svg.appendChild(mathJaxGlobal.cloneNode(true));

                // Create a data URL
                var svgSource = '<?xml version="1.0" encoding="UTF-8"?>' + "\n" + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + "\n" + svg.outerHTML;
                var retval = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(svgSource)));


                // Remove the temporary elements
                document.body.removeChild(div);

                // Invoke the user callback
                callback(retval, width, height);
            };
            setTimeout(display, 1000);
        });
    }


    document.onload = function() {
      var canvas = new fabric.Canvas("canvas");

      tex("1+\\int_x^y e^x dx + \\ldots", function(svg, width, height) {
          // Here you have a data url for a svg file
          // Draw using FabricJS:
          fabric.Image.fromURL(svg, function(img) {
              img.height = height;
              img.width = width;
              canvas.add(img);
          });
      });
    };
  </script>
</body>

Я также поместил это в JsFiddle: http://jsfiddle.net/3aHQc/39/

person Phillip    schedule 30.05.2014
comment
Я тестировал код только в Firefox 29. Очевидно, Chrome (или что-то еще, что вы используете) еще не поддерживает свойство outerHTML для изображений svg. Я обновил пример, чтобы он работал и с другими браузерами. - person Phillip; 03.06.2014
comment
К сведению: пользователь Github asturur недавно добавил поддержку загрузки SVG через loadSVGFromString. Использование этой функции вместо Image.fromURL должно улучшить качество масштабирования в Firefox. - person Phillip; 30.06.2014
comment
Спасибо за ваш ответ, я также вижу, что это изображение, поэтому оно не масштабируется. Как мне использовать loadSVGFromString, просто поменять его на Image.fromUrl? Хотите отправить скрипку? :) - person user1506145; 16.07.2014
comment
Здесь есть несколько примеров на SO, например. здесь, чтобы узнать, как использовать эту функцию. Чтобы получить SVG в виде строки, заставьте функцию загрузчика вызывать callback, используя svgSource вместо retval в качестве аргумента. - person Phillip; 16.07.2014
comment
Примечание из будущего: срок службы cdn.mathjax.org подходит к концу, проверьте mathjax .org/cdn-shutting-down для советов по миграции. - person Peter Krautzberger; 12.04.2017
comment
почему функция возвращает ошибку TypeError: svg is undefined :x - person flex_; 06.03.2018